An overview of how to structure your Lumen APIs to make them awesome. Topics covered: requests, responses, logging, documentation and testing.
Slides assume some background in Laravel.
6. • Also, an excellent use of subdomain routing:
Routing
Requests
7. • Create an /api/1/ping route for public APIs
• Don’t put any middleware in front of the route
• Two reasons:
• Lets clients easily check if server is up
• First step of integrating with an API is just making sure
your request reaches the remote server.
Routing
Requests
8. • Choose an endpoint structure and stick to it
• Have awesome documentation for all endpoints
we will come back to this
• GET is a safe method
this should really go without saying
• PUT and DELETE are idempotent
operation should always produce same result
Routing
Requests
9. • GET https://example.com/api/1/users
• POST https://example.com/api/1/users
• GET https://example.com/api/1/users/1
• PUT https://example.com/api/1/users/1
• DELETE https://example.com/api/1/users/1
Routing
Requests
11. • Session based authentication not appropriate
• Three options:
• Access token authentication
for server-server apps - you provide token in advance
• JSON web token
for client-side apps - you provide a token at user login
• Oauth
for third party apps accessing existing user accounts on your system
Authentication methods
Requests
12. • https://github.com/tymondesigns/jwt-auth
• Scales much better than other options - each server
validates the token, rather than making a DB call
• Frontend apps should store the token with LocalStorage
• Tokens should expire
use refresh tokens to generate new tokens
Authentication - JSON web tokens
Requests
14. • Avoid the magic controller validation
• Instead create a validation class, call it and check in your
controller if it fails
Validation
Requests
15. • Awesome APIs accept many date formats
• Validation facades date validator uses strtotime
• Carbon’s parse method uses strtotime
• Combine the two and you can safely accept any date
• Caveat… a unix timestamp is not parsed by strtotime
Dates
Requests
16. • Even APIs should have a view layer
• Explicitly cast all types
Transformers
Responses
17. • Do not forget to transform your Carbon objects
Transformers
Responses
18. • Use a transformer package
• https://github.com/salebab/larasponse
the documentation sucks, but it’s still the best package
• You provide a class with a transform method, then simply
call it in any controller:
Transformers
Responses
19. • Power comes when you want to include other transforms
in your transformer (transformer class)
• Always include with a transformer (transformer class):
• Or optional include (controller class):
Transformers
Responses
20. • Response macros let you include additional meta data to
response
• Macros also ensure consistency of base response across all
response statuses and all endpoints
• Register in a service provider:
Response Macros
Responses
21. • Log all requests and all responses
• This is 10x as true if you are making a public API
• Make your logs easily accessible
no, SSHing into a server is not easily accessible
When to log
Logging
22. • Shameless plug for today’s sponsor: www.understand.io
probably the best option, so not such a shameless plug
• Anything supported by Monolog should work out the box
• https://papertrailapp.com
• https://www.loggly.com
• The ELK stack https://www.elastic.co
open source
Logging services
Logging
23. • One is auto documented, one isn’t:
Auto documenters
Documentation
24. • http://readme.io/
• https://apiary.io/
• https://www.mashape.com/
• http://swagger.io/ -> popular auto documenter
• GitHub/Bitbucket wikis
Documentation services
Documentation
25. • Tell developers about any breaking API changes
• Give 30 days notice of breaking changes or downtime
ideally longer
• Make it super clear you won’t use the mailing list for
marketing
• Never use the mailing list for marketing
Mailing list
Documentation
26. • Write full end to end API tests. Lumen supports these out
the box:
API tests
Testing
27. • Statically define your test expectations for a given route
your seeder will need to have some fixtures for this
Test every field
Testing
28. • Returning a 200 when you should be returning a 403
(forbidden) is inexcusable.
Test failures
Testing