Upload
aaron-maturen
View
120
Download
3
Embed Size (px)
Citation preview
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
What is an API?API => Application Programming InterfaceREST => REpresentational State Transfer
http://www.aaronmaturen.com/api 7
Conventions?
DEAN_ROLECHAIR_ROLEEmployeeRoleDeanRole2DeanRole3ChairRole2ChairRole3ChairRole4
http://www.aaronmaturen.com/api 10
Leverage HTTPCreate => POSTRead => GetUpdate => PUT / PATCHDelete => DELETE
http://www.aaronmaturen.com/api 14
Leverage HTTP for Collectionshttp://api.svsu.edu/courses
POST => Update entire collectionGET => Retrieve the entire collectionPUT => Replace the entire collectionPATCH => Modify the collectionDELETE => Delete the entire collection
http://www.aaronmaturen.com/api 15
Leverage HTTP for elementshttp://api.svsu.edu/courses/courseNumber
POST => Update a single course elementGET => Retrieve a single course elementPUT => Replace a single course elementPATCH => Modify a single course elementDELETE => Delete a single course element
http://www.aaronmaturen.com/api 16
{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
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
{ "posts": [{ "id": "1" // ... attributes of this post }, { "id": "2" // ... attributes of this post }]}
http://www.aaronmaturen.com/api 20
{ "prefixes": [ { "prefix": "ACCT", "description": "Accounting" }, { "prefix": "ART", "description": "Art" }, ... ]}
http://www.aaronmaturen.com/api 22
Plural v. Singular/persons/person/23
Mixing it up starts to get confusing
/persons/persons/23/persons/23/courseshttp://www.aaronmaturen.com/api 23
Query StringsGET /persons?name=Aaron%20Maturen HTTP/1.1 Host: api.svsu.edu
http://www.aaronmaturen.com/api 24
{ "persons": [{ "firstName": "Aaron", "middleInitial": "T", "lastName": "Maturen", "email": "[email protected]", "division": "Administration & Business Affairs", "department": "Information Technology Services", "program": "Administration & Business Aff.", "title": "Developer", "office": { "location": "SVSU Main Campus", "phone": "989-964-2190", "room": "South Campus Complex B 117", "hours": null }, "degrees": [...], "ferpa": true, "username": "atmature", "faculty": false, "academicDepartment": false ... }]}
http://www.aaronmaturen.com/api 25
2xx is all about success
200 - Generic everything is OK201 - Created something OK202 - Accepted but is being processed async (for a videomeans encoding, for an image means resizing, etc)
http://www.aaronmaturen.com/api 28
3xx is all about redirection
301 - Moved permanently302 - Moved temporarily304 - Not Modified
http://www.aaronmaturen.com/api 29
4xx is all about client errors
400 - Bad Request (should really be for invalid syntax, butsome folks use for validation)401 - Unauthorized (no current user and there should be)403 - The current user is forbidden from accessing this data404 - That URL is not a valid route, or the item resource doesnot exist405 - Method Not Allowed410 - Data has been deleted, deactivated, suspended, etc418 - I'm a teapothttp://www.aaronmaturen.com/api 30
5xx is all about service errors
500 - Something unexpected happened and it is the API's fault503 - API is not here right now, please try again later507 - Hard-drive filled up.
http://www.aaronmaturen.com/api 31
HTTP/1.0 401 UnauthorizedDate: Fri, 19 Oct 2014 16:59:59 GMTContent-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
HTTP/1.0 401 UnauthorizedDate: Fri, 19 Oct 2014 16:59:59 GMTContent-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
It's normally a very bad idea to just output a db table through
your API
http://www.aaronmaturen.com/api 38
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
Remember our poorly named fields?
DEAN_ROLECHAIR_ROLEEmployeeRoleDeanRole2DeanRole3ChairRole2ChairRole3ChairRole4
http://www.aaronmaturen.com/api 40
Those get cleaned up quite nicely
{ "persons": [{ "firstName": "Joni", "middleInitial": "M", "lastName": "Boye-Beaman", "division": "Academic Affairs", "department": "College of Arts & Behavioral Sciences", "title": "Dean College of Arts & Behavioral Sciences", "dean": true, "chair": false ... }]}
http://www.aaronmaturen.com/api 41
Offices are nicer
LocationDescBuildingDescPriCampusOfficePriCampusPhonePriCampusFax
http://www.aaronmaturen.com/api 42
Offices are nicer
{ "persons": [{ "firstName": "Joni", "middleInitial": "M", "lastName": "Boye-Beaman", "office": { "location": "SVSU Main Campus", "phone": "989-964-4062", "room": "Wickes Hall 363", "hours": null }, ... }]}
http://www.aaronmaturen.com/api 43
Degrees are nicer
Degree1Degree2Degree3Degree4DegreeInSta1DegreeInSta2DegreeInSta3DegreeInSta4
http://www.aaronmaturen.com/api 44
Degrees are nicer
{ "persons": [{ "firstName": "Joni", "middleInitial": "M", "lastName": "Boye-Beaman", "degrees": [{ "degree": "Doctor of Philosophy", "from": "State Univ New York-albany" }], ... }]}
http://www.aaronmaturen.com/api 45
Hiding Schema UpdatesBefore
'firstName' => $person->nickName,
After
'firstName' => $person->firstName,
http://www.aaronmaturen.com/api 46
Hiding Schema UpdatesBefore
'status' => $person->status,
After
'status' => $person->status === 'a' ? 'available' : $person->status ,
http://www.aaronmaturen.com/api 47
Inclusion of Linked ResourcesGET /departments/?embed=colleges.deans HTTP/1.1 Host: api.svsu.edu
http://www.aaronmaturen.com/api 49
{ "departments": [{ "department": "CS", "colleges": { "college": "SC", "description": "Science Engineering & Technology", "deans": [{ "firstName": "Andrew", "middleInitial": "M", "lastName": "Chubb", ... }] ... }]}
http://www.aaronmaturen.com/api 50
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
PaginationGET /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
{ "persons": [ ...], "pagination" : { "total": 1262, "count": 12, "per_page": 12, "current_page": 1, "total_pages": 107, "next_url": "/persons?page=2&number=12", }}
http://www.aaronmaturen.com/api 54
{ "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
Lions, and Tigers, and FERPAOh 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
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
OAuth to the rescueGET /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
OAuth Grant Types
• Authorization Code
Typical third party workflow, takes user to a common login page, they enter their credentials, they are taken to apage that explains which rights the application would like to have and the user approves it.
http://www.aaronmaturen.com/api 59
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
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
POST /oauth/access_token HTTP/1.1 Host: api.svsu.edu { grant_type: "password", client_id: "98f9bc2f27159248b3e51fa9fd91a5f9", client_secret: "7329d92ebf23efc145b7370d5f4fbf32", username: "[email protected]", password: "secret", scope: "read_users", state: "123456789" }
http://www.aaronmaturen.com/api 62
HTTP/1.0 200 OKDate: Sun, 19 Oct 2014 16:59:59 GMTContent-Type: application/vnd.api+json{ "access_token": "qxacJ57Yo5XEhzExjsJgLleLoBRXz7kn9ySFB3sY", "token_type": "bearer", "expires": 1400880256, "expires_in": 604800, "refresh_token": "hHgKUskwd9Ukr08CtynO8PjHcV1CZICi1yU3nNmo"}
http://www.aaronmaturen.com/api 63
Apps
• Course Lookup
• Employee Directory
• Student Voting
• Grant logging
• HealthyU
http://www.aaronmaturen.com/api 66
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