You are on page 1of 36

Fabin Andrs Sabogal

(@fvioz)

Good ways to
build an api

Agenda
Know the standards
Design human readable URLs
JSON as beautiful object
Thinking big

Know the standards


?

Http Method definitions

Methods
GET means retrieve whatever information
POST used to request that the origin server accept the entity enclosed in
the request as a new subordinate of the resource
PUT requests that the enclosed entity be stored under the supplied
Request-URI
DELETE requests that the origin server delete the resource identified by
the Request-URI
HEAD method is identical to GET except that the server MUST NOT return
a message-body in the response
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

Know the standards


?

HTTP status codes

API Cocktails, enjoy it and learn it

https://github.com/3scale/httpstatus_cocktails/

Success codes
200 OK - Response to a successful GET, PUT, PATCH or DELETE.
Can also be used for a POST that doesn't result in a creation.
201 Created - Response to a POST that results in a creation.
Should be combined with a Location header pointing to the
location of the new resource
204 No Content - Response to a successful request that won't
be returning a body (like a DELETE request)
304 Not Modified - Used when HTTP caching headers are in
play

Error codes
400 Bad Request - The request is malformed, such as if the body does
not parse
401 Unauthorized - When no or invalid authentication details are
provided. Also useful to trigger an auth popup if the API is used from a
browser
403 Forbidden - When authentication succeeded but authenticated
user doesn't have access to the resource
404 Not Found - When a non-existent resource is requested
405 Method Not Allowed - When an HTTP method is being requested
that isn't allowed for the authenticated user

Error codes
410 Gone - Indicates that the resource at this end point is no
longer available. Useful as a blanket response for old API versions
415 Unsupported Media Type - If incorrect content type was
provided as part of the request
422 Unprocessable Entity - Used for validation errors
429 Too Many Requests - When a request is rejected due to rate
limiting
500 Internal Server Error

Know the standards


?

JSON

JSON

JavaScript Object Notation, is an open standard


format that uses human-readable text to transmit data
objects consisting of attributevalue pairs. It is used
primarily to transmit data between a server and web
application, as an alternative to XML.

JavaScript is to Java as ham is to hamster


Jeremy Keith

Design human readable URLs

The easier your API is to consume, the more people


that will consume it.

Definitions
Resource: A single instance of an object. For example, an animal.
Collection: A collection of homogeneous objects. For example, animals.
Consumer: A client computer application capable of making HTTP
requests.
Third Party Developer: A developer not a part of your project but who
wishes to consume your data.
Endpoint: An API URL on a Server which represents either a Resource or
an entire Collection.
URL Segment: A slash-separated piece of information in the URL.

Choose a root

Here are two common URL Roots:


https://example.com/*
https://api.example.com/*

Endpoints
Collections
https://api.example.com/v1/friends
https://api.example.com/v1/employees
Use nouns but no verbs
Use plural nouns

Endpoints
Resource
GET

/friends: List all Frends (ID and Name).

POST

/friends: Create a new Friend

GET

/friends/1234: Retrieve an Friend object

PUT

/friends/1234: Update an Friend (entire object)

PATCH

/friends/1234: Update an Friend (partial object)

DELETE /friends/1234: Delete an Friend (partial object)

Design human readable URLs

Filtering
Minimize the arbitrary limits imposed on Third Party Developers

Filtering
?limit=10: Reduce the number of results returned to the
Consumer (for Pagination)
?offset=10: Send sets of information to the Consumer (for
Pagination)
?sort=+name,-age: Sort the results based on the specified
attribute (ORDER BY name ASC, ORDER BY age DESC)
?fields=name,age,friends: Select the attributes for a results
(SELECT name, age)
/comments?filter[post]=1,2&filter[author]=12

Deep level
Use sub-resources for relations
Simplify associations - sweep complexity under the ?

GET /companies/1/departments/1/
employes/1

