56

Principles of building effective REST API

Embed Size (px)

DESCRIPTION

Brief introduction into designing REST API. Set of recipes how to solve typical architectural problems. List of topics that you should learn, before start designing API.

Citation preview

Page 1: Principles of building effective REST API
Page 2: Principles of building effective REST API

Principles of building effective REST API

Georgiy Podsvetov

Page 3: Principles of building effective REST API

Georgiy Podsvetov

What is REST?Representational State Transfer

is an architecture style for designing networked applications

Page 4: Principles of building effective REST API

Roy Fielding(1965 — )

Architectural Styles and the Design of Network-based Software Architectures

(2000, University of California, Irvine)

Georgiy Podsvetov

Page 5: Principles of building effective REST API

• Resources • URI • Representations • Safe and Idempotent operations • Visibility • Linking • Caching

Georgiy Podsvetov5

Page 6: Principles of building effective REST API

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

Page 7: Principles of building effective REST API

Method Safe? Idempotent?

GET YES YES

HEAD YES YES

OPTIONS YES YES

PUT NO YES

DELETE NO YES

POST NO NO

Georgiy Podsvetov7

Page 8: Principles of building effective REST API

Use GET for safe and idempotent information retrieval

Georgiy Podsvetov8

Page 9: Principles of building effective REST API

• 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)

Page 10: Principles of building effective REST API

Use PUT to create new resources only when clients can decide URIs of resources.

Otherwise, use POST.

Georgiy Podsvetov10

Page 11: Principles of building effective REST API

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

Page 12: Principles of building effective REST API

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

Page 13: Principles of building effective REST API

• 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

Page 14: Principles of building effective REST API

X-HTTP-Method-Override

use POST and distinct resource instead

Georgiy Podsvetov14

Page 15: Principles of building effective REST API

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

Page 16: Principles of building effective REST API

!

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

Page 17: Principles of building effective REST API

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

Page 18: Principles of building effective REST API

• 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

Page 19: Principles of building effective REST API

• 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

Page 20: Principles of building effective REST API

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

Page 21: Principles of building effective REST API

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

Page 22: Principles of building effective REST API

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

Page 23: Principles of building effective REST API

Design each representation such that it contains links that help clients transition to all the next possible steps

Georgiy Podsvetov23

Page 24: Principles of building effective REST API

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

Page 25: Principles of building effective REST API

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

Page 26: Principles of building effective REST API

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

Page 27: Principles of building effective REST API

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

Page 28: Principles of building effective REST API

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

Page 29: Principles of building effective REST API

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

Page 30: Principles of building effective REST API

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

Page 31: Principles of building effective REST API

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

Page 32: Principles of building effective REST API

Conditional requestsLast-Modified and ETag

Validating cached representations Concurrency control

If-Modified-Since If-Unmodified-Since

If-None-Match If-Match

Georgiy Podsvetov32

Page 33: Principles of building effective REST API

Conditional PUT requests

Georgiy Podsvetov33

Page 34: Principles of building effective REST API

Conditional DELETE request

Georgiy Podsvetov34

Page 35: Principles of building effective REST API

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

Page 36: Principles of building effective REST API

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

Page 37: Principles of building effective REST API

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

Page 38: Principles of building effective REST API

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

Page 39: Principles of building effective REST API

!

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

Page 40: Principles of building effective REST API

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

Page 41: Principles of building effective REST API

• 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

Page 42: Principles of building effective REST API

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

Page 43: Principles of building effective REST API

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

Page 44: Principles of building effective REST API

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

Page 45: Principles of building effective REST API

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

Page 46: Principles of building effective REST API

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

Page 47: Principles of building effective REST API

Changes in API

•Servers goal — keep clients from breaking •Client goal — not fail when new unknown data or links appear in representations

Georgiy Podsvetov47

Page 48: Principles of building effective REST API

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

Page 49: Principles of building effective REST API

•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

Page 50: Principles of building effective REST API

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

Page 51: Principles of building effective REST API

What is the most flexible to design API?

— resource identification

Georgiy Podsvetov51

Page 52: Principles of building effective REST API

• 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

Page 53: Principles of building effective REST API

Composite resources

• client usage patterns!• performance!• latency requirements

Georgiy Podsvetov53

Page 54: Principles of building effective REST API

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

Page 55: Principles of building effective REST API

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

Page 56: Principles of building effective REST API

Questions?

Georgiy Podsvetov

Georgiy Podsvetov

[email protected]

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