whoami Developer at Keboola currently more on UI/JS than PHP building ETL platform Keboola Connection writing about it at 500.keboola.com Occasional speaker, geek, blogger twitter.com/ujovlado medium.com/@ujovlado ujovlado.com 2
State of the APIs? It's 2019 and we're still building (or maintaining) the APIs which are huge PITA to use. Cause: Bad design decisions made (e.g. consuming form-data) Developers are careless about API consumers (e.g. objects everywhere) Developers are lazy (e.g. 400 Bad Request for all things that cannot be processes) 4
Fail: Not accepting endpoint w/o trailing / GET /users/ HTTP/1.1 200 OK GET /users HTTP/1.1 500 Internal Server Error Something like your web not working without www part 6
But it can be even worse Redirects, they said ... GET /users HTTP/1.1 301 Moved Permanently Location: /users/ POST /users HTTP/1.1 301 Moved Permanently Location: /users/ 7
401 Unauthorized vs. 403 Forbidden It's not the same (obviously) 401 Unauthorized I'm accessing API without valid credentials (token, authorization, etc) 403 Forbidden I'm authorized but not allowed to access speci c endpoint or Rate limiting is in action 8
TIP: Return 404 Not Found in some cases Imagine rst user is authenticated. User is allowed to access /pictures/123 (because he uploaded that picture) There's another image with id 456 uploaded by other user Accessing /pictures/456 should return 404 Not Found for the rst user not 403 Forbidden Otherwise we're leaking existence Security issue. 9
Fail: 201 Created with empty body POST /users HTTP/1.1 201 Created I don't know what's that mean Where is resource I just created? Well, I'll get it my way: GET /users ^ That can be prevented 12
Tip: Return new resources For creation, return newly created: POST /users HTTP/1.1 201 Created { "username": "ujovlado", "email": "vlado@..." } For updates, return updated resource: PUT /users/ujovlado HTTP/1.1 200 OK { ... 13
Tip: 202 Accepted for async resource actions There are some cases when requests action is processed asynchronously Provide meaningful response, so consumer can check processing (if available) 14
Tip: Allow browser usage Don't expect only server to server communication (especially not these days when "everything" is moving to client). Accept OPTIONS method. And response with proper headers. OPTIONS / HTTP/1.1 204 No Content Access-Control-Allow-Headers: ... Access-Control-Allow-Methods: ... Access-Control-Allow-Origin: * 16
Fail: Versioning instead of evolution Issuing new endpoint (e.g. /v3 ) is the same like major version of the library. It is less invasive if your APIs are used through client libraries, but still a BC break. 20
Include related resources Instead of 2 requests GET /users/ujovlado and GET /users/ujovlado/devices , special parameter is used to include also related resources. GET /users/ujovlado?include=devices { ... "devices": [ {"type": "mobile"}, {"type": "screen"} ] } 22
Respect cache-related headers If request is made with header If-Modified-Since: Thu, 05 Feb 2019 15:31:30 GMT you should return data only if resource changed. Otherwise return 304 Not Modify 23
Tips & Links Spend more time on designing Design your API with respect to some speci cation (e.g. https://jsonapi.org/ is better than nothing) Or use framework which will do it Do not reinvent a wheel, get inspired by highly used APIs (Github API, etc.) For REST APIs, check: https://apisyouwonthate.com/ Try to write simple SPA consuming your API 26