GET /companies/1
GET /companies/1/departments
GET /departments/1/employees

GET /dogs/color/red/state/running/
location/park

GET /employees/1
GET /dogs?color=red&state=running&location=park

Json as beautiful object

How should I show the data?

Top level structure

{
"data": {
},
"errors": {
},
"meta": {
// non-standard meta-information about the primary data.
},
"included": {
// a list of resource objects that are related to the primary data and/or
// each other ("included resources").
}
}

Resource structure
GET

/articles/1

{
data: {
"type": "articles",
"id": "1",
"title": "Rails is Omakase",
"links": {
"self": "https://api.example.com/articles/1"
"comments":"https://api.example.com/articles/1/comments"
}
}
}

Collection structure
GET

"data": [{
"type": "articles",
"id": "1",
"title": "JSON API paints my bikeshed!",
"links": {
"self": https://api.example.com/articles/1",
"authors": {
"self": https://api.example.com/articles/1/authors,
"linkage": { "type": "people", "id": "9" }
},
"comments": {
"self": https://api.example.com/articles/1/comments"
}
}
}],

/articles

"included": [{
"type": "people",
"id": "9",
"first-name": "Dan",
"last-name": "Gebhardt",
"links": {
"self": https://api.example.com/people/9"
}
}]

Meta structure
GET

/articles/1

{
"meta": {
"copyright": "Copyright 2015 Example Corp.",
"authors": [
"Yehuda Katz",
"Steve Klabnik",
"Dan Gebhardt"
]
}
}

Pagination
GET
{
"meta": {
"count": 5,
"pagination":
first: 1,
last: 5,
"prev": 1,
"next":
"current":
"per_page":
"count":
}
}

3,
2,
5,
23

/articles

Errors
POST

/articles

{
"errors": {
"code": 422,
"status": "Invalid Resource",
"title": "The current resource was deemed invalid.",
"messages": {
"name":
["can't be blank"],
id_number: ["can't be blank", "is not a number"],
"company":
["is too short (minimum is 5 characters)", "is invalid"]
}
}
}

k
n
i
h
T

g
in

g
i
b

Versioning
1. URL: You simply whack the API version into the URL, for
example: https://api.example/v2/accounts/foo
2. Custom request header: You use the same URL as before
but add a header, for example: https://api.example.com/
accounts/foo
api-version: 2
3. Accept header: You modify the accept header to specify the
version, for example: https://api.example.com/accounts/foo
Accept: application/vnd.api.v2+json

Request Headers

Versioning, which is better?

1. URLs suck because they should represent the entity


2. Custom request headers suck because its not really
a semantic way of describing the resource.
3. Accept headers suck because theyre harder to test.

Caching
There are 2 approaches: ETag and Last-Modified
ETag: When generating a request, include a HTTP header ETag
containing a hash or checksum of the representation. This value should
change whenever the output representation changes. Now, if an inbound
HTTP requests contains a If-None-Match header with a matching ETag
value, the API should return a 304 Not Modified status code instead of
the output representation of the resource.
Last-Modified: This basically works like to ETag, except that it uses
timestamps. The response header Last-Modified contains a timestamp in
RFC 1123 format which is validated against If-Modified-Since. Note that
the HTTP spec has had 3 different acceptable date formats and the server
should be prepared to accept any one of them.

Rate limiting
X-Rate-Limit-Limit - The number of allowed requests in
the current period
X-Rate-Limit-Remaining - The number of remaining
requests in the current period
X-Rate-Limit-Reset - The number of seconds left in the
current period

Resources
http://json.org
http://jsonapi.org
http://apiux.com
http://www.troyhunt.com/2014/02/your-api-versioning-is-wrong-whichis.html
http://www.toptal.com/api-developers/5-golden-rules-for-designing-agreat-web-api
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

Questions ?

,
s
k
n
a
h
e
T
n
o
y
r
e
v
E

You might also like