Continued from page 1.
How to use RAML to enhance your API spec core
In API-first, your API spec is the foundation that everything is being built atop of.
There are two widely used types of APIs: SOAP or single-object access protocol (common to legacy service-oriented infrastructures) and REST or Representational State Transfer. About half of enterprise APIs are on SOAP, but, according to Sarid, it’s seen as “yesterday’s technology,” pointing to the fact that it no longer attracts the same amount of excitement and innovation as REST does. While SOAP stays strong in heavier business-to-business APIs, “where there’s a lot of complexity that’s seen as necessary inside those ecosystems,” he says that largely REST dominates, particularly in public APIs, newer APIs in general and anything mobile.
RAML or RESTful API modeling language is a way of describing what Sarid refers to as practically RESTful APIs, a RAML spec that is a way of describing APIs that do not obey all constraints of REST, but most.
A grammar lesson in RESTful APIs
While the grammatical tradition of sentence diagramming is a dying art, Sarid makes a compelling case for the simplicity of RESTful APIs by breaking out his English composition book:
- The set of nouns or “things” you are going to be dealing with are modeled as resources, often described by URI paths--like /users, /groups, /items--and are the things you are dealing with in this particular domain.
- The verbs then come naturally as the things that you do on these nouns are characterized by the HTTP methods, the number of which is limited, but the semantic that you give those methods--What does it actually mean to do a post, a put, or a patch?--is something that you get to put into your model.
- The metadata (which I like to call the adjectives) is usually encoded in HTTP headers, although sometimes in the payload.
- The responses (could we call them predicate objects?) are the pre-established HTTP status codes, which Sarid recommends taking advantage of and using.
- The representations of the data (let’s call them pronouns?) are found inside the body of the request or, sometimes, in the query parameters
- And finally, there is hypermedia, which is technically required for REST but still uncommon, describing the hypermedia data itself and, moreover, the relationships between the data. Sarid admits though that “The reality is that actually today the vast majority of APIs don’t actually use hypermedia. The use effectively static content--JSON or XML. That’s why he calls them practically RESTful APIs.
What does a good RAML spec look like?
What Sarid calls the guiding light of the RAML workgroup is to never go back to “big, hairy and complex” design endeavours. “The whole goal of RAML was to keep the spirit of rest--that simplicity, that working at the HTTP level--and create a spec that has that same aspect.”
But how can you define simplicity? “If I needed to send an email to someone to describe what my API is, I would probably send them something like this. Here’s a collection of users, identified by /users. I’d do a get, I’d do a post. Within that collection of users [I can identify one] by its user ID. What can I do? I can get them, I can update them, I can delete them,” Sarid said. “My spec should be able to describe my API in the same way.”
“If I needed to send an email to someone to describe what my API is, I would probably send them something like this. Here’s a collection of users, identified by /users. I’d do a get, I’d do a post. Within that collection of users [I can identify one] by its user ID. What can I do? I can get them, I can update them, I can delete them,” Sarid said. “My spec should be able to describe my API in the same way.”
RAML is constructed with a lot of white space so that everything looks like an email outlining the steps to do something.
To simplify further, you remove the descriptions--because things like GETs always behave in the same manner--and can use that opened-up space to fill out other aspects of the API, like query parameters. Following the grammar lesson above, you take an iterative approach to fill out and explain the API within its code.
With the goal of repeating yourself for /users, /groups, /permissions and the like, RAML allows you also to refactor your APIs into reusable pieces that define behavior patterns. This is enabled through resource types--the kind of resource this is--and schemas--which provide the resource types with simple perimeters.
“Nothing is built into RAML. It’s up to you to find the library that has it.” But it’s flexible enough that if you don’t want to manage schemas, you can do things like submit name-value pairs that outline the requirements for your chosen media type. “If something is required in the input, you can always submit it. If something is required on the output, you can always expect to get it.”
In an effort to streamline your RAML definition, you can even externalize, create YAML anchors and point to added patterns. You can then publish libraries of these resource types and schemas that can be reused over and over again, maintaining consistency both within the API and across APIs.
The RAML spec also comes with built-in examples.
The idea of this narrative style is to communicate in a machine-readable way that provides a simple developer experience. Delightful, API-first design has DX at the forefront.
Sarid gave the example of how to lay out an API for Amazon delivery drones. Common API design practice would be to offer a full API on how to control the drones, but that’s not how a drone delivery would want to start. A delivery company’s priority is how to schedule the deliveries, which becomes the core of the RAML description. Then, you can create another API for drones that notifies the consumer of when she will receive her drone-delivery.
“It’s more about starting from the end-user experience and working backwards.”
Sarid said that the primary motivation he and his cofounders at the RAML Workgroup felt for developing RAML is that “This is really about developing APIs with the delight of the consumer in mind.”
How do you put make DX a priority in your API design? Tell us below!