steam learn: rest good practices

24
2015-02-19 Parsys Telemedicine REST Good Practices Field experience by Jean-Christophe Bohin Phiropsi

Upload: inovia

Post on 07-Aug-2015

37 views

Category:

Software


1 download

TRANSCRIPT

2015-02-19Parsys Telemedicine

REST Good PracticesField experience

by Jean-Christophe Bohin

Phiropsi

2015-02-19Parsys Telemedicine

So… What Can I Expect ?

● No REST 101 (come on, read a book)● No specific implementation details for any target

language● No REST Maturity Model● And no schweppes

Just some return on experience designing and building a few dozen REST API in various circumstances.

2015-02-19Parsys Telemedicine

If You Need To Remember One Thing:

Respect Web standards;

Use them, but don’t abuse them;

Pragmatism is more important than integrism.

2015-02-19Parsys Telemedicine

Who Do You Aim To ?

● Public API ?

● Private API for multiple clients ?

● Private API for just one client ?

Keep that in your head, it has high impacts on your design decisions.

2015-02-19Parsys Telemedicine

Basics About Resources And REST

REST is about Resources. Resources are about nouns.

You manipulate Resources with a CRUDL-like API with HTTP verbs (GET, POST, PUT, PATCH, DELETE).

Understand idempotency and safeness of actions/verbs.

Don’t forget HEAD and OPTIONS.

2015-02-19Parsys Telemedicine

Transport

TLS. I mean it.

gzip everything in your REST API.

Go for HTTP2/SPDY if you can (it’s just an ops parameter most of the time anyway).

2015-02-19Parsys Telemedicine

For resource listing (and embedding), always paginate. That’s not an option./api/archer_drinks?limit=50&offset=200

Use Link header. prev/next/last are your friends.

Regarding number of items in a collection, add it if you have a cost effective-way to have it and if it’s meaningful. But no link header covers this.

Paginate

2015-02-19Parsys Telemedicine

Filter, Sorting, Search

Use query elements:

/api/agents?name=Randy%20Magnum

/api/missions?bulletCount={“gte”: 210}

/api/agents?_sort=drinksPerDay,-age

/api/agents?_q=Laaaaaanaaaaa

2015-02-19Parsys Telemedicine

Authentication

No HTTP basic auth.

Choose (at least one) from :● API key● User token (JsonWT for example, or macaroons)● A Bearer (OAuth2, …)● A per call token (ala Amazon)● TLS Client cert authentication

2015-02-19Parsys Telemedicine

Versioning

Good: Accept header.Accept: application/vnd.malory-archer.v2+json

Acceptable: in URI path./api/v2/missions/

Use semver-like versioning, so publish only stable-backward compatible major version.

2015-02-19Parsys Telemedicine

Representation

Unless you have specific constraints, go for JSON by default.

Embrass JS camelCase representation. I don’t like camelCase neither, but that’s what most clients might expect.

If you support multiple representations, respect Accept header, and maybe provide URI extension as a way to force it (for limited clients).

2015-02-19Parsys Telemedicine

Representation contd.

Avoid JSON Number for anything exact/precise. Use string instead.

Use iso8601 dates. Support the full spec. Please.

Validate Content-Type, at least for inputs.

2015-02-19Parsys Telemedicine

It’s nice and really useful, use it. It prevents developers to dynamically build URIs.

But don’t expect black magick from it. Just because you linked a resource in a response makes your client’s code understand what a ‘kills’ is.{…

"links": [

{"rel": "self", "href":"/api/agents/1"},{"rel": "kills", "href":"/api/agents/1/kills"},

]

…}

HATEOAS / HAL

2015-02-19Parsys Telemedicine

Return Nice Errors

With a list of problems. And maybe error# if you document them.{

"message": "Fields validation error","errors": [

{ "field": "answer", "message": "Phrasing!" }, { "field": "cellphone", "message": "You can’t add a KGB cellphone in your HR records." }

]}

2015-02-19Parsys Telemedicine

Some More Optimizations

2015-02-19Parsys Telemedicine

Aliases

They can be really nice to prevent a recurring complex query.

/api/missions?agents=archer,lana&defcon={“gte”:4}&_fields=id,missionName

could be

/api/danger_zone

2015-02-19Parsys Telemedicine

Return Ressource on Update

When you change a resource, always return that resource in the response.

And if you just created a resource (POST on a collection), add a Location header to your response.

2015-02-19Parsys Telemedicine

Same Origin Policy

If you plan on using your API from a browser, from a different domain, add CORS headers.

Access-Control-Allow-Origin

Access-Control-Allow-Credentials

Access-Control-Expose-Headers

2015-02-19Parsys Telemedicine

Leverage Caching

Etag based on a value (could be a version increment, a hash, ...)Last-Modified on resource update.

Force cache invalidation if you need to.Ask (gently) proxies and clients not to cache if you don’t want them to.Cache-Control is your friend for both requirements.

2015-02-19Parsys Telemedicine

Limit Fields and Embed

Provide a way for Clients to specify which fields they need in query string:/api/agents/42?_fields=id,location,availability

And maybe you should provide an embed query string to load sub-resources:/api/agents/42?_embed=partners

2015-02-19Parsys Telemedicine

Rate Limiting

If you expose your API to others, rate limit.Better to return 429 to a subset of clients than 500s to everybody (and being blamed by ops).

Inform your client about it’s limits with headers :X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset

2015-02-19Parsys Telemedicine

Conclusion

2015-02-19Parsys Telemedicine

And last, but not least...

… be consistent with your API

2015-02-10

Join the community !(in Paris)

Social networks :● Follow us on Twitter : https://twitter.com/steamlearn● Like us on Facebook : https://www.facebook.com/steamlearn

SteamLearn is an Inovia initiative : inovia.fr

You wish to be in the audience ? Join the meetup group! http://www.meetup.com/Steam-Learn/

24