RESTful Service Best Practices - GitHub

Transcription

RESTful Service Best PracticesRESTful Service Best PracticesRecommendations for Creating Web ServicesTodd FredrichPearson ww.RestApiTutorial.comPage 1 of 40

RESTful Service Best Practices08/02/13www.RestApiTutorial.comPage 2 of 40

RESTful Service Best PracticesTable of ContentsDocument History. 5Who Should Read This Document.5Introduction. 6What is REST?.6Uniform Interface. 7Resource-Based. 7Manipulation of Resources Through Representations.7Self-descriptive Messages. 7Hypermedia as the Engine of Application State (HATEOAS). 7Stateless. 7Cacheable. 8Client–server. 8Layered system.8Code on demand (optional). 8REST Quick Tips. 9Use HTTP Verbs to Mean Something. 9Sensible Resource Names. 9XML and JSON. 9Create Fine-Grained Resources.10Consider Connectedness.10Definitions.10Idempotence. 10Safety. 11HTTP Verbs. 11GET. 11PUT. 12POST. 12PUT vs POST for Creation.13DELETE.13Resource Naming. 14Resource URI Examples. 15Resource Naming Anti-Patterns. 16Pluralization.16Returning Representations. 17Resource Discoverability Through Links (HATEOAS cont'd). 18Minimal Linking Recommendations. 19Link Format. 19Wrapped Responses.21Handling Cross-Domain Issues. 22Supporting CORS. 22Supporting JSONP.22Querying, Filtering and Pagination. 23Limiting Results. 2408/02/13www.RestApiTutorial.comPage 3 of 40

RESTful Service Best PracticesLimiting via the Range Header.25Limiting via Query-String Parameters.25Range-Based Responses. 25Pagination.26Filtering and Sorting Results.27Filtering. 27Sorting. 28Service Versioning. 28Support Versioning via Content Negotiation.29What version is returned when no version is specified?.31Unsupported Versions Requested. 31When Should I Create a New Version?. 32Changes that will break contracts. 32Changes considered non-breaking.33At What Level Should Versioning Occur?. 33Use Content-Location to Enhance Responses.33Links with Content-Type.33Finding Out What Versions are Supported. 33How many versions should I support at once?. 33Deprecated. 33How do I inform clients about deprecated resources?.34Date/Time Handling.34Date/Time Serialization In Body Content. 34Date/Time Serialization In HTTP Headers.35Securing Services. 35Authentication. 35Transport Security. 36Authorization.36Application Security.36Caching and Scalability. 37The ETag Header. 37HTTP Status Codes (Top 10). 39Additional Resources. omPage 4 of 40

RESTful Service Best PracticesDocument HistoryDateVersionDescriptionFeb 10, 2012DraftInitial draft version.Apr 24, 2012v1.0Initial public (non-draft) version.May 29, 2012v1.1Minor updates to correct misspellings and clarify wording afterfeedback from API Best Practices Task force.Aug 2, 2013v1.2Updated versioning section. Additional minor corrections ofmisspellings, wording, etc.Who Should Read This DocumentThis best-practices document is intended for developers who are interested in creating RESTful Webservices that provide high reliability and consistency across multiple service suites. By following theseguidelines, services are well positioned for rapid, widespread, public adoption by both internal andexternal clients.The guidelines in this document are also appropriate for support engineers where they desire to servicesdeveloped using these best practices. While their concerns may be focused on caching practices, proxyrules, monitoring, security and such, this document may be useful as an overarching servicedocumentation guide of sorts.Additionally, management personnel may benefit from these guidelines by endeavoring to understandthe effort required to create services that are publicly consumable and offer high levels of consistencyacross their service suites.08/02/13www.RestApiTutorial.comPage 5 of 40

RESTful Service Best PracticesIntroductionThere are numerous resources on best practices for creating RESTful web services (see the Resourcessection at the end of this document). Many of the available resources are conflicting, depending onwhen they were written. Plus, reading and comprehending several books on the subject in order toimplement services “tomorrow” is not doable. In order to facilitate the quick uptake and understandingof RESTful concepts, without requiring the reading of at least three to five books on the subject, thisguide is meant to speed up the process—condensing REST best practices and conventions into just thehigh points with not a lot of discussion.REST is more a collection of principles than it is a set of standards. Other than its over-arching sixconstraints nothing is dictated. There are "best practices" and de-facto standards but those areconstantly evolving—with religious battles waging continuously.Designed to be brief, this document provides recommendations and some cookbook-style discussion onmany of the common questions around REST and provides some short background information to offersupport for effective creation of real-world, production-ready, consistent RESTful services. Thisdocument aggregates information available in other sources, adapting it with experience gained throughhard knocks.There is still considerable debate as to whether REST is better than SOAP (and vice versa), and perhapsthere are still reasons to create SOAP services. While touching on SOAP, this document won't spend alot of time discussing the relative merits. Instead, because technology and the industry marches on, wewill proceed with the assumption that leveraging REST is the current best practice for Web servicecreation.The first section offers an overview of what REST is, its constraints, and what makes it unique. Thesecond section supplies some quick tips as little reminders of REST service concepts. Later sections gomore in depth to provide the Web service creator more support and discussion around the nitty-grittydetails of creating high-quality REST services capable of being publicly exposed in a productionenvironment.What is REST?The REST architectural style describes six constraints. These constraints, applied to the architecture,were originally communicated by Roy Fielding in his doctoral dissertation (seehttp://www.ics.uci.edu/ fielding/pubs/dissertation/rest arch style.htm) and defines the basis ofRESTful-style.The six constraints are: Uniform InterfaceStatelessCacheableClient-ServerLayered SystemCode on Demand08/02/13www.RestApiTutorial.comPage 6 of 40

RESTful Service Best PracticesA more detailed discussion of the constraints follows:Uniform InterfaceThe uniform interface constraint defines the interface between clients and servers. It simplifies anddecouples the architecture, which enables each part to evolve independently. The four guidingprinciples of the uniform interface are:Resource-BasedIndividual resources are identified in requests using URIs as resource identifiers. The resourcesthemselves are conceptually separate from the representations that are returned to the client. Forexample, the server does not send its database, but rather, some HTML, XML or JSON that representssome database records expressed, for instance, in Finnish and encoded in UTF-8, depending on thedetails of the request and the server implementation.Manipulation of Resources Through RepresentationsWhen a client holds a representation of a resource, including any metadata attached, it has enoughinformation to modify or delete the resource on the server, provided it has permission to do so.Self-descriptive MessagesEach message includes enough information to describe how to process the message. For example,which parser to invoke may be specified by an Internet media type (previously known as a MIMEtype). Responses also explicitly indicate their cache-ability.Hypermedia as the Engine of Application State (HATEOAS)Clients deliver state via body contents, query-string parameters, request headers and the requested URI(the resource name). Services deliver state to clients via body content, response codes, and responseheaders. This is technically referred-to as hypermedia (or hyperlinks within hypertext).Aside from the description above, HATEOS also means that, where necessary, links are contained inthe returned body (or headers) to supply the URI for retrieval of the object itself or related objects.We'll talk about this in more detail later.The uniform interface that any REST services must provide is fundamental to its design.StatelessAs REST is an acronym for REpresentational State Transfer, statelessness is key. Essentially, whatthis means is that the necessary state to handle the request is contained within the request itself,whether as part of the URI, query-string parameters, body, or headers. The URI uniquely identifies theresource and the body contains the state (or state change) of that resource. Then after the server doesit's processing, the appropriate state, or the piece(s) of state that matter, are communicated back to theclient via headers, status and response body.08/02/13www.RestApiTutorial.comPage 7 of 40

RESTful Service Best PracticesMost of us who have been in the industry for a while are accustomed to programming within acontainer which provides us with the concept of “session” which maintains state across multiple HTTPrequests. In REST, the client must include all information for the server to fulfill the request, resendingstate as necessary if that state must span multiple requests. Statelessness enables greater scalabilitysince the server does not have to maintain, update or communicate that session state. Additionally, loadbalancers don't have to worry about session affinity for stateless systems.So what's the difference between state and a resource? State, or application state, is that which theserver cares about to fulfill a request—data necessary for the current session or request. A resource, orresource state, is the data that defines the resource representation—the data stored in the database, forinstance. Consider application state to be data that could vary by client, and per request. Resourcestate, on the other hand, is constant across every client who requests it.Ever had back-button issues with a web application where it went AWOL at a certain point because itexpected you to do things in a certain order? That's because it violated the statelessness principle.There are cases that don't honor the statelessness principle, such as three-legged OAuth, API call ratelimiting, etc. However, make every effort to ensure that application state doesn't span multiple requestsof your service(s).CacheableAs on the World Wide Web, clients can cache responses. Responses must therefore, implicitly orexplicitly, define themselves as cacheable, or not, to prevent clients reusing stale or inappropriate datain response to further requests. Well-managed caching partially or completely eliminates some client–server interactions, further improving scalability and performance.Client–serverThe uniform interface separates clients from servers. This separation of concerns means that, forexample, clients are not concerned with data storage, which remains internal to each server, so that theportability of client code is improved. Servers are not concerned with the user interface or user state, sothat servers can be simpler and more scalable. Servers and clients may also be replaced and developedindependently, as long as the interface is not altered.Layered systemA client cannot ordinarily tell whether it is connected directly to the end server, or to an intermediaryalong the way. Intermediary servers may improve system scalability by enabling load-balancing and byproviding shared caches. Layers may also enforce security policies.Code on demand (optional)Servers are able to temporarily extend or customize the functionality of a client by transferring logic toit that it can execute. Examples of this may include compiled components such as Java applets andclient-side scripts such as JavaScript.Complying with these constraints, and thus conforming to the REST architectural style, will enable any08/02/13www.RestApiTutorial.comPage 8 of 40

RESTful Service Best Practiceskind of distributed hypermedia system to have desirable emergent properties, such as performance,scalability, simplicity, modifiability, visibility, portability and reliability.NOTE: The only optional constraint of REST architecture is code on demand. If a service violates anyother constraint, it cannot strictly be referred to as RESTful.REST Quick TipsWhether it's technically RESTful or not (according to the six constraints mentioned above), here are afew recommended REST-like concepts that will result in better, more usable services:Use HTTP Verbs to Mean SomethingAny API consumer is capable of sending GET, POST, PUT, and DELETE verbs, and they greatlyenhance the clarity of what a given request does. Also, GET requests must not change any underlyingresource data. Measurements and tracking may still occur, which updates data, but not resource dataidentified by the URI.Sensible Resource NamesHaving sensible resource names or paths (e.g., /posts/23 instead of /api?type posts&id 23) improvesthe clarity of what a given request does. Using URL query-string parameters is fantastic for filtering,but not for resource names.Appropriate resource names provide context for a service request, increasing understandability of theservice API. Resources are viewed hierarchically via their URI names, offering consumers a friendly,easily-understood hierarchy of resources to leverage in their applications.Resource names should be nouns—avoid verbs as resource names. It makes things more clear. Use theHTTP methods to specify the verb portion of the request.XML and JSONFavor JSON support as the default, but unless the costs of offering both JSON and XML are staggering,offer them both. Ideally, let consumers switch between them by just changing an extension from .xmlto .json. In addition, for supporting AJAX-style user interfaces, a wrapped response is very helpful.Provide a wrapped response, either by default or for separate extensions, such as .wjson and .wxml toindicate the client is requesting a wrapped JSON or XML response (see Wrapped Responses below).JSON in regards to a "standard" has very few requirements. And those requirements are onlysyntactical in nature, not about content format or layout. In other words, the JSON response to a RESTservice call is very much part of the contract—not described in a standard. More about the JSON dataformat can be found at http://www.json.org/.Regarding XML use in REST services, XML standards and conventions are really not in play otherthan to utilize syntactically correct tags and text. In particular, namespaces are not, nor should they beuse in a RESTful service context. XML that is returned is more JSON like—simple and easy to read,without the schema and namespace details present—just data and links. If it ends up being more08/02/13www.RestApiTutorial.comPage 9 of 40

RESTful Service Best Practicescomplex than this, see the first paragraph of this tip—the cost of XML will be staggering. In ourexperience few consumers uses the XML responses anyway. This is the last 'nod' before it gets phasedout entirely.Create Fine-Grained ResourcesWhen starting out, it's much easier to create APIs that mimic the underlying application domain ordatabase architecture of your system. Eventually, you'll want aggregate services—services that utilizemultiple underlying resources to reduce chattiness. But it's much easier to create larger resources laterfrom individual resources than it is to create fine-grained or individual resources from largeraggregates. Make it easy on yourself and start with small, easily defined resources, providing CRUDfunctionality on those. You can create those use-case-oriented, chattiness-reducing resources later.Consider ConnectednessOne of the principles of REST is connectedness—via hypermedia links. While services are still usefulwithout them, APIs become more self-descriptive when links are returned in the response. At the veryleast, a 'self' reference informs clients how the data was or can be retrieved. Additionally, utilize theLocation header to contain a link on resource creation via POST. For collections returned in a responsethat support pagination, 'first', 'last', 'next' and 'prev' links at a minimum are very helpful.DefinitionsIdempotenceContrary to how it sounds, make no mistake, this has no relation to certain areas of disfunction. FromWikipedia:In computer science, the term idempotent is used more comprehensively to describe anoperation that will produce the same results if executed once or multiple times. This mayhave a different meaning depending on the context in which it is applied. In the case ofmethods or subroutine calls with side effects, for instance, it means that the modified stateremains the same after the first call.From a RESTful service standpoint, for an operation (or service call) to be idempotent, clients canmake that same call repeatedly while producing the same result—operating much like a “setter”method in a programming language. In other words, making multiple identical requests has the sameeffect as making a single request. Note that while idempotent operations produce the same result on theserver (side effects), the response itself may not be the same (e.g. a resource's state may changebetween requests).The PUT and DELETE methods are defined to be idempotent. However, read the caveat on DELETEin the HTTP Verbs, DELETE section below.GET, HEAD, OPTIONS and TRACE methods are defined as idempotent also, since they are defined assafe. Read the section on safety below.08/02/13www.RestApiTutorial.comPage 10 of 40

