The document discusses API-driven development using the OpenAPI specification. It describes how taking an API-first and test-driven approach, where the API is designed before code and tested through integration tests of the OpenAPI spec, can lead to more productive development. This approach, called API-driven development, provides benefits like transparent changes, generated documentation and collections, and empowering individual developers.
Nordic APIs 2023 Platform Summit - API-Driven Development with OpenAPI Specification Testing
1. Nordic APIs 2023 Platform Summit
Brett Bush
API-Driven
Development with
OpenAPI Specification
Testing
2. Myself LogicGate
Brett Bush
LogicGate (Chicago, IL)
Senior Software Engineer
Platform & Developer Relations
APIs SDKs
Developer
Relations
OpenAPI
Specifications
API-First API Documentation GRC Platform SaaS API Integrations
Introduction
3. The Journey to API-First
75% Agreed that developers at API-first
companies are more productive
11% Ranked themselves as highly API-first
Postman State of the API Report 2023: API-first and other strategies
https://www.postman.com/state-of-api/api-first-strategies/#api-first-strategies
The Journey to API-First
4. The Journey to API-First
75% Agreed that developers at API-first
companies are more productive
11% Ranked themselves as highly API-first
Postman State of the API Report 2023: API-first and other strategies
https://www.postman.com/state-of-api/api-first-strategies/#api-first-strategies
The Journey to API-First
5. Code-First
API Codebase
with API Documentation
Libraries
➜ ➜
OpenAPI
Specification
API
Documentation
The code is developed before the API.
The Journey to API-First
6. API-First
API Codebase
with API Documentation
Libraries
OpenAPI
Specification
API
Documentation
The API is developed before the code.
The Journey to API-First
➜
➜
7. API-First
API Codebase
with API Documentation
Libraries
OpenAPI
Specification
API
Documentation
The API is developed before the code.
➜
The Journey to API-First
➜
8. API-Driven
API Codebase
with API Documentation
Libraries
OpenAPI
Specification
API
Documentation
=
The API is developed before the code, and alignment is guaranteed between them.
The Journey to API-First
➜
➜
9. Code-First
API Codebase
with API Documentation
Libraries
OpenAPI
Specification
API
Documentation
The code is developed before the API.
The Journey to API-First
➜ ➜
39. API-Driven Development 39
Static file
Available
Per-commit accuracy
Main OpenAPI Specification
Main OpenAPI
OpenAPI
Integration
Test
40. API-Driven Development 40
Get the main OpenAPI object
Get the generated OpenAPI object
Test OpenAPI object equality
Test formatting (bonus)
OpenAPI Integration Test
Main OpenAPI
OpenAPI
Integration
Test
01.
02.
03.
04.
41. API-Driven Development 41
Test-Driven Development
Main OpenAPI
OpenAPI
Integration
Test
API-First + Test-Driven = API-Driven
API-First
The API is developed before the code.
Test-Driven
The test is developed before the code.
42. GitHub Specification
Sharing the OpenAPI
Specification on GitHub
Transparent Changes
Breaking API changes in code
reviews aren’t hidden
API-Driven Development
Empowering a test-driven
approach to API design
Release Notes
Generated with open source
OpenAPI diff tooling
Postman Collection
Generated per-commit via git
hooks and open source tools
API Documentation
Generated with open source
tools like Slate & Widdershins
API-Driven Development
43. GitHub Specification
Sharing the OpenAPI
Specification on GitHub
Transparent Changes
Breaking API changes in code
reviews aren’t hidden
API-Driven Development
Empowering a test-driven
approach to API design
Release Notes
Generated with open source
OpenAPI diff tooling
Postman Collection
Generated per-commit via git
hooks and open source tools
API Documentation
Generated with open source
tools like Slate & Widdershins
API-Driven Development
44. API Documentation
Generated with open source
tools like Slate & Widdershins
Transparent Changes
Breaking API changes in code
reviews aren’t hidden
API-Driven Development
Empowering a test-driven
approach to API design
Release Notes
Generated with open source
OpenAPI diff tooling
Postman Collection
Generated per-commit via git
hooks and open source tools
GitHub Specification
Sharing the OpenAPI
Specification on GitHub
API-Driven Development
45. API Documentation
Generated with open source
tools like Slate & Widdershins
GitHub Specification
Sharing the OpenAPI
Specification on GitHub
Transparent Changes
Breaking API changes in code
reviews aren’t hidden
Release Notes
Generated with open source
OpenAPI diff tooling
Postman Collection
Generated per-commit via git
hooks and open source tools
API-Driven Development
Empowering a test-driven
approach to API design
API-Driven Development
46. API Documentation
Generated with open source
tools like Slate & Widdershins
GitHub Specification
Sharing the OpenAPI
Specification on GitHub
API-Driven Development
Empowering a test-driven
approach to API design
Release Notes
Generated with open source
OpenAPI diff tooling
Postman Collection
Generated per-commit via git
hooks and open source tools
Transparent Changes
Breaking API changes in code
reviews aren’t hidden
API-Driven Development
47. API Documentation
Generated with open source
tools like Slate & Widdershins
GitHub Specification
Sharing the OpenAPI
Specification on GitHub
Transparent Changes
Breaking API changes in code
reviews aren’t hidden
API-Driven Development
Empowering a test-driven
approach to API design
Postman Collection
Generated per-commit via git
hooks and open source tools
Release Notes
Generated with open source
OpenAPI diff tooling
API-Driven Development
48. API Documentation
Generated with open source
tools like Slate & Widdershins
GitHub Specification
Sharing the OpenAPI
Specification on GitHub
Transparent Changes
Breaking API changes in code
reviews aren’t hidden
API-Driven Development
Empowering a test-driven
approach to API design
Release Notes
Generated with open source
OpenAPI diff tooling
Postman Collection
Generated per-commit via git
hooks and open source tools
API-Driven Development
49. Scaling to development
Applying a test-driven approach on individual
development tickets.
Applying to internal APIs
Improving API developer experience both externally and
internally.
What’s next?
SDKs
Leveraging our OpenAPI Specification to generate client
SDKs for our APIs.
49
API-Driven Development
50. An OpenAPI Specification goes a long way,
a main one goes even further
API-First + Test-Driven = API-Driven
Takeaways
API-First is a journey, not a
destination
50
01.
02.
03.
API-Driven Development
Good morning everyone!
My name is Brett Bush, and today
I’m going to be sharing the story of how our team leveraged OpenAPI Specification testing
to adopt an API-Driven Development model
and as a result seamlessly scale our Developer Relations program.
Before we dive in, I’ll share a bit about myself and my company.
Again, I’m Brett Bush
I work at LogicGate which is based in Chicago Illinois
I’m a Senior Software Engineer, and over the last 2 years, I’ve been leading and building out LogicGate’s Developer Relations program.
My background has been APIs and SDK Development, which ultimately led me to Developer Relations!
And in leading our DevRel program, I’ve become involved with OpenAPI Specifications, API-First development, and API Documentation
As far as LogicGate,
We’re in the industry of GRC (Governance, Risk, and Compliance)
And we deliver a holistic, no-code, GRC software platform so organizations can proactively understand, manage and mitigate their ever-changing risk and compliance landscape.
We have a SaaS platform called the Risk Cloud, and as a SaaS platform we provide APIs for building out custom integrations.
Hence, the need for our Developer Relations program to begin our journey to an API-First inspired approach.
However, shifting to an API-First model can be an uphill climb.
According to Postman’s 2023 State of the API Report
75% of participants agree that developers at API-First companies are more productive, so there’s a large incentive to adopt an API-First approach.
However only 11% ranked themselves as highly API-first.
So, how do companies in the 75% that acknowledge the productivity benefits of an API-First model become highly API-First themselves?
Well, like many software development answers go, it depends!
Every company is at a different stage in their journey and is starting from a different place.
Which leads to our journey!
Our team’s API started out as Code-First, where the codebase of our API used API Documentation generation libraries to generate our OpenAPI Specification from the codebase, which in turn could be used to generate our API Documentation.
The code was developed before the API, with our OpenAPI Specification and documentation essentially being improvised off of the codebase.
However, like many organizations, we wanted to make a pivot to API-First.
Where the API is developed before the code!
For this, it meant putting the OpenAPI Specification as the central source of truth, informing the design of the codebase as well.
However, we soon realized that the codebase could change independently of the API documentation, causing a disconnect between the two.
In addition, by not leveraging the API Documentation libraries in our codebase to generate the OpenAPI Specification, we lost a fair amount of convenience that we had before.
What we desired wasn’t just a Code-First approach, or an API-First approach, but what we would call an API-Driven approach,
Where, similar to API-First, the API is developed before the code, however alignment is guaranteed between the API and the code as well.
So from our starting point of Code-First, how do we manage the trade-offs of transitioning our OpenAPI Specification from being improvised from our codebase, to becoming an aligned and central source of truth across our entire development process.
With our starting point being improvised, let’s envision this in another improvisational setting…
Improvised Jazz!
Let’s say we are in a jazz band, and here is our performance process
For our band
Our musicians are the source of our music
The performance of our music is the production
And the sheet music that is transcribed from the performance is the output
Along with any variations of the sheet music including other musicians performing the piece or exporting the sheet music to a digital setting
We’re happy with the existing qualities of our performance process
However, our goal is that we want to share our music with the world through our sheet music, which we’re currently unable to do.
How can we preserve the benefits we currently have as an improvised jazz band, while also achieving our goals?
Let’s walk through each quality of our performance process, and the tradeoffs we’ll need to make.
The first quality that we enjoy as a jazz band is that our performance is direct
Being direct means that there is convenience in how the musicians create the performance, and the performance is transcribed directly to the sheet music.
Next, our performance process is flexible!
If a musician notices that the performance would be better if their part were louder, this would reflect in the transcribed sheet music of the performance.
And finally, as a jazz band, we like knowing that the sheet music that is transcribed from the performance will always be accurate (provided of course that we have a talented transcriptionist)!
However, as a jazz band there’s some room for improvement
For instance, our performance process does not guarantee a singular piece of sheet music.
Our musicians can perform any number of performances, with each producing a slightly different output of sheet music.
Additionally, our performance process does not have sheet music available at any given time, as a full performance and transcription is necessary before the sheet music is available.
With generating sheet music being an inconvenient and time consuming task, this impacts our ability to share the sheet music with other musicians or export it to a digital format as well.
And finally, if a musician unintentionally makes a mistake, the mistake would be recorded into the final sheet music, which would have a ripple effect to other musicians performing the music or digital exports.
So with these goals in mind, what’s one step we could take to making this sheet music and performance process more singular, available, and intentional?
Well currently the performance is developed before the sheet music, so let’s try flipping it so the sheet music is developed before the performance!
Now that we’ve written the sheet music out first, and have given it to our musicians, we achieve our goals of singularity and availability by having a single source of truth on-hand.
However, the performance of the sheet music may not be intentional, given that the musicians can still make mistakes.
With the possibility of mistakes, that also means there’s no guarantee that the Sheet Music the musicians have, and the Sheet Music transcribed from the performance, are the same.
How can we ensure that the musicians perform the music as intended, without making any mistakes?
Well, we could replace the musicians with robots!
With robots performing the music, we achieve all our goals!
We have a single source of sheet music
The sheet music is composed ahead of time and is readily available to share
And We can guarantee that the Sheet Music will be always performed as intended, since again, it’s being performed by robots!
However, in replacing human musicians with robots, we lose a level of musicality, which ultimately affects the flexibility of the performance that we had before.
For example, if we want a part of the music to be louder, the robot musician would disregard any level of nuance in favor of following the score note for note.
That means that any musicality details and nuance would need to be written directly into the sheet music ahead of time, which could become very time consuming and complex.
So, let’s take a step back from robots, and reflect on where we are. We want to have our Sheet Music composed and available, and we have a feeling it’s a step in the right direction, but we need something to align the sheet music across our whole performance cycle.
Picturing this group performing on a stage, there’s a key member that it feels like we’re missing.
A conductor!
A conductor has the ability to internally transcribe the sheet music from the performance in real time and verifies its alignment with their golden copy of the sheet music, called the score.
Now, the sheet music is developed before the performance, but alignment is also guaranteed between the performance and the sheet music!
It’s direct in that it’s convenient to perform for the conductor, who can transcribe in real time
It’s flexible where if a musician notices that the performance would be better if their part were louder, the conductor would notice the difference, but can act as a mediator to update the score to reflect the positive change
The performance will always be aligned with the conductor’s transcription, and in turn the score itself.
There is also a singular source of truth for the sheet music, as represented by the score.
The score itself is also available at any time for either sharing with another musician or exporting to a digital format for remixing.
Additionally, it’s circularly available as a sheet music source for the performing musicians as well.
And while the conductor serves as a flexible mediator for productive changes, if there are unintentional mistakes, the conductor can detect them and indicate that they should be addressed, keeping the golden copy of the score preserved as intended.
With our goals of availability, singularity, and intentionality in mind, we’ve come a long way from our original process of improvised jazz, from a performance driven approach, to a score driven approach, with the help of conductor.
Now you may be asking yourself, what does any of this have to do with APIs? And that’s a good question!
Well, while we’ve walked through the journey of this jazz band adopting a score driven approach through the help of a conductor…
This is the same journey our team took when adopting an API-Driven approach, however instead of
A source of musicians
A production of our performance
And an output of Sheet music
This was actually our Code-First approach, where the code is developed before the API.
Instead of musicians, our source is API code
Instead of a performance, our production is the live API in production
And instead of sheet music, our output is an OpenAPI Specification, with the ability to export to tools like API documentation or Postman
So, with this shift, let’s recap what we tried with the jazz band to achieve the goals of having a singular, available, and intentional OpenAPI Specification to serve as the source of truth in our development process
We tried API-First, quite literally, by developing the API design first and having it inform our API code like sheet music, and for a time this gave us a singular and available copy of what we wanted to develop.
However, just as with our jazz band, intentionality was still lacking, and as code is updated, although following a OpenAPI Specification is a great guide, there’s nothing preventing unintended API changes from making it into production.
So again, how can we ensure that the OpenAPI Specification is honored?
Taking inspiration from our robot approach from earlier, we could generate all the API code from the OpenAPI Specification using a code generator tool! This ensures that our goal of intentionality is met since the production API and generated OpenAPI specification will always reflect that core OpenAPI Specification.
However, given that we’re a SaaS platform, generating our API entirely from an OpenAPI Specification would cost us the flexibility of our application’s business logic, meaning new features would need to be built entirely from within the OpenAPI Specification as opposed to in a codebase.
And while it would be really cool to replicate the nuance of our entire web application with OpenAPI extension properties, it would unfortunately be very time consuming and complex.
So here we are, stepping back to API-First, trying to balance the trade-offs of the benefits of Code-First and API-First.
We need to call our friend the conductor
And in this case, our conductor and score is instead
an integration test
and a main, static, and golden copy of our OpenAPI Specification
Just as the conductor served as a mediator and validator between the performed sheet music and the score, the integration test validates alignment between the generated OpenAPI specification and the main OpenAPI Specification
And as the score served as a source of truth for the sheet music, the main OpenAPI Specification serves as a static, per-commit reference of the API at any given moment in time
With this approach we balance Code-First and API-First together, where the API is developed before the code, and alignment is guaranteed between them, thanks to our integration test
Let’s take a closer look at our Integration Test and this main OpenAPI Specification
Our main OpenAPI specification lives in our codebase alongside our production code
It’s a static file, so there’s no need to generate it
Since it doesn’t require generation, it’s also available for reference or testing at any given time
And thanks to our OpenAPI Test, it accurate reflects the state of the API in the codebase at any given time, to the git commit
When we zoom into the code of the test level, the OpenAPI test is only a few steps, and could be refactored into a variety of code languages that have OpenAPI libraries available.
The test here is written in Kotlin and here are the steps it does:
First it creates an OpenAPI object based off of the static, main OpenAPI File in our codebase
Next, it creates a second OpenAPI object from the OpenAPI File generated from our API (in example, we’re getting this file from an endpoint provided by our API documentation library)
Then we test both OpenAPI objects for equality, which depending on the language and library, can sometimes be done with a default equals symbol or method alone, or you can test certain sections of the OpenAPI specification uniquely too
A bonus while you’re testing is to test both OpenAPI Specifications for formatting, this way you can ensure that every property is documented and that API design standards are met for things like camelCase versus kebab-case
That’s not the only bonus though
With the existence of this test makes any API-First change to the OpenAPI Specification is an act of Test-Driven Development!
If you’re familiar with Test-Driven Development, it’s a development model where tests are developed before the code.
Similarly, API-First is where the API is developed before the code.
And with both the API and our OpenAPI Test developed before code is written, our API-Driven approach can be thought of as a combination of these two models.
As a result, we’re able to gain the benefits of Test-Driven development in that we can update the OpenAPI specification to drive the implementation of the API.
For example, in the screenshot here, a developer adding a new property can add all the details of API change to the OpenAPI Specification prior to development, then make the code changes to meet this definition.
This certainly doesn’t replace functional testing, but it serves as a design test to ensure that your code changes are aligned directly to the planned design of the API.
If the OpenAPI test detects an unexpected change that occurred during development, the test will fail, however you now have the flexibility to determine whether you should update the code to fit the specification, or whether the main specification itself should be updated, similar to our conductor updating the main score based on constructive feedback from a musician.
With our main OpenAPI specification at the center of our development process, we’ve been able to leverage it in so many ways.
We’ve improved out API Documentation using open source tooling to generate it per-release
We’ve released the openapi specification itself on GitHub, so it can be accessible to any developers looking to leverage it
API Design can be defined ahead of development, with testing in place to ensure that API design criteria is met from code changes
With a test in place, we can also detect breaking changes in our API design prior to merging code, adding transparency into our development process.In addition, each merge request for review includes the updates made to the OpenAPI Specification, making the API changes clear and visible.
We’ve also gained the ability to share accurate release notes, powered by open source tools to take a diff between the OpenAPI Specifications of the current and previous release, saving us a ton of time and helping our customers be aware of every change in a given release.
And finally, we also use our OpenAPI Specificaiton as the basis for our Postman Collection, which has allowed us to have an accessible means of streamlining the onboarding of API development for our customers.
So what’s next?
We’re planning to leverage the OpenAPI Specification to build client SDKs
We’re looking to scale out API-Driven development into our feature planning and ticket planning by attaching the pre-designed OpenAPI Specification to development tickets to serve as a guide for development
And while a lot of this work was focused towards our public APIs, we’d love to see the benefits internally as well, so we’re exploring how we can leverage this model for our internal API practices too
Overall, here are some of the takeaways we learned
API-First is a journey, not a destination - and it’s a series of trade-offs from where you’re at and how you can continue to prioritize API design in your development process
Next, OpenAPI Specifications go a long way, and formalizing one as a single source of truth at any given time goes even further, unlocking so many new opportunities. However, building out a process to have this single source of truth can be a challenge. In our case, the solution was an API-Driven development model.
And on that note, our final takeaway was the discovery of our API-Driven development model which combined Test-Driven development with an API-First approach, allowing us to leverage the best of Code-First and API-First development.
So once again, I’m Brett Bush! If you’re interested in chatting more about API-Driven development, DevRel, or APIs in general you can connect to me on LinkedIn, my website, or any time during the conferenceAnd if you’re interested in leveraging our Risk Cloud platform to help with managing your Cyber Risk programs, check out LogicGate as well!That’s all from me, thanks so much!