3min.

Fine tune an OpenAPI specification for mocking

More and more often, in the projects I work on, I need to mock APIs. When I’m lucky enough, the API provides an OpenAPI specification, but sometimes it can be heavy.

I almost never need to locally mock the whole API, only a few endpoints. Mocking the whole API, with Prism for example, could lead to issues like route priority, or performance. The question is: how can I filter the specification to only get the needed endpoints?

Furthermore, for those endpoints, I often need to set response examples (for integration testing). So the second question is : How can I inject response examples for specific endpoints?

All of this without manual editing of course.

Section intitulée endpoints-filteringEndpoints filtering

The first step is to reduce the size of the specification by filtering on needed endpoints only. To achieve this step, I use the openapi-format CLI tool.

With a short configuration file, I can create a copy of the OpenAPI PetStore specification containing the few endpoints I need (and their dependencies, such as components, tags, etc).

{
    "inverseOperationIds": [
        "getPetById",
        "placeOrder"
    ],
    "unusedComponents": [
        "schemas"
    ]
}

This file allows me to have a copy of the OpenAPI specification with only getPetById and placeOrder operations (I have to filter by operationId here, not by path, because openapi-format does not provide path filter). In addition, openapi-format will remove all unnecessary schema components, to make the output even lighter.

Let’s see the result of this first step (truncated, to avoid you to deep scroll):

{
  "openapi": "3.0.3",
  "info": {...},
  "paths": {
    "/pet/{petId}": {
      "get": {
        "operationId": "getPetById",
        "summary": "Find pet by ID",
        "description": "Returns a single pet",
        "parameters": [...],
        "responses": {...},
        "security": [...],
        "tags": ["pet"]
      }
    },
    "/store/order": {
      "post": {
        "operationId": "placeOrder",
        "summary": "Place an order for a pet",
        "description": "Place a new order in the store",
        "requestBody": {...},
        "responses": {...},
        "tags": ["store"]
      }
    }
  },
  "components": {
    "schemas": {
      "Order": {...},
      "Category": {...},
      "User": {...},
      "Tag": {...},
      "Pet": {...}
    },
    "requestBodies": {...},
    "securitySchemes": {...}
  },
  "tags": [...]
}

Section intitulée endpoints-enrichingEndpoints enriching

Now that I have a light version of the OpenAPI specification, let’s see how I can inject response examples!

After some lost hours spent on looking for the right tool for this step, I resigned myself and wrote mine. Sometimes the best open-source tool is the one you write 😅

This is how OpenAPI enricher was released!

This time, no configuration file needed, just the OpenAPI specification and a standalone JSON file containing response examples.

Here, a sample of the examples file I used to inject responses example for the getPetById operation:

{
  "paths": {
    "/pet/{petId}": {
      "get": {
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "doggie": {
                    "value": {
                      "id": 0,
                      "category": {
                        "id": 0,
                        "name": "string"
                      },
                      "name": "doggie",
                      "photoUrls": [
                        "string"
                      ],
                      "tags": [
                        {
                          "id": 0,
                          "name": "string"
                        }
                      ],
                      "status": "available"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

This file is a bit verbose, but it has the advantage of letting you inject any kind of response example (for any content-type, any status code, any HTTP method, …).

Now I can run openapi-enricher petstore-light.json --examplesFile petstore-examples.json --output final-petstore.json!

You can find an example of the final generated file in /test directory of the GitHub repository.

Section intitulée to-infinity-and-beyondTo infinity and beyond 🚀

In May 2022, I wrote a blog post entitled Efficiently Mock APIs Locally With Prism . Now, you can mix this blog post with the current one to generate the exact OpenAPI file you need to mock super efficiently any API!

Auteurs & autrices

Commentaires et discussions

Nos articles sur le même sujet

Ces clients ont profité de notre expertise