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.
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.
To use dynamic variables, we need to know when to save and consume them.
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:
- type: save
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
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:
- type: load
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
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.
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
You can see that it is saving the variables that have the
save type defined.
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
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.
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
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.
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:
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!