OpenAPI Spec-First API Development
Tags: openapi, swagger, rest, postman
Published: 2023-01-24 15:08:14

---
title: OpenAPI Spec-First API Development
published: true
date: 2021-04-07 00:00:00 UTC
tags: openapi, swagger, rest, postman
canonical_url: https://www.rocky.dev/blog/openapi-spec-first-api-development
---

Recent APIs I've built follow both the [OpenAPI](https://swagger.io/specification/) (formerly known as Swagger) and [JSON:API](https://jsonapi.org/) specs. The former allows us to generate server-side data models and API clients in a number of languages using the [OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator). The latter allows us to leverage shared conventions on how a RESTful JSON API should function.

Through much trial and error, we've landed on a solid approach to automating much of our workflow when adding new API endpoints. The process begins as follows,

1. Update the OpenAPI schema
2. Use [Vert.x Web API Contract](https://vertx.io/docs/vertx-web-api-contract/java/) to import the schema to handle things like authentication and request validation
3. Use the OpenAPI generator to create server-side domain models and implement the endpoint

Since we offer [Postman](https://www.postman.com/) collections for our API, we chose to host our documentation using Postman as well. Ideally, we'd upload the new schema during our CI process, which would trigger the collection and documentation to update. Unfortunately, Postman wasn't built with this workflow in mind.

They allow you to upload an OpenAPI schema and generate a collection from it, but not through their API. This means we can't automate it. So as a workaround, we use the [`openapi-to-postman`](https://github.com/postmanlabs/openapi-to-postman) tool to convert our schema to a Postman collection and then use their API to update the collection we provide our customers.

A big problem with this tool, however, is that it generates new IDs for endpoints each time you run it. This makes diffs hard to follow and, more importantly, breaks documentation URLs. To workaround that, we use a [forked version](https://github.com/therockstorm/openapi-to-postman) that stores a sourcemap of the endpoints so the IDs remain stable.

From there, we call [Update Schema](https://www.postman.com/postman/workspace/postman-public-workspace/request/12959542-f9544c35-d4e1-4013-b2c2-88425c1cbcd2) with the updated OpenAPI schema. This doesn't update Postman collections created from the schema, however, so we then call [Update Collection](https://www.postman.com/postman/workspace/postman-public-workspace/request/12959542-bc8b292b-ffbb-4c67-a2a1-2fc416e2aef8), which, thankfully, triggers the documentation to update.

Now that our Postman collection, documentation, and code samples are updated, we use the OpenAPI generator to update our API clients and we're done.

This seems like a relatively normal use-case: update the OpenAPI spec and have all downstream artifacts ("Golden" Collection, Documentation, Forked Collections, API clients) automatically update to reflect those changes. If you'd like to see Postman handle this better, add your thoughts to [this pull request](https://github.com/postmanlabs/postman-app-support/issues/8940).