Restful API Design
Representational state transfer (REST) or RESTful web services are one way of providing interoperability between computer systems on the internet. REST-compliant web services allow requesting systems to access and manipulate textual representations of web resources using a uniform and predefined set of stateless operations.
Table of Contents
Everything is a resource
Any interaction of a RESTful API is an interaction with a resource. In fact, the API can be considered simply as mapping and endpoint - or, resource identifier (URL) - to a resource. Resources are sources of information, typically documents or services.
Resources can have different representations.
Design
Protocol
HTTPS
Domain
- https://api.example.com
- https://example.com/api/
Versioning
https://api.example.com/v1/
Endpoint
- https://api.example.com/v1/articles
- https://api.example.com/v1/tags
HTTP Verbs
HTTP Method | Action |
---|---|
GET | retrieve a representation of a resource without side-effects |
HEAD | retrieves just the resource meta-information (headers) |
OPTIONS | returns the actions supported for specified the resource |
POST | used for creating resources |
PUT | (completely) replace an existing resource |
PATCH | Used for updating resources with partial JSON data. For instance, an Issue resource has title and body attributes. A PATCH request may accept one or more of the attributes to update the resource. PATCH is a relatively new and uncommon HTTP verb, so resource endpoints also accept POST requests. |
DELETE | Used for deleting resources |
Filtering
- ?limit=10
- ?offset=10
- ?page=2&size=10
- ?sortedby=name&order=asc
- ?type=article
Status Codes
Error Handling
{
"error": "invalid token"
}
Responses
- GET /collection: list or array
- GET /collection/resource: single object
- POST /collection: return new object
- PUT /collection/resource: return whole object
- PATCH /collection/resource: return whole object
- DELETE /collection/resource: return an empty document
HTTP Status Code
Status-Code =
"100" ; Section 10.1.1: Continue
| "101" ; Section 10.1.2: Switching Protocols
| "200" ; Section 10.2.1: OK
| "201" ; Section 10.2.2: Created
| "202" ; Section 10.2.3: Accepted
| "203" ; Section 10.2.4: Non-Authoritative Information
| "204" ; Section 10.2.5: No Content
| "205" ; Section 10.2.6: Reset Content
| "206" ; Section 10.2.7: Partial Content
| "300" ; Section 10.3.1: Multiple Choices
| "301" ; Section 10.3.2: Moved Permanently
| "302" ; Section 10.3.3: Found
| "303" ; Section 10.3.4: See Other
| "304" ; Section 10.3.5: Not Modified
| "305" ; Section 10.3.6: Use Proxy
| "307" ; Section 10.3.8: Temporary Redirect
| "400" ; Section 10.4.1: Bad Request
| "401" ; Section 10.4.2: Unauthorized
| "402" ; Section 10.4.3: Payment Required
| "403" ; Section 10.4.4: Forbidden
| "404" ; Section 10.4.5: Not Found
| "405" ; Section 10.4.6: Method Not Allowed
| "406" ; Section 10.4.7: Not Acceptable
| "407" ; Section 10.4.8: Proxy Authentication Required
| "408" ; Section 10.4.9: Request Time-out
| "409" ; Section 10.4.10: Conflict
| "410" ; Section 10.4.11: Gone
| "411" ; Section 10.4.12: Length Required
| "412" ; Section 10.4.13: Precondition Failed
| "413" ; Section 10.4.14: Request Entity Too Large
| "414" ; Section 10.4.15: Request-URI Too Large
| "415" ; Section 10.4.16: Unsupported Media Type
| "416" ; Section 10.4.17: Requested range not satisfiable
| "417" ; Section 10.4.18: Expectation Failed
| "500" ; Section 10.5.1: Internal Server Error
| "501" ; Section 10.5.2: Not Implemented
| "502" ; Section 10.5.3: Bad Gateway
| "503" ; Section 10.5.4: Service Unavailable
| "504" ; Section 10.5.5: Gateway Time-out
| "505" ; Section 10.5.6: HTTP Version not supported
| extension-code
Hypermedia API
{
"login": "octocat",
"id": 1,
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"public_repos": 2,
"public_gists": 1,
"created_at": "2008-01-14T04:33:35Z",
"updated_at": "2008-01-14T04:33:35Z"
}
Others
Authentication
OAuth 2.0
JSON
Applied to web services
Web service APIs that adhere to the REST architectural constraints are called RESTful APIs. HTTP-based RESTful APIs are defined with the following aspects:
- Base URL
http://api.example.com/resources/
- An internet media type that defines state transition data elements (e.g. Atom, microformats, application/vnd.collection+json, etc.)
- Standard HTTP methods (e.g. OPTIONS, GET, PUT, POST and DELETE)
Relationship between URL and HTTP methods
HTTP Method | Collection http://api.example.com/resources/ |
Element http://api.example.com/resources/item17/ |
GET | List the URIs and perhaps other details of the collection’s members. | Retrieve a representation of the addressed member of the collection, expressed in an appropriate Internet media type. |
PUT | Replace the entire collection with another collection | Replace the addressed member of the collection, or if it does not exist, create it. |
POST | Create a new entry in the collection. The new entry’s URI is assigned automatically and is usually returned by the operation. | Not generally used. Treat the addressed member as a collection in its own right and create a new entry within it. |
DELETE | Delete the entire collection. | Delete the addressed member of the collection. |
Examples
Elasticsearch API
ELK (Elasticsearch Logstash Kibana) Stack
Github Users API
- get a single user
- GET /users/:username
- get the authenticated user
- GET /user
- update the authenticated user
- PATCH /user
- get all users
- GET /users
Github Repositories API
- List your repositories
- GET /user/repos
- List user repositories
- GET /users/:username/repos
- List organization repositories
- GET /orgs/:org/repos
- List all public repositories
- GET /repositories
- Create
- POST /user/repos
- POST /orgs/:org/repos
Tumblr API
Reblog a post: api.tumblr.com/v2/blog/{blog-identifier}/post/reblog
URI Structure
- api.tumblr.com/v2/blog/{blog-identifier}/…
- api.tumblr.com/v2/blog/{blog-identifier}/posts
- api.tumblr.com/v2/blog/{blog-identifier}/posts[/type]
- api.tumblr.com/v2/user/
OAuth
URL | Description |
---|---|
Request-token URL | https://www.tumblr.com/oauth/request_token |
Authorize URL | https://www.tumblr.com/oauth/authorize |
Access-token URL | https://www.tumblr.com/oauth/access_token |