Programming

How to Create an Extension for Your Open API Specification

How to Create an Extension for Your Open API Specification

2021 is going to be the year of the API. We’re going to focus on converging on a standard, providing public APIs, and fast-forwarding our rate of innovation.

With our focus on API design with Open API Spec (OAS), we are going to run into scenarios where some automation is needed but not currently possible. Maybe this automation is custom to you and your company or maybe it’s a service you want to provide to developers everywhere. How do we go about implementing this automation? Through the use of an extension.

An extension is a simple way to add functionality to your OAS. You add some attributes to your file, implement a handler to read it and take an action, and reap the benefits of automation!

Instead of explaining what an extension is conceptually, today I am going to walk you through the creation of a brand new one. We are going to make an extension that enhances the Postman contract test generator we made a while back.

The test generator is great, but it relies on seeded data to work properly. This means that prior to execution, specific data has to be in the database so the tests can use it.

This causes a little bit of a problem because it increases the barrier to entry. It would be nice if there was a way to use the data generated from the tests in the tests themselves. Meaning when the generator does a POST to create a new entity, it can use the id of that entity in subsequent requests to GET or update with a PUT.

Let’s walk through end-to-end how to solve this problem by building an extension.

Photo by Kayla Farmer on Unsplash Photo by Kayla Farmer on Unsplash

Identify the Business Problem

In our example, we want to be able to use values created by the generated tests in subsequent generated tests. The business problem can be stated:

I want to use dynamic variables in my tests so I do not have to rely on seeded data.

Once you identify the business problem, you want to come up with a plan on how to best solve it. In our case, that involves using values created by the test generator in other requests.

To do this, we must be able to save response values and use them in other requests. With this in mind, we should be able to start the next step, defining the schema.

Image by Free-Photos from Pixabay Image by Free-Photos from Pixabay

Define the Extension Schema

To use dynamic variables, we need to know when to save and consume them.

Saving Dynamic Variables

To save a variable from a dynamic test, we need to know when and where to grab the value from a response. In our example, certain response codes on specific endpoints will produce the values we want.

There are two pieces of data we need to identify: name of the variable and where to find it. We also need to let our handler know that we want to save a variable.

With this in mind, the following schema supports our business need:

x-postman-variables:
  - type: save
    name: myVariable
    path: .id

With this schema, type will tell the handler that we want to save the variable. name is going to be the name of the variable in Postman. path is going to be the json path to the property in the response. You can see that we also made the extension an array in case we need to store multiple values from a single response.

We can now add the extension into our Open API spec under a specific response for a particular endpoint. We can reference the Gopher Holes Unlimited example API spec.

Example usage of the extension in the Gopher Holes Unlimited OAS Example usage of the extension in the Gopher Holes Unlimited OAS

Consuming Dynamic Variables

Now that we have our variables properly saved, it all comes down to using them in subsequent tests. With Open API Spec, we are able to define parameters used in our requests.

Since we want to use a variable in subsequent requests, we should be sure to enrich our OAS parameters with the extension. Every time we use the parameter, the test generator will pull the current Postman variable value and use it in the test.

Consuming the values are significantly easier than saving because we just need to know the variable name. Which leads us to a schema of:

x-postman-variables:
  - type: load
    name: myVariable

With this schema, type says we are loading the value, and name tells our handler which variable we want. With this, we have our extension definition defined!

Adding the example into our OAS will look like:

Example usage of consuming a variable in Gopher Holes Unlimited Example usage of consuming a variable in Gopher Holes Unlimited

Implement the Handler

With the schema of the extension defined, it’s now time to write the code that interprets the values. After all, an OAS document is just a definition. It doesn’t actually do anything.

Our extension is meant for usage exclusively with Postman, so our handler is going to be written from within the pre-request and test scripts in the Contract Test Generator collection.

Saving Extension Variables

The contract test generator already looks at allowed responses for each method on every endpoint. To implement the logic for our extension, we are going to be tying into that existing functionality.

When we are saving the responses for each method, the handler will look for the extension and save off the variables to a variables property on the test.

Save variable handler logic reading from our extension ‘Save variable’ handler logic reading from our extension

You can see that it is saving the variables that have the save type defined.

Persisting Response Values As Variables

Now it’s time for the actual work: taking the value from the response at the defined path and saving it to a Postman collection variable.

Again, it’s not a terribly difficult code snippet, it just uses what we saved off from step 1.

Persisting the response value into a Postman variable Persisting the response value into a Postman variable

Looking at what we’ve done, you can see that we are pathing to the property we want piece by piece. If we find it in the response, the value is saved to a collection variable. If no value is found, an assertion fails letting our tests know something went wrong.

Using Response Values

The last piece to our puzzle is to load the value we just saved whenever it is needed. A function exists already in the test generator that replaces parameters with a provided example from the OAS.

With our extension, we will modify that logic to use the value from the collection variable if necessary. If we don’t find a value in the collection variable, we fall back to the example.

Loading persisted variables into usable parameters Loading persisted variables into usable parameters

You can see here that the code is looking for our x-postman-variables extension for any parameters with the load save type. If there is one, it will use the collection variable. If not, it pulls from the example.

The code has also been updated for query parameters and headers.

Try it Out

That’s it! With the implementation of the handler, everything should just work.

Building an extension for your Open API Spec is as simple as that. Just three easy steps:

  1. Identify the problem
  2. Define the schema
  3. Implement the handler

Of course if you want your extension to be used by other people, you will need to document the usage (like what I’m doing here!).

I hope you are inspired to make an extension of your own. The possibilities are limitless. The handler doesn’t even have to be in Postman! It could be a script in your CI pipeline, a custom resource in your AWS CloudFormation script, or even a little on-demand desktop app.

Any way you go, you’re bound to make the lives easier of your entire development team.

So go out there and build some extensions! And if you haven’t already, try out the test generator, it’s better than ever!

Share on:
comments powered by Disqus

Join the Ready, Set, Cloud! Newsletter

Stay up to date with the latest posts, get the thought of the week, and keep in touch! Subscribe to our weekly newsletter for all these sweet deets.