REST API Design: Put the “Type” in “Content-Type”

Guest Author, November 18th, 2011

This guest post comes from Mark Massé, Senior Director of Engineering at ESPN. Mark has fourteen years of engineering, management, and architecture experience with The Walt Disney Company and received a “Disney Inventor Award” in 2008.

Greetings Programs! Well-designed REST APIs can be leveraged to create balanced client-server web applications; where the client’s responsibilities extend far beyond simply rendering a server-generated HTML document. Web sites and applications have been slowly shifting to this architecture since Internet Explorer 5’s inclusion of the core AJAX mechanics, DOM scripting and XHR. More recently, the architectural shift has been accelerated by significant advances in standards (e.g. HTML5) and performance (e.g. device CPUs and JavaScript).

This architecture is attractive to organizations for a number of reasons, such as:

  • Better experiences – Rich client applications create stickier sessions.
  • Faster time to market – The reusable REST API tier can be leveraged to create a variety of client applications, since it exposes “raw” data and functions to the Web without a screen or presentation-specific bias.
  • Cheaper to operate – Requires fewer servers, since modern clients can handle a larger share of the application’s processing and storage needs.

In order to support the increasing complexity of web applications being built with this architecture, the design and development practices applied to REST APIs must continue to mature.

REST and Media Types

One area of REST API design that warrants our attention is the use of “Media Types”, which are also known as either MIME Types or Content Types. Media types have the following syntax:

type "/" subtype *( ";" parameter )

REST APIs typically work with media types that fall under the “application” type. Note that parameters may follow the type/subtype in the form of attribute=value pairs that are separated by a leading semi-colon (;) character. HTTP/1.1 uses media types in the values of the Accept and Content-Type headers. As shown in the example below, client applications can convey their preference for a response body’s media type using HTTP/1.1’s Accept request header.

Accept: application/json,application/xml;q=0.9,text/html;q=0.8,*/*;q=0.7

In the Content-Type header of an HTTP/1.1 request or response, a media type reference indicates the “type” associated with the message body’s byte sequence. The example below demonstrate a Content-Type header value that references a media type with a “charset” parameter:

Content-type: text/html; charset=ISO-8859-4

REST APIs commonly use either the “application/json” or the “application/xml” media type in the Content-Type header of an HTTP/1.1 request or response. This anti-pattern is a form of tunneling, that we might call “type tunneling” because it masks the content’s actual “type” and reveals only its format. While it is correct that the body is formatted using languages such as JSON or XML, its content usually has semantics that require special processing beyond simply parsing the language’s syntax. Clients will expect a specific set of “fields” and hypermedia “links” to be present in a response message body’s formatted content.

Web Resource Model

A “Web Resource Model” begins with the hierarchical organization of data and functions that results from the design of a REST API’s URI paths. While its true that REST requires URIs be treated as opaque, the design of URIs matters a lot to folks that enjoy logical data models. Web resource schemas can add another dimension to the resource model by providing data structure type definitions to describe the representational forms that are traded back and forth between client and server.

As an example, consider a REST API URI such as http://api.soccer.restapi.org/players/2113 that responds to GET requests with a representation of a Player resource that is formatted using JSON. If the Content-Type header field value declares that the response’s media type is application/json, it has accurately conveyed the content’s syntax but has disregarded the schema of the Player representation. This response’s Content-Type header simply tells a client that it should expect some JSON-formatted text. Instead, it should communicate that the body contains a representation of a Player document that is formatted with JSON.

Most modern REST APIs communicate thier schema, via human-readable documentation hosted on a developer facing portal or wiki. This approach leads to a more static type system as the REST API owners are encouraging client developers to hard-code (and easily typo) the details of their API’s types. Once hard-coded by clients, the REST API must employ and maintain a versioning system in order to significantly evolve the schemas. Machine-readable schema defintions are preferred since they can be loaded dynamically at client development-time and runtime to up the level of robustness, introspection, and developer productivity.

Some modern REST APIs use frameworks like XML Schema Definition (XSD) and JSONSchema to communicate their schemas in a machine-readable format. These solutions have two design concerns that make them unfavorable. First, they require content (the application’s data) in an HTTP/1.1 message’s body to include references to the type definition, instead of conveying this type link where it belongs, in the Content-Type header. Second, formats are fashionable – they are cosmetic and they go in and out of style. Formats should be pluggable. Swapping one format in for another should not require an overhaul of your web resource type system. The schema of our web resources should be de-coupled from the format du jour. Schemas are constant reflections of our data structures. Formats offer a variety of serialization flavors.

WRML

To support and separate these design concerns, the “application/wrml” media type can be used to communicate both the “Format” and “Schema” of the data exchanged between a REST API and its clients.

application/wrml; schema=URI; format=URI

This media type may appear excessive when compared to simpler ones like application/json. However, this is a worthwhile trade-off since this media type communicates, directly to clients, distinct and complementary bits of information regarding the content of a message. The Web Resource Modeling Language (WRML, www.wrml.org) provides this “pluggable” media type to give rich web applications direct access to structural information and format serialization code. The media type’s self-descriptive and pluggable design reduces the need for information to be communicated out-of-band and then hard-coded by client developers.

The example below shows WRML’s media type used to describe a Player form that is formatted using JSON.

application/wrml; schema="http://api.schemas.wrml.org/soccer/Player"; format="http://api.formats.wrml.org/application/json"

The application/wrml media type’s required schema parameter’s value identifies a separate document that details the Player resource type’s form, which is independent of the media type’s format parameter’s value. The media type’s required format parameter’s value identifies a document resource that describes the JSON format itself.

WRML is an active open source project. For more information and to track its progress, see wrml.org and the “REST API Design Rulebook“, O’Reilly Media, Inc., October 2011.

Both comments and pings are currently closed.

5 Responses to “REST API Design: Put the “Type” in “Content-Type””

November 22nd, 2011
at 11:44 am
Comment by: Mark Masse

Thanks for reading. I wanted to add a note that WRML is an active open source project. You can learn more about it and track its progress here: http://www.wrml.org/project

-Mark

November 25th, 2011
at 7:16 am
Comment by: Distributed Weekly 130 — Scott Banwart's Blog

[...] REST API Design: Put the “Type” in “Content-Type” * [...]

July 11th, 2012
at 7:15 pm
Comment by: Jon Moore

In “REST APIs Must Be Hypertext Driven” (http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven), Roy Fielding writes:

“A REST API should never have “typed” resources that are significant to the client.”

I’m wondering how this jives with your Player type example.

August 19th, 2012
at 10:04 pm
Comment by: BitterCoder – Final Thoughts

[...] to custom media types would be a good move in this case – programmable web had a good post on this a while back – but is likely not something we would do until we feel the API is [...]

September 10th, 2012
at 9:46 pm
Comment by: Web API Implementation – Final Thoughts | Catch Blogs

[...] to custom media types would be a good move in this case – programmable web had a good post on this a while back – but is likely not something we would do until we feel the API is [...]

Follow the PW team on Twitter

ProgrammableWeb
APIs, mashups and code. Because the world's your programmable oyster.

John Musser
Founder, ProgrammableWeb

Adam DuVander
Executive Editor, ProgrammableWeb. Author, Map Scripting 101. Lover, APIs.