How to Sync Your OpenAPI Schema in Stoplight With GitHub and Runscope
This is a post from our Featured Guest Series! Glen Semino shows how to combine Stoplight and GitHub APIs with Runscope to keep your OpenAPI Schema always versioned and up to date.
About a month ago, after I and part of the SYNQ team attended the APIDays SF conference, we reflected on what we had learned at the conference. One of the things we realized was that our API spec documentation needed quite a bit of improvement. And among the tools discussed in the conference was Stoplight, which helps one design, document, mock, and debug APIs.
We decided to give Stoplight a try to rewrite and edit our API spec. Once we started, I noticed that I was often manually syncing our Open API spec (OAS) file that Stoplight generates with our GitHub repo. I wanted a way to automate this process so that regardless of what gets edited/changed in Stoplight, Stoplight and GitHub are always in sync.
This is where Runscope came to save the day. Using the export function Stoplight offers, in addition to GitHub's API, I was able to automate syncing our Stoplight OAS spec file with our GitHub repo every minute using Runscope. In this tutorial, we're going to walk through this workflow step-by-step so that you can do it too!
The Setup
These are the things you will need to do to create the necessary API requests in Runscope to automate the syncing process:
- Generate a personal access token from GitHub for using the GitHub API.
- Obtain the export URL for your spec file from Stoplight.
- Commit your spec file from Stoplight into GitHub manually just once, so that it has a place in your GitHub repo.
- Get the path to the spec file in GitHub you want to commit to, along with the file name, to generate a URL like this: https://api.github.com/repos/SYNQ/spec/contents/oas.json (replace bold parts).
What we will be doing first is obtaining our spec file from Stoplight, then committing the updated spec file into GitHub (in the same place where we manually created one). The process is then automated by running it on a schedule in Runscope.
If you want to use a template as a starting point, scroll to the end of the blog post to download a JSON file you can import to your Runscope account that includes a template of all the requests you need to create.
Obtaining Your Spec File With Runscope
To start, we will be retrieving our spec file from Stoplight using a simple 'GET' request to our spec's file export URL.
The export URL from Stoplight will look something like this:
- https://api.stoplight.io/v1/versions/{version_id}/export/oas.json
We can obtain this by following the instructions provided in Spotlight docs, "Exporting to Swagger or RAML."
After we have the export URL, we need to create a 'GET' request in Runscope using the request editor. It will look like this:
For the ‘Assertions’ on our ‘GET’ request, we want to:
- Request a ‘Status Code’ that equals 200.
- Make sure that Text Body ‘is not empty.’
And, lastly, for the Variables section of our Runscope request, we want to:
- Store ‘Text Body’ in a variable, 'json_body,'
Let's save and run this request to make sure it works. Assuming all went well, we are now ready for the next request.
Getting a Commit From GitHub
When using Git to do a commit, we need to have the SHA (unique ID or hash) for the specific file we want to commit to. To get that, we will make another ‘GET’ request. This time it will be calling the GitHub API to get the SHA for the specific file we want to commit to.
The URL we will be making a GET request to in Runscope will look something like this:
- https://api.github.com/repos/SYNQ/spec/contents/oas.json
The URL above should point to the path and the name of the spec file we will be committing to.
After we have the URL to call the GitHub API, we will create a new request in Runscope. To call the GitHub API, we will need the personal GitHub access token that we created as part of the setup section. To authenticate with GitHub, we will need to add an ‘Authorization’ header and then provide our token. It should look like this:
Note: make sure your Authorization header includes a single space between "token" and the token key.
For the ‘Assertions’ on our ‘GET’ request, we want to assert that the:
- Request ‘Status Code’ equals 200.
- JSON Body ‘is not empty.’
Lastly, for the variables section of our Runscope request, we want to:
- Store the ‘JSON Body’ property ‘sha’ into a variable, 'current_sha.'
Save, run, and make sure everything works again. Now we are ready for the last step of committing to GitHub.
Committing Your Spec File to GitHub
The last request that we need is a PUT request to the GitHub API to commit our updated spec file from Stoplight.
We can use the same URL from the previous request we just created, for example:
- https://api.github.com/repos/SYNQ/spec/contents/oas.json
Using the same URL from your previous request, we can now create a new ‘PUT’ request and pass in our credentials, plus all the information needed to do the GitHub commit.
Using the request editor, add in our PUT request. After that, we will need to set headers and parameters as described below.
For the headers in our request, we will need the following:
- An ‘Authorization’ header to pass in our personal token
- A ‘Content-Type’ header set to ‘application/json.’
Note: Again, make sure your Authorization header includes a single space between "token" and the token key.
For the ‘Parameters’ section of our request, we will use all the variables saved in the previous two requests. The GitHub API requires a message, the SHA for the file we want to commit to, and the spec content itself. The JSON formatted parameters we will be sending will look something like this:
{
"message": "updated-runscope-{{timestamp}}",
"sha": "{{current_sha}}",
"content": "{{encode_base64({{json_body}})}}"
}
The variables in the above example represent the following:
- timestamp - is a built-in variable in Runscope that gives you an integer Unix timestamp.
- current_sha - is the SHA for the file we want to commit to, that was obtained in the GET request to the GitHub API.
- json_body - represents the text body we saved from the GET request to the Stoplight export URL.
Here is a what the ‘Parameters’ section in Runscope should look like:
The Parameters section of the Runscope reques,t including the code snippet in the previous code box.
For the ‘Assertions’ on our ‘PUT’ request, we will want to assert:
- That the request ‘Status Code’ equals 200.
- The JSON Body ‘is not empty.’
No,w one last time, save and run to make sure things work. In addition to that, let's check that there is now a new commit in GitHub.
Assuming it all went as intended, we now have a Stoplight GitHub synchronizer in Runscope!
The last thing to do is simply run the monitor you created on a schedule following Runscope’s instructions, found here.
Importing a Runscope Monitor Template
If you're already familiar with Runscope, the GitHub API, and Stoplight, or you're just looking to get a head start on this tutorial, we have created a JSON file that you can import into your Runscope account. That includes all the steps described in this tutorial, and all you need to do is change the variables for your GitHub access token, and the URLs for GitHub and Stoplight.
You can download the JSON template file by clicking here, and you can find instructions on how to import it here.
Wrapping it Up
Now we can repeat these steps for any other spec file you want to synchronize between Stoplight and GitHub. In the beginning, when I had thought about this problem or how I would create a system to allow me to do this, it was actually taking me a few days. Once I decided to give it a try with Runscope, I was pleasantly surprised with the results and I was able to complete the task within a day. Runscope has gone from being a tool we only used to monitor our APIs to a tool that we can also use to automate processes like the one we have described here.
If you have any questions about the process, feel free to reach out to me via Twitter @glensemino.