May 25, 2015
Principles of building effective REST API
Georgiy Podsvetov
Georgiy Podsvetov
What is REST?Representational State Transfer
is an architecture style for designing networked applications
Roy Fielding(1965 — )
Architectural Styles and the Design of Network-based Software Architectures
(2000, University of California, Irvine)
Georgiy Podsvetov
• Resources • URI • Representations • Safe and Idempotent operations • Visibility • Linking • Caching
Georgiy Podsvetov5
GET get a representation of a resource
PUT update a resource
DELETE delete a resource
POST perform a variety of potentially nonidempotent and unsafe operations
Add appropriate HTTP headers to describe requests and responses
Georgiy Podsvetov6
Method Safe? Idempotent?
GET YES YES
HEAD YES YES
OPTIONS YES YES
PUT NO YES
DELETE NO YES
POST NO NO
Georgiy Podsvetov7
Use GET for safe and idempotent information retrieval
Georgiy Podsvetov8
• To create a new resource, using the resource as a factory
• To modify one or more resources via a controller resource
• To run queries with large inputs • To perform any unsafe or nonidempotent
operation when no other HTTP method seems appropriate
POST
Georgiy Podsvetov9
Slug header (RFC 5023)
Use PUT to create new resources only when clients can decide URIs of resources.
Otherwise, use POST.
Georgiy Podsvetov10
Asynchronous creation• Create «State Resource» • Return status code 202 (Accepted) • Let a client track the status of the asynchronous task
using this resource
Still processing 200 (OK) and description of current status
On success 303 (See Other) and Location header with resource URI
On error 200 (OK) with error description
Georgiy Podsvetov11
Avoid using nonstandard custom HTTP methods New methods — you cannot rely on off-the-shelf software that only knows about the standard HTTP methods
Instead, design a controller resource that can abstract such operations, and use HTTP method POST
Georgiy Podsvetov
Custom methods
12
• Use custom headers for informational purposes only • Omitting custom headers shouldn’t fail processing
request or response • Avoid using custom HTTP headers to change the
behavior of HTTP methods
Georgiy Podsvetov
Custom headers
13
X-HTTP-Method-Override
use POST and distinct resource instead
Georgiy Podsvetov14
Tunneling occurs whenever the client is using the same method on a single URI for different actions.
# Request to add a discount offer POST /book/1234 HTTP/1.1 Host: www.example.org Content-Type: application/x-www-urlencoded !op=updateDiscount&discount=15
# Request to add the book for 30-day offers POST /book/1234 HTTP/1.1 Host: www.example.org Content-Type: application/x-www-urlencoded !op=30dayOffer&ebook_from=2009-10-10&ebook_to=2000-11-10
Georgiy Podsvetov
Tunneling
15
!
The visible parts of requests such as the request URI, the HTTP method used, headers, and media types do not unambiguously describe the operation.
Tunneling reduces protocol-level visibility
Georgiy Podsvetov
Tunneling
16
4xx status code for client inputs errors
!
5xx status code for server implementation errors
include a Date header with a value indicating the date-time at which the error occurred.
Georgiy Podsvetov
Error status codes
17
• A brief message describing the error condition
• A longer description with information on how to fix the error condition, if applicable
• An identifier for the error • A link to learn more about the error condition,
with tips on how to resolve it
Error description
Georgiy Podsvetov18
• Use domains and subdomains to logically group or partition resources for localization, distribution, or to enforce various monitoring or security policies.
• Use the forward-slash separator (/) in the path portion of the URI to indicate a hierarchical relationship between resources.
• Use the comma (,) and semicolon (;) to indicate nonhierarchical elements in the path portion of the URI.
• Use the hyphen (-) and underscore (_) characters to improve the readability of names in long path segments.
• Use the ampersand (&) to separate parameters in the query portion of the URI.
• Avoid including file extensions (such as .php, .aspx, and .jsp) in URIs.
http://www.example.org/co-ordinates;w=39.001409,z=-84.578201 http://www.example.org/axis;x=0,y=9
Georgiy Podsvetov
Constructing URI
19
Capital lettersRFC 3986 defines URIs as case sensitive except for the scheme and host parts. !The same: • http://www.exam ple.org/my-folder/doc.txt • HTTP://WWW.EXAMPLE.ORG/my-folder/doc.txt !Different • http://www.example.org/My-Folder/doc.txt
Georgiy Podsvetov20
Link header RFC 5988
Link: <{URI}>;rel="{relation}";type="{media type"};title="{title}"...
• self — link to the preferred URI of the resource • alternate — alternative version of the same resource • edit — link to to edit the resource • related — link to a related resource • previous and next — pagination in collection • first and last — first and last resources in collection • help — refers to a resource offering help • hub — refers to a hub that enables registration for
notification of updates to the context • payment — indicates a resource where payment is
accepted
Georgiy Podsvetov21
Always use URIs as the values of extended link relation types.
Provide HTML documentation at the URI
• Purpose of the link relation • The types of resources that use the link relation,
and the types of resources at the target of the link • Valid HTTP methods for the target URI • Expected media types on request and response
for the target URI
Georgiy Podsvetov
Relation types
22
Design each representation such that it contains links that help clients transition to all the next possible steps
Georgiy Podsvetov23
Include a Vary header whenever multiple representations are available for a resource.
comma-separated list of request headers the server uses when choosing a representation
Vary: *If the server uses information other than the headers in the request
Vary: Accept,Accept-Language
Georgiy Podsvetov
Multiple representations
24
Querying for information
• Filtering — selecting a subset of entities based on some filter criteria
• Sorting — influences how the server arranges the results in the response
• Projection — selecting certain fields in each entity to be included in the results
Georgiy Podsvetov25
Queries with long dataHow to make queries with long data? — Use POST1. Create a new resource whose state contains the query
criteria 2. Return response code 201 (Created) with a Location header
referring to a resource created 3. Implement a GET request for the new resource such that it
returns query results
Server can support the pagination of such query results via GET
Georgiy Podsvetov26
CachingCache-Control
• public (default) — marks responses as cacheable. • private — allows caches that are specific to one user to store the
response; shared caches ay not • no-cache and no-store — prevent any cache from storing or serving
a cached response • max-age — freshness lifetime in seconds as the value of this directive • s-maxage — this directive is similar to max-age but is meant only for
shared caches • must-revalidate — require caches to check the origin server before
serving stale representations • proxy-revalidate — similar to the must-revalidate directive except that
it applies only to shared caches
‘Expires’ header to support HTTP 1.0 include a Date header with a date-time of the time
at which the server returned the response
‘Pragma: no-cache’ for HTTP 1.0
Georgiy Podsvetov27
Caching# First requestGET /person/joe HTTP/1.1 Host: www.example.org
# First response HTTP/1.1 200 OK Date: Sun, 09 Aug 2009 00:44:14 GMT Last-Modified: Sun, 09 Aug 2009 00:40:14 GMT Cache-Control: max-age=3600,must-revalidate
# Second request after 10 minutes GET /person/joe HTTP/1.1 Host: www.example.org
# Second response - returned by cache HTTP/1.1 200 OK Date: Sun, 09 Aug 2009 00:54:14 GMT Last-Modified: Sun, 09 Aug 2009 00:40:14 GMT Cache-Control: max-age=3600,must-revalidate Age: 600
‘Age’ header indicates how long ago the cache retrieved the representation from the origin server
Georgiy Podsvetov28
Set expiration caching headers for responses of GET and HEAD requests for all successful response codes.
300 (Multiple Choices) 301 (Moved Permanently)
400 (Bad Request) 403 (Forbidden) 404 (Not Found) 405 (Method Not Allowed) 410 (Gone)
Georgiy Podsvetov
Caching headers
29
Concurrency controlPessimistic
Optimistic
Client gets a lock -> obtains the current state of the resource -> makes modifications -> releases the lock
Client gets a token -> attempts a write operation with the token -> succeeds if the token is still valid and fails otherwise
Georgiy Podsvetov30
HTTP, being a stateless application control, is designed for optimistic concurrency control
1. Server gives token to the client with each representation of the resource
2. Tokens change with every change to the resource 3. Client send token with each request to modify or
delete a resource — conditional request 4. Server validate token, if it is not actual — concurrency
failure — server aborts request
Georgiy Podsvetov
Concurrency control
31
Conditional requestsLast-Modified and ETag
Validating cached representations Concurrency control
If-Modified-Since If-Unmodified-Since
If-None-Match If-Match
Georgiy Podsvetov32
Conditional PUT requests
Georgiy Podsvetov33
Conditional DELETE request
Georgiy Podsvetov34
POST creation. Prevent duplicates.1. Generate one-time token on server 2. Client submits POST request with this token 3. If token already used -> 403 (Forbidden)
# RequestGET /entity/creation-token HTTP/1.1 Host: www.example.org
# ResponseHTTP/1.1 204 OK Cache-Control: no-cache Link: <example.com/entity?t=az345ed>;rel=«http://example.com/rel/create-entity»
Georgiy Podsvetov35
Create several resources
1. Use POST 2. Pass collection of the resources 3. Redirect to newly created collection -> 303 (See other) 4. Representation of this resource includes links to all the
newly created resources
Georgiy Podsvetov36
UPDATE or DELETE several resources
1. Generate URI that contains representation of all this resources
2. Submit PUT or DELETE request to this URI
Georgiy Podsvetov37
Representation annotationContent-Type describe the type of the representation
Content-Length specify the size in bytes of the body
Content-Language specify the localization
Content-MD5 checksums of the body
Content-Encoding when you encode the body of the representation using gzip, compress, or deflate encoding
Last-Modified last time the server modified the representation
For POST and PUT requests, even if you are using ‘Transfer-Encoding: chunked’, include the Content-Length header in requests from client applications. Some proxies reject POST and PUT requests that contain neither of these headers.
Georgiy Podsvetov38
!
Internet Assigned Numbers Authority media type registry (IANA, http://www.iana.org/assignments/media-types/)
Preferable to use standard media types
Media types
If you are designing a new media type, register the format and media type with IANA by following the procedure outlined in RFC 4288.
Georgiy Podsvetov39
multipart/form-data!
To encode name-value pairs of data mixed with parts containing data of arbitrary media types.
multipart/mixed!To bundle several parts of arbitrary media types.
multipart/alternative!Use this when sending alternative representations of the same resource using different media types.
multipart/related!
Use this when the parts are interrelated and you need to process the parts together. The first part is the root part and can refer to various other parts via a Content-ID header.
Avoid encoding binary data within textual formats using Base64 encoding
Georgiy Podsvetov
Media types
40
• Self link to the collection resource • Link to the next page • Link to the previous page • Indicator of the size of the collection
Include the following in collection representation
Georgiy Podsvetov
Representation data
41
Georgiy Podsvetov
Data formats• Use decimal, float, and double datatypes defined in the
W3C XML Schema for formatting numbers including currency.
• Use ISO 3166 codes for countries and dependent territories. • Use ISO 4217 alphabetic or numeric codes for denoting
currency. • Use RFC 3339 for dates, times, and date-time values used in
representations. • Use BCP 47 language tags for representing the language of
text. • Use time zone identifiers from the Olson Time Zone
Database to convey time zones.
42
The JSON media type application/json does not specify a charset parameter but uses UTF-8 as the default encoding. RFC 4627 specifies ways to determine the character encoding of JSON-formatted data.
Also avoid using the text/xml media type for XML-formatted representations. The default charset for text/xml is us-ascii, whereas application/xml uses UTF-8.
Georgiy Podsvetov
Media types
43
For resources that are expected to be consumed by end users, provide HTML representations. !
Avoid designing HTML representations for machine clients. !
To enable web crawlers and such software, use microformats or RDFa to annotate data within the markup. !http://microformats.org/wiki/hcard
Georgiy Podsvetov
Representation format
44
Accept headers
• Accept-Charset • Accept-Encoding • Accept-Language
Accept — Content-Types that are acceptable for the responseAccept: application/atom+xml;q=1.0, application/xml;q=0.6, */*;q=0.0 Accept-Language: fr;q=1.0, en;q=0.5 Accept-Encoding: gzip
q = 0.0 … 1.0 default: 1.0
If the request has no Accept-Encoding header, do not compress representations.
Georgiy Podsvetov45
When the server cannot serve a representation that meets the client’s preferences and if the client explicitly included a */*;q=0.0, !return status code 406 (Not Acceptable) with the body of the representation containing the list of representations.
# Request GET /user/001/followers HTTP/1.1 Accept: application/json,*/*;q=0.0 !# Response406 Not Acceptable Content-Type: application/json Link: <http://www.example.org/errors/mediatypes.html>;rel="help" { "message" : "This server does not support JSON. See help for alternatives." }
Georgiy Podsvetov46
Changes in API
•Servers goal — keep clients from breaking •Client goal — not fail when new unknown data or links appear in representations
Georgiy Podsvetov47
Preserve the hierarchical structure<user> <first-name>John</first-name> <last-name>Doe</last-name> <street>1 Some Street</street> <city>Some City</city> <user>
<user> <first-name>John</first-name> <last-name>Doe</last-name> <street>1 Some Street</street> <city>Some City</city> <state>WA</state> <user>
<user> <first-name>John</first-name> <last-name>Doe</last-name> <address> <street>1 Some Street</street> <city>Some City</city> <state>WA</state> </address> <user>
Origin
Good
Bad
Changes in API
Georgiy Podsvetov48
•When parsing bodies of representations, look for known data
•In the case of XML, look for known elements and attributes by name and not by position
•Implement the client to not fail when it finds unrecognized data
•If the client is capable of storing the complete representation locally, store everything
Changes in API
Georgiy Podsvetov49
•Treat new parameters as optional
Add new resources with new URIs when there is a change in the behavior of resources or a change in the information contained in representations
Avoid treating each version as a new representation with a new media type of the same resource
Georgiy Podsvetov50
What is the most flexible to design API?
— resource identification
Georgiy Podsvetov51
• Analyze your use cases to find domain nouns that can be operated using «create», «read», «update» or «delete» operations.
• Designate each noun as a resource.
• Check resource granularity.
Resource identification
- network efficiency!- size of representations!- client convenience
- cacheablility!- frequency of change!- mutability
Georgiy Podsvetov52
Composite resources
• client usage patterns!• performance!• latency requirements
Georgiy Podsvetov53
Documentation• All resources and methods supported for each resource • Media types and representation formats for resources in
requests and responses • Each link relation used, its business significance, HTTP
method to be used, and resource that the link identifies • All fixed URIs that are not supplied via links • Query parameters used for all fixed URIs • URI templates and token substitution rules • Authentication and security credentials for accessing
resources
Georgiy Podsvetov54
Documentation
Always provide consistent examples !
Be ready — users will copy examples and will try to run !
They will come to you and will lament that nothing works
Georgiy Podsvetov55
Questions?
Georgiy Podsvetov
Georgiy Podsvetov
https://www.linkedin.com/pub/georgiy-podsvetov/45/989/868
https://www.facebook.com/GeorgiyPodsvetov
56
#Request GET / HTTP/1.0 Host: 134.219.188.123 !#Response HTTP/1.0 418 I am a Teapot Connection: close Content-Type: text/html
RFC 7168