scalabay - api design antipatterns
Post on 19-Oct-2014
243 views
DESCRIPTION
Slides from my talk on API Design Patterns at ScalaBay Meetup at Netflix on 09/09/2014. http://www.meetup.com/Scala-Bay/events/195982742/TRANSCRIPT
API An&pa)erns …iden&fying, and avoiding them
Manish Pandit @lobster1234
Manish Pandit @lobster1234
mpandit at neAlix dot com
linkedin.com/in/mpandit slideshare.net/lobster1234
@lobster1234
APIs
A means for soGware to interact with other soGware.
@lobster1234
@lobster1234
@lobster1234
Image Credit: h)p://en.wikipedia.org/wiki/Internet_of_Things
@lobster1234
REST API
REST is not a standard, but an architecture
@lobster1234
REST API
REST is not a standard, but an architecture, which uses HTTP as a model for all interac.ons.
If HTTP is a standard, REST is a conven&on.
@lobster1234
@lobster1234
REST API
Noun è Resource, or the En&ty
Verb è Ac&on
+ Iden.fier
@lobster1234
Image: h)p://www.educa&on.com/study-‐help/ar&cle/nouns/
@lobster1234
Protocol
May or may not be standard
@lobster1234
Protocol
May or may not be standard Indicates an agreement between the par&es
@lobster1234
@lobster1234
Payload
Format (XML, JSON, Custom Text, Binary..)
Transport (HTTP, Binary over sockets, FTP..)
@lobster1234
@lobster1234
h)p://www.neAlix.com/header/neAlix_logo.gif Or, reques.ng a resource from the server by
giving its path using a protocol.
@lobster1234
Every request deserves a response.
@lobster1234
Headers describe the response
@lobster1234
Headers describe the response
Status Code indicates the success/failure
@lobster1234
Headers describe the response
Status Code indicates the success/failure
Body contains the actual payload
@lobster1234
Tell the server what to do via ac.ons
@lobster1234
Ac&ons are HTTP methods, which map nicely to
(most of) the business interac&ons
@lobster1234
Create – POST Read – GET
Update – PUT (or PATCH) Delete -‐ DELETE
HEAD, OPTIONS, TRACE, CONNECT
@lobster1234
Pa)erns
@lobster1234
Pa)erns
Pa)erns are re-‐usable solu&ons to commonly occurring problems.
@lobster1234
Common Scenarios
Gebng data from the server
@lobster1234
Common Scenarios
Gebng data from the server
Sending data to the server
@lobster1234
An&pa)erns
An&pa)erns are re-‐usable solu&ons to commonly occurring problems, that look great on the surface, but
really aren’t.
@lobster1234
Request An&pa)erns
@lobster1234
Over-‐using Query Strings
@lobster1234
/pets?name=scruffy vs.
/pets/name/scruffy
@lobster1234
/pets?name=scruffy&zip=94568 vs.
/pets/name/scruffy/loca&on/zip/94568
@lobster1234
Avoid query strings for resource iden&fica&on But use them for request metadata *
*Except for search
@lobster1234
Pagina&on Filtering Sor&ng
..
@lobster1234
@lobster1234
Query Strings
h)p://some.api.com/movies?start=0&count=10&sortBy=name&fields=name,cast,releaseDate
@lobster1234
Allowing clients to scrape the data via your APIs
@lobster1234
@lobster1234
Think batch jobs reques&ng the catalog nightly!
@lobster1234
Request metadata to the rescue?
@lobster1234
….how about a ?since=1d
…or ?since=UTC
@lobster1234
Method An&pa)erns
@lobster1234
Using Query Strings to overload verbs
@lobster1234
/pets?perform=update&name=scruffy&id=24
@lobster1234
Use the appropriate HTTP Method to represent your ac&on
@lobster1234
Using POST for all writes
@lobster1234
GET to retrieve, or search POST to create, or upsert
PUT to update (or be)er yet, PATCH) DELETE to delete
@lobster1234
Using HTTP PUT or POST to set a value to null
@lobster1234
Updates vs. Deletes
Everything works when there is data, but what
when there is no data..?
@lobster1234
Use HTTP DELETE to set a value to null
Remember, we have a path to not just the resource, but also it’s
a)ributes
@lobster1234
DELETE /pets/<id>/collartag
@lobster1234
Response An&pa)erns
@lobster1234
Always returning HTTP 200
@lobster1234
@lobster1234
HTTP 200 OK
{ “success” : false }
@lobster1234
HTTP 200 OK
{ “error” : ”Person jdoe not found” }
@lobster1234
2xx for success 3xx for redirects/caching
4xx for request/client errors 5xx for server errors
@lobster1234
Some Useful (and not so common) Codes
Return aGer a delete -‐ 204 Failed database constraint -‐ 409 Method not supported -‐ 405
Trying to ask for too much data -‐ 413 Valida&on Failure -‐ 418
@lobster1234
Always returning a 401 for auth failures
@lobster1234
Auth
Use HTTP 401 Unauthorized to indicate that the client needs to authen&cate
@lobster1234
Auth
Use HTTP 403 Forbidden to indicate that the client’s creden&als do not allow access to the
requested resource
@lobster1234
401 vs 403
401 = Come back with a key
403 = Your key does not work for this lock.
@lobster1234
Processing requests synchronously, even &me
intensive ones
@lobster1234
Async the opera&on, and return HTTP 202 – Accepted
@lobster1234
@lobster1234
Async opera&on’s response should help the
caller.
{“statusUrl”: <some URL>}
@lobster1234
Organiza&onal An&pa)erns
@lobster1234
Not differen&a&ng between en..es and instances
@lobster1234
/pets?type=dog&name=big vs
/pets/dogs/name/big
@lobster1234
Namespace your resources in a collec&on Use paths and iden&fiers to traverse
@lobster1234
Using id in the resource iden&fica&on path
@lobster1234
/pets/id/1234
vs
/pets/1234
@lobster1234
Use all other a)ributes in the path, except the
id. id is implied
@lobster1234
@lobster1234
Resources in an island
@lobster1234
Every en&ty or a resource is &ed to others.
@lobster1234
Every en&ty or a resource is &ed to others.
And you’re stuck guessing the connec&ons!
@lobster1234
@lobster1234
We’ll just return the IDs!
HATEOAS
(or something similar)
@lobster1234
Read code to figure out the resources and
a)ributes.
@lobster1234
@lobster1234
Use Meta pages for resource descrip&on /resource/meta /collec&on/meta
@lobster1234
APIs are not discoverable
@lobster1234
Consider a documenta&on generator like Swagger, IODocs
@lobster1234
Relying on cookies for authen&ca&on
@lobster1234
@lobster1234
Accept cookies as a fallback, but prefer a query
parameter or HTTP request header.
@lobster1234
Storing state on the server nodes
@lobster1234
Stateless == Simple
@lobster1234
Requests either modify the state of a resource, or read it.
All requests to the cluster see the same state of the resource
@lobster1234
Avoid state as much as possible. Maintain the state in the database.
If you need to store transient state on the server, it’s a code (or architecture) smell.
@lobster1234
Versioning Using 301s to redirect/re&re APIs
Caching
Using HTTP headers correctly Caching response bodies
@lobster1234
@lobster1234
Fin