56

WebCamp: Developer Day: Принципы построения эффективного REST API - Георгий Подсветов

Embed Size (px)

DESCRIPTION

Принципы построения эффективного REST API Георгий Подсветов Доклад посвящен основополагающимся принципам концепции REST, на чем базируется идеология. Будет рассмотрен круг вопросов, которые необходимо решить при проектировании нового API и вопросов эффективности API, какой API будет удобен вашим пользователям

Citation preview

Page 1: WebCamp: Developer Day: Принципы построения эффективного REST API - Георгий Подсветов
Page 2: WebCamp: Developer Day: Принципы построения эффективного REST API - Георгий Подсветов

Principles of building effective REST API

Georgiy Podsvetov

Page 3: WebCamp: Developer Day: Принципы построения эффективного REST API - Георгий Подсветов

Georgiy Podsvetov

What is REST?Representational State Transfer

is an architecture style for designing networked applications

Page 4: WebCamp: Developer Day: Принципы построения эффективного REST API - Георгий Подсветов

Roy Fielding(1965 — )

Architectural Styles and the Design of Network-based Software Architectures

(2000, University of California, Irvine)

Georgiy Podsvetov

Page 5: WebCamp: Developer Day: Принципы построения эффективного REST API - Георгий Подсветов

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

Georgiy Podsvetov5

Page 6: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного REST API - Георгий Подсветов

Use GET for safe and idempotent information retrieval

Georgiy Podsvetov8

Page 9: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного REST API - Георгий Подсветов

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

Otherwise, use POST.

Georgiy Podsvetov10

Page 11: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного REST API - Георгий Подсветов

X-HTTP-Method-Override

use POST and distinct resource instead

Georgiy Podsvetov14

Page 15: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного REST API - Георгий Подсветов

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

Georgiy Podsvetov23

Page 24: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного REST API - Георгий Подсветов

Conditional PUT requests

Georgiy Podsvetov33

Page 34: WebCamp: Developer Day: Принципы построения эффективного REST API - Георгий Подсветов

Conditional DELETE request

Georgiy Podsvetov34

Page 35: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного REST API - Георгий Подсветов

What is the most flexible to design API?

— resource identification

Georgiy Podsvetov51

Page 52: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного REST API - Георгий Подсветов

Composite resources

• client usage patterns!• performance!• latency requirements

Georgiy Podsvetov53

Page 54: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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: WebCamp: Developer Day: Принципы построения эффективного 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