Tag - api

Articles

RESTful Service Best Practices
RESTful Service Best Practices Recommendations for Creating Web Services Todd Fredrich Pearson eCollege @tfredrich www.RestApiTutorial.com Table of Contents Document History 5 Who Should Read This Document 5 Introduction 6 What is REST? 6 Uniform Interface 7 Resource-Based 7 Manipulation of Resources Through Representations 7 Self-descriptive Messages 7 Hypermedia as the Engine of Application State (HATEOAS) 7 Stateless 7 Cacheable 8 Client–server 8 Layered system 8 Code on demand (optional) 8 REST Quick Tips 9 Use HTTP Verbs to Mean Something 9 Sensible Resource Names 9 XML and JSON 9 Create Fine-Grained Resources 10 Consider Connectedness 10 Definitions 10 Idempotence 10 Safety 11 HTTP Verbs 11 GET 11 PUT 12 POST 12 PUT vs POST for Creation 13 DELETE 13 Resource Naming 14 Resource URI Examples 15 Resource Naming Anti-Patterns 16 Pluralization 16 Returning Representations 17 Resource Discoverability Through Links (HATEOAS cont’d) 18 Minimal Linking Recommendations 19 Link Format 19 Wrapped Responses 21 Handling Cross-Domain Issues 22 Supporting CORS 22 Supporting JSONP 22 Querying, Filtering and Pagination 23 Limiting Results 24 Limiting via the Range Header 25 Limiting via Query-String Parameters 25 Range-Based Responses 25 Pagination 26 Filtering and Sorting Results 27 Filtering 27 Sorting 28 Service Versioning 28 Support Versioning via Content Negotiation 29 What version is returned when no version is specified? 31 Unsupported Versions Requested 31 When Should I Create a New Version? 32 Changes that will break contracts 32 Changes considered non-breaking 33 At What Level Should Versioning Occur? 33 Use Content-Location to Enhance Responses 33 Links with Content-Type 33 Finding Out What Versions are Supported 33 How many versions should I support at once? 33 Deprecated 33 How do I inform clients about deprecated resources? 34 Date/Time Handling 34 Date/Time Serialization In Body Content 34 Date/Time Serialization In HTTP Headers 35 Securing Services 35 Authentication 35 Transport Security 36 Authorization 36 Application Security 36 Caching and Scalability 37 The ETag Header 37 HTTP Status Codes (Top 10) 39 Additional Resources 40 Books 40 Websites 40 Document History Date Version Description Feb 10, 2012 Draft Initial draft version. Apr 24, 2012 v1.0 Initial public (non-draft) version. May 29, 2012 v1.1 Minor updates to correct misspellings and clarify wording after feedback from API Best Practices Task force. Aug 2, 2013 v1.2 Updated versioning section. Additional minor corrections of misspellings, wording, etc. Who Should Read This Document This best-practices document is intended for developers who are interested in creating RESTful Web services that provide high reliability and consistency across multiple service suites. By following these guidelines, services are well positioned for rapid widespread public adoption by both internal and external clients. The guidelines in this document are also appropriate for engineers who support services developed using these best practices. While their concerns may be focused on caching practices, proxy rules, monitoring, security, and such, this document may be useful as an overarching service documentation guide of sorts. Additionally, management personnel may benefit from these guidelines by endeavoring to understand the effort required to create services that are publicly consumable that offer high levels of consistency across their service suites. 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 implement services “tomorrow” is not doable. In order to facilitate quick uptake and understanding of RESTful concepts, without requiring the reading of at least three to five books on the subject, this guide is meant to speed up the process—condensing REST best practices and conventions into just the high 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 six constraints, nothing is dictated. There are “best practices” and de-facto standards but those are constantly evolving—with religious battles waging continuously. Designed to be brief, this document provides recommendations and some cookbook-style discussion on many of the common questions around REST and provides some short background information to offer support for effective creation of real-world, production-ready, consistent RESTful services. This document aggregates information available in other sources, adapting it with experience gained through hard knocks. There is still considerable debate as to whether REST is better than SOAP (and vice versa), and perhaps there are still reasons to create SOAP services. While touching on SOAP, this document won’t spend a lot of time discussing relative merits. Instead, because technology and the industry marches on, we will proceed with the assumption that leveraging REST is the current best practice for Web service creation. The first section offers an overview of what REST is, its constraints, and what makes it unique. The second section supplies some quick tips as little reminders of REST service concepts. Later sections go more in depth to provide the Web service creator more support and discusses the nitty-gritty details of creating high-quality REST services capable of being publicly exposed in a production environment. What is REST? The REST architectural style describes six constraints which were originally communicated by Roy Fielding in his doctoral dissertation (see http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm). They define the basis of RESTful-style. The six constraints are: Uniform Interface Stateless Cacheable Client-Server Layered System Code on Demand A more detailed discussion of the constraints follows: Uniform Interface The uniform interface constraint defines the interface between clients and servers. It simplifies and decouples the application architecture, which enables each part to evolve independently. The four guiding principles of the uniform interface are: Resource-Based Individual resources are identified in requests using URIs as resource identifiers. The resources themselves are conceptually separate from the representations that are returned to the client. For example, the server does not send its database, but rather, some HTML, XML, or JSON that represents some database records expressed, for instance, in Finnish and encoded in UTF-8, depending on the details of the request and the server implementation. Manipulation of Resources Through Representations When
API Design Cheat Sheet
Build the API with consumers in mind–as a product in its own right. Not for a specific UI. Embrace flexibility / tunability of each endpoint (see #5, 6 & 7). Eat your own dogfood, even if you have to mockup an example UI. Use the Collection Metaphor. Two URLs (endpoints) per resource: The resource collection (e.g. /orders) Individual resource within the collection (e.g. /orders/{orderId}). Use plural forms (‘orders’ instead of ‘order’). Alternate resource names with IDs as URL nodes (e.g. /orders/{orderId}/items/{itemId}) Keep URLs as short as possible. Preferably, no more-than three nodes per URL. Use nouns as resource names (e.g. don’t use verbs in URLs). Make resource representations meaningful. “No Naked IDs!” No plain IDs embedded in responses. Use links and reference objects. Design resource representations. Don’t simply represent database tables. Merge representations. Don’t expose relationship tables as two IDs. Support filtering, sorting, and pagination on collections. Support link expansion of relationships. Allow clients to expand the data contained in the response by including additional representations instead of, or in addition to, links. Support field projections on resources. Allow clients to reduce the number of fields that come back in the response. Use the HTTP method names to mean something: POST – create and other non-idempotent operations. PUT – update. GET – read a resource or collection. DELETE – remove a resource or collection. Use HTTP status codes to be meaningful. 200 – Success. 201 – Created. Returned on successful creation of a new resource. Include a ‘Location’ header with a link to the newly-created resource. 400 – Bad request. Data issues such as invalid JSON, etc. 404 – Not found. Resource not found on GET. 409 – Conflict. Duplicate data or invalid data state would occur. Use ISO 8601 timepoint formats for dates in representations. Consider connectedness by utilizing a linking strategy. Some popular examples are: HAL Siren JSON-LD Collection+JSON Use OAuth2 to secure your API. Use a Bearer token for authentication. Require HTTPS / TLS / SSL to access your APIs. OAuth2 Bearer tokens demand it. Unencrypted communication over HTTP allows for simple eavesdroppping and impersonation. Use Content-Type negotiation to describe incoming request payloads. For example, let’s say you’re doing ratings, including a thumbs-up/thumbs-down and five-star rating. You have one route to create a rating: POST /ratings How do you distinguish the incoming data to the service so it can determine which rating type it is: thumbs-up or five star? The temptation is to create one route for each rating type: POST /ratings/five_star and POST /ratings/thumbs_up However, by using Content-Type negotiation we can use our same POST /ratings route for both types. By setting the Content-Type header on the request to something like Content-Type: application/vnd.company.rating.thumbsup or Content-Type: application/vnd.company.rating.fivestar the server can determine how to process the incoming rating data. Evolution over versioning. However, if versioning, use the Accept header instead of versioning in the URL. Versioning via the URL signifies a ‘platform’ version and the entire platform must be versioned at the same time to enable the linking strategy. Versioning via the Accept header is versioning the resource. Additions to a JSON response do not require versioning. However, additions to a JSON request body that are ‘required’ are troublesome–and may require versioning. Hypermedia linking and versioning is troublesome no matter what–minimize it. Note that a version in the URL, while discouraged, can be used as a ‘platform’ version. It should appear as the first node in the path and not version individual endpoints differently (e.g. api.example.com/v1/…). Consider Cache-ability. At a minimum, use the following response headers: ETag – An arbitrary string for the version of a representation. Make sure to include the media type in the hash value, because that makes a different representation. (ex: ETag: “686897696a7c876b7e”) Date – Date and time the response was returned (in RFC1123 format). (ex: Date: Sun, 06 Nov 1994 08:49:37 GMT) Cache-Control – The maximum number of seconds (max age) a response can be cached. However, if caching is not supported for the response, then no-cache is the value. (ex: Cache-Control: 360 or Cache-Control: no-cache) Expires – If max age is given, contains the timestamp (in RFC1123 format) for when the response expires, which is the value of Date (e.g. now) plus max age. If caching is not supported for the response, this header is not present. (ex: Expires: Sun, 06 Nov 1994 08:49:37 GMT) Pragma – When Cache-Control is ‘no-cache’ this header is also set to ‘no-cache’. Otherwise, it is not present. (ex: Pragma: no-cache) Last-Modified – The timestamp that the resource itself was modified last (in RFC1123 format). (ex: Last-Modified: Sun, 06 Nov 1994 08:49:37 GMT) Ensure that your GET, PUT, and DELETE operations are all idempotent. There should be no adverse side affects from operations.