RESTful APIs: Tutorial of OpenAPI Specification
As we are moving towards service-based applications and cutting-edge microservices, the necessity of having a standard interface definition for RESTful APIs more and more emerges.
What is the OpenAPI Specification?
The OpenAPI Specification (formerly known as Swagger) defines a standard, language-agnostic interface to RESTful APIs. The main advantage of using a standard definition is that all consumers of the service (including other developers, customers or even other microservices) can understand and interact with the service with a minimal amount of implementation logic.
There are other special benefits to using OpenAPI Specification (OAS) such as automatic code generation for clients and servers, interactive API documentation generations and testing tools. The OAS is currently at Version 3.0.2. The OAS is versioned using Semantic Versioning 2.0.0 (semver). if you want to learn more about semantic versioning here is a quick guide I wrote on that.
In this article, I try to cover the basics of creating an OpenAPI definition. In this tutorial, we will be building a blog posts API using OpenAPI Specification and we create documentation for our API. We also shortly go over the ways to generate code for client and server.
The examples in this article are in YAML but you can write your OAS also in JSON. I also assume that you are familiar with RESTful APIs basics. If you want to learn more about RESTful APIs, here is a good tutorial.
Blog Posts API
Let's say we want a blog post API which will be used for a simple blog website. I review quickly the requirements of our blog post API. We want an API with the below-mentioned functionalities. The expected endpoints and methods are also specified.
- Return all the posts: GET /posts
- Add a post: POST /posts
- Return a post with
postId
: GET /posts/{id} - Deletes a post with
postId
: DEL /posts/{id} - Completely update a post with
postId
: PUT /posts/{id} - Partially update a post with
postId
: PATCH /posts/{id} - Return the comments on a post with
postId
: GET /comments?postId={id}
Here is a post
JSON object. The posts
will be an array of this post
object.
{
"userId": 1,
"id": 1,
"title": "The First Post",
"body": "we are building a blog post API using OpenAPI Specification."
}
And here is a comment
JSON object. The comments
will be an array of this.
{
"postId": 1,
"id": 1,
"name": "A comment",
"email": "person@example.com",
"body": "like it!"
}
Alright with the requirements in mind, Let’s move forward to building an OpenAPI Specification for this bog post API.
OAS Basic Architecture
In this section, we go over the basics structure of Open API Specification and meanwhile we create our blog posts API.
Metadata Section
An OAS starts with a openapi
meta tag which declares the version of the OAS we are using.
openapi: 3.0.2
The Info Object
The info
Object defines metadata about the API. title
is the title of the application, description
is a short description of the application and you can use CommonMark syntax for more rich text presentation. You can add more metadata like contact
, version
and license
.
The Servers Object
The servers
section enables you to define API servers base URLs. You can define multiple servers such as production and sandbox and using OAS server templating system you can parameterize any part of the server URL.
The Paths Object
The paths
section defines relative individual endpoints (paths) in your API, and the HTTP methods (operations) supported by these endpoints. The path is appended to the URL from the servers
in order to construct the full URL.
In our example, let's say we want our API to have the following endpoints.
- GET /posts (Return all the posts)
- POST /posts (Creates a new post)
- GET /posts/{id} (Return the requested post by passing post_id in the URL)
- PUT/posts/{id} (A complete replacement of the post with post_id)
- PATCH /posts/{id} (Update the post with post_id partially)
- DELETE /posts/{id} (Deletes the post with post_id)
- GET /comments?postId={id} (Return the comments on a post with post_id)
OpenAPI 3.0 supports get
, post
, put
, patch
, delete
, head
, options
, and trace
. OpenAPI defines a unique operation as a combination of a path and an HTTP method.
Each operation can have some operation objects such as summary
, description
, tags
, operationId
, parameteres
, requestBody
, response
and more. In the following, I will explain some of the important operation objects. For detailed information refer to the operation object section in OpenAPI Specification.
Paths may have an optional short summary
and a longer description
for documentation purposes.
A useful operation object is tags
. A list of tags for API documentation control. Tags can be used for logical grouping of operations by resources or any other qualifier.
It is a good practice to add operationId
to each operation, this name will be used as the name of the function that handles this request in the generated code.
here is the code for the first endpoint in the above list.
Parameter Object
We can also have parameters in the endpoint path such as /posts/{id}
. OpenAPI 3.0 supports arrays and objects in operation parameters.
Operations can have parameters passed via URL path (/users/{userId}
), query string (/users?role=admin
), headers (X-CustomHeader: Value
) or cookies (Cookie: debug=0
). You can define the parameter data types, format, whether they are required or optional, and other details.
Request Body Object
Describes a single request body. If an operation sends a request body, use the requestBody
keyword to describe the body content and media type. In our example, the POST /posts
operation will have a blog post JSON object request body to be sent to the server. Here is the code for POST /posts
operation.
Responses Object
A container for the expected responses of an operation. The container maps a HTTP response code to the expected response.
For each operation, you can define possible status codes, such as 200 OK or 404 Not Found, and the response body schema
. Schemas can be defined inline or referenced via $ref
. You can also provide example responses for different content types.
Schema Object
The Schema Object allows the definition of input and output data types. These types can be objects, but also primitives and arrays. For our blog post example, we have a schema for post
JSON which is a schema for a post
. This can be defined as the following using component
and referenced in other schemas with the $ref
keyword. In the following schema
, posts
is an array of post
object.
You can refer to the OpenAPI documentation for more on data models and schemas.
components:
schemas:
Post:
type: object
properties:
id:
type: string
userId:
type: string
title:
type: string
body:
type: string
required:
- id
- userId
- title
- body
Posts:
type: array
items:
$ref: '#/components/schemas/Post'
Authentication
The securitySchemes
and security
keywords are used to describe the authentication methods used in your API.
Supported authentication methods are:
- HTTP authentication: Basic, Bearer, and so on.
- API key as a header or query parameter or in cookies
- OAuth 2
- OpenID Connect Discovery
Finally
Here is the complete OpenAPI specification for our blog post API.
Interactive API documentation
After defining our blog post API using OAS, we can generate documentation for our API. There are many ways of creating documentation for our OAS API.
SwaggerHub
Using swaggerHub you can create or import your OpenAPI Specifications. You can view and change your API online.
bump.sh
This is a good online service for generating documentation for your API. Just sign up and upload your OpenAPI YAML file to generate online documentation.
The following is generated for our blog posts example.
There are many documentation tools that will convert your OAS to an interactive HTML page.
For better documentation, you should provide examples
and description
for each element and schemas in your YAML file.
Code Generators
There are many tools for generating client-side and server-side code from an OAS. One of the most famous ones is openapi-generator. It supports code generation in many programming languages. You can release many SDKs for your API easily.
You can simply install it using npm
and start generating API clients and server stubs for your API.
npm install @openapitools/openapi-generator-cli -g
OAS Tools
There are many open-source tools for OpenAPI Specification. Take a look at the following website for all the tools you might need.
Full Specification
The full OpenAPI 3.0 Specification is available on GitHub:
I hope this article was useful to you and if you enjoyed it don't forget to share it.
Thanks for reading.