It's possible to make a structured, consistent, API that can handle changes to logic and the schema. Sure, it seems like a good plan to dump everything out of the database today, but what are you going to do when something changes down the road? Let's have a talk about some SOLID ways to structure our APIs and keep them from breaking down the road.
Hot Service (+9316020077 ) Goa Call Girls Real Photos and Genuine Service
Extreme APIs for Better Tomorrow
1. EXTREME
APIS
for a better tomorrow
http://www.aaronmaturen.com/api 1
2. I'm Aaron.
• I work at Saginaw Valley State University in Michigan
• I normally write in PHP and JavaScript
• I am going to try to keep this (mostly) langauge agnostic
http://www.aaronmaturen.com/api
http://www.aaronmaturen.com/api 2
3. I have a small company (Ivory Penguin) to do side jobs
http://www.aaronmaturen.com/api 3
14. Leverage HTTP
Create => POST
Read => Get
Update => PUT / PATCH
Delete => DELETE
http://www.aaronmaturen.com/api 14
15. Leverage HTTP for Collections
http://api.svsu.edu/courses
POST => Update entire collection
GET => Retrieve the entire collection
PUT => Replace the entire collection
PATCH => Modify the collection
DELETE => Delete the entire collection
http://www.aaronmaturen.com/api 15
16. Leverage HTTP for elements
http://api.svsu.edu/courses/
courseNumber
POST => Update a single course element
GET => Retrieve a single course element
PUT => Replace a single course element
PATCH => Modify a single course element
DELETE => Delete a single course element
http://www.aaronmaturen.com/api 16
17. {json:api} 1
If you've ever argued with your team about the way your JSON
responses should be formatted, JSON API is your anti-bikeshedding
weapon.
By following shared conventions, you can increase productivity,
take advantage of generalized tooling, and focus on what
matters: your application.
1 http://jsonapi.org/
http://www.aaronmaturen.com/api 17
18. A JSON object MUST be at the root of every document.
A document's top level SHOULD contain a representation of
the resource or collection requested.
The primary resource(s) SHOULD be keyed either by their
resource type or the generic key "data".
http://www.aaronmaturen.com/api 18
19. {
"posts": {
"id": "1",
// ... attributes of this post
}
}
http://www.aaronmaturen.com/api 19
20. {
"posts": [{
"id": "1"
// ... attributes of this post
}, {
"id": "2"
// ... attributes of this post
}]
}
http://www.aaronmaturen.com/api 20
23. Plural v. Singular
/persons
/person/23
Mixing it up starts to get confusing
/persons
/persons/23
/persons/23/courses
http://www.aaronmaturen.com/api 23
24. Query Strings
GET /persons?name=Aaron%20Maturen HTTP/1.1
Host: api.svsu.edu
http://www.aaronmaturen.com/api 24
28. 2xx is all about success
200 - Generic everything is OK
201 - Created something OK
202 - Accepted but is being processed async (for a video
means encoding, for an image means resizing, etc)
http://www.aaronmaturen.com/api 28
29. 3xx is all about redirection
301 - Moved permanently
302 - Moved temporarily
304 - Not Modified
http://www.aaronmaturen.com/api 29
30. 4xx is all about client errors
400 - Bad Request (should really be for invalid syntax, but
some folks use for validation)
401 - Unauthorized (no current user and there should be)
403 - The current user is forbidden from accessing this data
404 - That URL is not a valid route, or the item resource does
not exist
405 - Method Not Allowed
410 - Data has been deleted, deactivated, suspended, etc
418 - I'm a teapot
http://www.aaronmaturen.com/api 30
31. 5xx is all about service errors
500 - Something unexpected happened and it is the API's fault
503 - API is not here right now, please try again later
507 - Hard-drive filled up.
http://www.aaronmaturen.com/api 31
33. HTTP/1.0 401 Unauthorized
Date: Fri, 19 Oct 2014 16:59:59 GMT
Content-Type: application/vnd.api+json
{
"error": {
"type": "OAuthException",
"message": "Session has expired at unix time 1385243766.
The current unix time is 1385848532."
}
}
http://www.aaronmaturen.com/api 33
34. HTTP/1.0 401 Unauthorized
Date: Fri, 19 Oct 2014 16:59:59 GMT
Content-Type: application/vnd.api+json
{
"error": {
"type": "OAuthException",
"code": "ERR-01234",
"message": "Session has expired at unix time 1385243766.
The current unix time is 1385848532."
"documentation_url": "/docs/errors/#ERR-01234"
}
}
http://www.aaronmaturen.com/api 34
35. 200 OK
and
Error Code
http://www.aaronmaturen.com/api 35
36. If it's a 2xx code.
It doesn't get an error code.
EVER.
http://www.aaronmaturen.com/api 36
38. It's normally a very bad idea to
just output a db table through
your API
http://www.aaronmaturen.com/api 38
39. You're ...
• revealing your database structure
• probably returning incorrect value types
• returning everything
• tightly coupling your api to the database
http://www.aaronmaturen.com/api 39
52. Remember the example from
before...
GET /persons/23 HTTP/1.1
Host: api.svsu.edu
This is better
GET /persons/66dc3930-5928-11e4-8ed6-0800200c9a66 HTTP/1.1
Host: api.svsu.edu
http://www.aaronmaturen.com/api 52
53. Pagination
GET /persons/teaches=Y HTTP/1.1
Host: api.svsu.edu
• Downloading more stuff takes longer
• Your database might not be happy about trying to return
100,000 records in one go
• Presentation logic iterating over 100,000 records is also no
fun
http://www.aaronmaturen.com/api 53
55. {
"persons": [ ...],
"pagination": {
"cursors": {
"after": 12,
"next_url": "/places?cursor=12&number=12"
}
}
}
If the API returns 12 persons then there might be a next page.
http://www.aaronmaturen.com/api 55
56. Lions, and Tigers, and FERPA
Oh my.
We're not returning anything protected by FERPA to
anonymous users
GET /persons?name=Student%20McStudent HTTP/1.1
Host: api.svsu.edu
http://www.aaronmaturen.com/api 56
57. persons: [{}]
We could have returned an unauthorized
error (401), but we decided to just act like
we didn't find anything
http://www.aaronmaturen.com/api 57
58. OAuth to the rescue
GET /persons?name=Student%20McStudent HTTP/1.1
Host: api.svsu.edu
Authorization: Bearer qxacJ57Yo5XEhzExjsJgLleLoBRXz7kn9ySFB3sY
may return
persons: [{
firstName: "Student",
...
}]
http://www.aaronmaturen.com/api 58
59. OAuth Grant Types
• Authorization Code
Typical third party workflow, takes user to a common login
page, they enter their credentials, they are taken to a
page that explains which rights the application would like to
have and the user approves it.
http://www.aaronmaturen.com/api 59
60. OAuth Grant Types
• Password (user credentials)
User Credentials are possibly the easiest way to get an
access token for a user. It skips the whole redirect-flow that
“Authentication Code” provides Internal Apps Only
• Refresh Token
Users receive a 401 when the access token expires and the
client automatically requests a new one with it's refresh
token
http://www.aaronmaturen.com/api 60
61. OAuth Grant Types
• Client Credentials
The application will not have any context of a “user”, but it
will be able to interact with your API. This is useful for CRON
jobs, worker processes, daemons or any other sort of
background process.
• Custom Grant Type
You're free to add any new grant types that you would like
http://www.aaronmaturen.com/api 61
67. Password Authentication
• Login to the API and the Application simultaneously
Authorization Code
• Allow students and third parties to access our data
• Users are notified that the application is not created by IT
and informed of what rights it is requesting
http://www.aaronmaturen.com/api 67