This is the site's logo
This is the site's logo
Published on

Simple API Design with OpenAPI - 1

Authors

image1

Always the beginning of a new web project has its pain points along the way, one of those pain points is the business modeling, another would be the workflow between backend, frontend and the stakeholders. The starting point of a project is a hard stage that every team needs to overcome.

Today there are many tools that help us with those stressful situations and encourage us to designing it first and implementing it later, promesing that the designing time will be well spent and also will decrease dramatically our implementation time avoiding us a lot of back and forth between the stakeholders, the frontend team and the backend team and therefore headaches 😅.

Fortunately, the world of web development is teeming with powerful tools designed to tackle these challenges and transform the development process. These tools encourage teams to focus on designing APIs first before diving into implementation, promising that the time spent on design will be well invested, leading to smoother implementation and reduced back-and-forth with stakeholders and teams.

One of these game-changing tools is OpenAPI, a specification language that goes beyond defining HTTP APIs. It's an entire ecosystem of tools that make API design and development enjoyable and efficient. OpenAPI empowers developers to create APIs in a robust, fun, and interactive way, revolutionizing the way we build and consume APIs.

Let's dive into a hands-on exercise to experience the power of OpenAPI. In this exercise, we'll design a microservice to serve a resource called Users, demonstrating the capabilities and benefits of OpenAPI's ecosystem.

Users Model

Development Setup

  1. First of all, we'll need a code editor for this task. Luckily, the OpenAPI ecosystem offers a fantastic application called Swagger Editor, which assists us in designing APIs interactively. Accessing the Swagger Editor is easy, and there are multiple ways to get started:

    image4

    • Online Version: The simplest way to access the Swagger Editor is through its online version. Just open your web browser and navigate to the official Swagger Editor website. Once there, you can start designing your API right away without the need for any installations or downloads.
    • Local Installation: If you prefer working offline or want to have more control over the environment, you can install the Swagger Editor locally on your computer. It's available as a standalone application, and you can find installation instructions on the official Swagger Editor website.
    • Docker: For those familiar with Docker, you can use the Swagger Editor as a Docker container. This option provides easy setup and deployment, making it a convenient choice for developers who work extensively with Docker. Here's the Docker Image to pull from.
    • Integrated Development Environments (IDEs): Some modern code editors and IDEs come with plugins or extensions that integrate the Swagger Editor directly into the development environment. If you use VScode there's an extension for OpenAPI that integrates the Swagger Editor with vscode and you can design the OAS (Open API Specification) on VScode.
  2. It's fundamental you have at least some knowledge about YAML (Yet Another Markup Lenguage) format

Let's create a file called users.oas.yml. Always start with the minimum structure required to be a valid OpenAPI specification

users.oas.yml
openapi: 3.0.3
info:
    title: Users API
    description: Users service Spec
    version: 1.0.0
paths: {}

Understing OpenAPI specification

In this minimum structure we need to specify the openapi version we're using and specification metadata, title, description and version of our API and finally the paths item object at the upper most level.

Pathsitem Object describes the HTTP operations that can be performed on a path, operations match HTTP methods names like get, put, delete, post, to list the most common.

paths:
    /user/{id}:
        get:
        ...
        put:
        ...

Operations methods have some properties as well such as, summary, description, parameters and responses.

paths:
  /user/{id}:
    get:
      summary: Get a specific user
      description: Retrieves the user that matches the id from path paramter.
      parameters: ...
      responses: ...

We already know how to define a path with all its nested item objects, but there are some objects left yet, parameters, responses and requestBody.

Responses are the details of each response type, defined by its status code.

paths:
    /user/{id}:
        get:
            summary:
                ...
            parameters:
                ...
            responses:
                "200":
                    description: Ok
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    id:
                                        type: string
                                    name:
                                        type: string
                                    ...

At this stage it seems overwhelming and a lot of nested objects to remember but the good news is we could start our OAS spec with the responses and reuse them on each response and requestBody.

requestBodys look similar like responses and can be reuse as well as responses. The only thing to take in mind is requestBody is just for operations that require request Body object like post, put or patch.

One effective strategy is to begin by defining the responses section of our OAS specification. This involves outlining the possible responses our API endpoints may return, along with their respective status codes and data models. By doing this upfront, we establish a consistent pattern for handling responses across different endpoints.

paths:
    /user/{id}:
        post:
            summary:
                ...
            parameters:
                ...
            requestBody:
                content
                    application/json:
                        schema:
                            type: object
                            properties:
                                name:
                                    type: string
                                emailAdress:
                                    type: string
                                ...
            responses:
                ...

the last important type object is parameters, all parameter types are defined in the same way.

paths:
  /user/{id}:
    get:
      summary: ...
      parameters:
        - name: id
          in: path # This also can be `query`
          required: true
      responses: ...

If you got this far has been quite a lot but there is one last thing you need to know to start with our implementation, all responses, parameters and requestBodys can be defined first and be reused using a reference, in order to acomplish that we're going to use a item object called components at the upper most level of our OAS.

components:
  schemas:
    users:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        emailAdress:
          type: string
        roles:
          type: array
          items:
            type: string
  parameters:
    userParam:
      name: id
      in: path
      required: true
      schema:
        - $ref: '#/components/schemas/users'
# ------------------------------------------------------------------
paths:
  /users/{id}:
    get:
      summary: ...
      parameters:
        - $ref: '#/components/parameters/userParam'
      responses:
        '200':
          description: Ok
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/users'

Congratulation, OpenAPI is the secret weapon every development team needs. By embracing API-first design and leveraging the OpenAPI ecosystem, we overcome the initial challenges of web projects and create APIs that leave a lasting impact. It's time to unlock the full potential of API design and development with OpenAPI!

So, stay tuned for the next post where we embark on the exciting journey of implementing our Users service! I'm here to support you every step of the way, Happy coding, and let's make our vision a reality with OpenAPI! 🚀