RESTful Service Best PracticesSafetyFrom Wikipedia:Some methods (for example, HEAD, GET, OPTIONS and TRACE) are defined as safe,which means they are intended only for information retrieval and should not change thestate of the server. In other words, they should not have side effects, beyond relativelyharmless effects such as logging, caching, the serving of banner advertisements orincrementing a web counter. Making arbitrary GET requests without regard to the contextof the application's state should therefore be considered safe.In short, safety means that calling the method does not cause side effects. Consequently, clients canmake safe requests repeatedly without worry of side effects on the server. This means that servicesmust adhere to the safety definitions of GET, HEAD, OPTIONS and TRACE operations. Otherwise,besides being confusing to service consumers, it can cause problems for Web caching, search enginesand other automated agents—making unintended changes on the server.By definition, safe operations are idempotent, since they produce the same result on the server.Safe methods are implemented as read-only operations. However, safety does not mean that the servermust return the same response every time.HTTP VerbsThe HTTP verbs comprise a major portion of our “uniform interface” constraint and provide us theaction counterpart to the noun-based resource. The primary or most-commonly-used HTTP verbs (ormethods, as they are properly called) are POST, GET, PUT, and DELETE. These correspond to create,read, update, and delete (or CRUD) operations, respectively. There are a number of other verbs, too,but are utilized less frequently. Of those less-frequent methods, OPTIONS and HEAD are used moreoften than others.GETThe HTTP GET method is used to retrieve (or read) a representation of a resource. In the “happy” (ornon-error) path, GET returns a representation in XML or JSON and an HTTP response code of 200(OK). In an error case, it most often returns a 404 (NOT FOUND) or 400 (BAD REQUEST).Examples:GET http://www.example.com/customers/12345GET http://www.example.com/customers/12345/ordersGET http://www.example.com/buckets/sampleAccording to the design of the HTTP specification, GET (along with HEAD) requests are used only toread data and not change it. Therefore, when used this way, they are considered safe. That is, they canbe called without risk of data modification or corruption—calling it once has the same effect as callingit 10 times, or none at all. Additionally, GET (and HEAD) is idempotent, which means that makingmultiple identical requests ends up having the same result as a single request.08/02/13www.RestApiTutorial.comPage 11 of 40

RESTful Service Best PracticesDo not expose unsafe operations via GET—it should never modify any resources on the server.PUTPUT is most-often utilized for update capabilities, PUT-ing to a known resource URI with the requestrequest body containing the newly-updated representation of the original resource.However, PUT can also be used to create a resource in the case where the resource ID is chosen by theclient instead of by the server. In other wor

RESTful Service Best Practices Introduction There are numerous resources on best practices for creating RESTful web services (see the Resources section at the end of this document). Many of the available resources are conflicting, depending on when they were written. Plus, reading and comprehending several books on the subject in order to