build an api the right way
TRANSCRIPT
![Page 1: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/1.jpg)
Building an API the right way@kurenn
![Page 2: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/2.jpg)
How does a web-service works?
![Page 3: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/3.jpg)
ServerClient
Request
Response
Request
Response
Request
Response
Each request generates a response, could be a success or and error response.
This is how the REST API currently works.
REST is about exposed resources so we can perform operations on things and get back responses
Client-Server Communication
![Page 4: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/4.jpg)
Resources
![Page 5: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/5.jpg)
Individual Resource Representation
An individual resource should be represented as a simple JSON object
{ "user": { "id": 1, "email": "[email protected]", "name": "Abraham Kuri" } }
![Page 6: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/6.jpg)
Multiple Resource Representation
A collection of resources should be represented as an array of JSON objects
{ "users": [{ "id": 1, "email": "[email protected]", "name": "Abraham Kuri" }, { "id": 2, "email": "[email protected]", "name": "Eduardo Lopez" }] }
![Page 7: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/7.jpg)
To-One Relationship Resource Representation
An object embedded into another one
{ "post": { "id": 1, "content": "This is my giving a SG talk", "created_at": "2014-10-12T19:34:23Z", "author": { "id": 1, "name": "Abraham Kuri" } } }
![Page 8: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/8.jpg)
To-Many Relationship Resource Representation
An object embedded with a collection of other related objects
{ "book": { "id": 1, "title": "API's on Rails", "authors": [{ "id": 1, "name": "Abraham Kuri" }, { "id": 2, "name": "Osvaldo Ayala" }] } }
Be aware that this may be inefficient,
due to the number of authors.
In this case creating another endpoint for authors, would be a
good solution.
![Page 9: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/9.jpg)
GET
Use it to fetch a resource or collection of resources
/books/books/1
200 - Success
/books/1/authors
![Page 10: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/10.jpg)
POSTUse to create a single resource, but some API’s may support
multiple creation
/books
201 - Created
/books/1/authors
![Page 11: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/11.jpg)
PUTUse to update a resource, but some API’s may support
multiple resource update
/books/1
200 - Success
/authors/1
![Page 12: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/12.jpg)
DELETE
Use to delete a specific resource
/books/1
204 - No Content
/authors/1
![Page 13: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/13.jpg)
Meta
"meta": { "pagination": { "per_page": 20, "total_pages": 1, "total_objects": 2 } }
![Page 14: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/14.jpg)
Content Negotiation
![Page 15: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/15.jpg)
Server
ClientRequest
JSON
Request
XML
Request
HTML
The API should be able to process multiple types of content to send to the client.
Understanding Content-Negotiation
Client
Client
This can be easily achieve by appending the format to the URI
http://api.icalialabs.com/members.json
![Page 16: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/16.jpg)
Using the Accept Header for Content Negotiation
Accept: “application/json”
http://api.icalialabs.com/members
![Page 17: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/17.jpg)
I18n
![Page 18: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/18.jpg)
Using the Accept-Language Header for Internationalization
Accept-Language: “es”
http://api.icalialabs.com/members
This way the API supports multiple languages for the response
![Page 19: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/19.jpg)
VersioningVersioning helps prevent major changes from breaking existing clients
![Page 20: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/20.jpg)
Versioning
Through the URL
http://api.icalialabs.com/v1/members
Through an Accept Header
http://api.icalialabs.com/members
Accept: application/vnd.icalialabs.com+json; version=1
![Page 21: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/21.jpg)
Authentication Authentication is how servers prevent unauthorized access to protected resources.
![Page 22: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/22.jpg)
Authentication
There are two ways you can authenticate clients
Basic Authentication
Token Based AuthenticationGET /episodes HTTP/1.1 Host: localhost:3000 Authorization: Token token=16d7d6089b8fe0c5e19bfe10bb156832
GET /episodes HTTP/1.1 Host: localhost:3000 Authorization: Basic Zm9vOnNlY3JldA==
![Page 23: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/23.jpg)
Understanding denied access
You should handle the unauthorized access with a WWW-Authenticate header with a 401 HTTP code response
HTTP/1.1 401 UnauthorizedWWW-Authenticate: Basic realm="Application"Content-Type: text/html; charset=utf-8
“realm” is used for different protection spaces, in this case is the whole application
![Page 24: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/24.jpg)
http://jsonapi.org/
http://apionrails.icalialabs.com/book/
https://github.com/rails-api/active_model_serializers
http://jsonapi.org/extending/
Where to go next?
http://sudo.icalialabs.com/a-short-story-on-timming-attack/
![Page 25: Build an API the right way](https://reader033.vdocuments.us/reader033/viewer/2022052912/55a05db91a28ab522e8b45aa/html5/thumbnails/25.jpg)
Thanks!