Conquer the API Rainbow Road Level with these Dev “Cheat Codes”
First Things First, Addressing the Hazards
Now, to the Cheat Codes
Cheat Code #2: Generate API code from Specs
Cheat Code #3: Test With Spec-Driven Mocks
Cheat Code #4: Develop Locally, Test Remotely
Cheat Code #5: Use Production Like Dev Environments
One Final Easter Egg…
Much like the rainbow road level in the popular Mario Kart games, the API development world is getting more and more complex. How do you power up your dev team to complete each level faster and better? Let’s get into the top five “cheat codes” that will put your dev team in the winner’s circle.
From design through testing, this blog will share how to give developers ultimate control over the development process, pursue spec-first development, and remove infrastructure obstacles from impeding the advancement of your API strategy.
If you’re more of a listener than a reader, you can watch my 2024 API world talk on the same topic below.
Listen to the Talk at API World 2024
First Things First, Addressing the Hazards
Hazards in Mario Kart refer to obstacles that can impede your progress in several ways, ranging from spinning you out to slowing down or knocking your kart over. Sound familiar? We experience many of these in our daily development lives, too. And before I jump into the cheat codes, it’s important to understand what challenges we’re trying to address.
The first hazard: Too many APIs and not enough spes.
I think of this problem like getting hit with a blue shell in Mario Kart. You may be racing towards deploying an API into production, but without things like API contract tests or proper API governance, you can get hit with a game-ending bug or security vulnerability. Failing to pursue a design-first approach to API development can not only lead to a poor developer experience but also be the reason for bugs, integration issues, and possibly security gaps in your production APIs. Most traffic on the internet today is done through API calls. Additionally, according to Postman’s 2023 State of the API report, “85% of devs say ‘they have a RESTful API,’ but less than 50% have OpenAPI Specs.”
Now, you may be asking yourself, “why is that problem? What’s the big deal with specs?”
API specs describe the contract between the server and client, acting as a source of truth. In this way, a spec can assert that an API is implemented correctly - we can use it for contract testing or other integration tests. API Specs can also be a boon to organizations with thousands of microservices offering the ability to govern and enforce API standards.
Without the API spec, you may face the following issues:
Integration issues: You may have tested your API thoroughly, but how do you know it will work with other services or clients?
More Bugs: A spec is a manifest that anyone can use for testing. Without it, you may not be covering all parts of your API with tests which can lead to bugs or regressions.
Worse Security: Microservices powering APIs on the internet create a big attack surface area, with cybercriminals often exploiting vulnerable APIs to launch their attacks. What happens when you don’t have specs for all your microservice APIs? You may have forgotten to apply a security scheme to an API, and without the spec you may be missing a crucial security test case.
Awful Developer Experience: This should go without saying, but missing an API spec can lead to lack of documentation for those looking to consume that API. This not only affects your public APIs, but internal ones as well. And when talking about DX, don’t assume it’s just for humans but potentially machines too (e.g. AI agents).
Now, I know that a design-first approach to building APIs is easier said than done. Many times I have built the API first and generated the spec afterwards. But this still carries the same integration and security risks and may lead to drift between the API spec and the implementation. Don’t despair, there is tooling out there (such as Blackbird) that can help you pursue a design-first approach, going seamlessly from API spec to generate server-side code, but that’s a story for later on.
Hazard #2: Bad DevEx in Development Loops
The next hazard to watch out for on the rainbow road of API development would be similar to the lightning bolt in Mario Kart, which shrinks all players except the user, slowing them down and making them vulnerable to being squished. That same kind of vulnerability and poor process occurs when we’re not operating our development loops effectively.
Development loops are tasks that we, as developers and teams execute regularly as part of the Software Development Lifecycle. We break them down into two loops: the inner and the outer dev loop. Think of them this way:
- The Inner Loop -> Fast, Local, run it multiple times: This is where developers write, build, test, debug, and commit code. It should be a fast, efficient loop, because a developer may execute it multiple times when implementing an API. It also typically happens locally on a developer’s workstation.
- Outer Loop -> Slow, Remote, run it as few times as possible: Conversely, the outer loop covers the activities such as reviewing code, running automated tests, and integrating the code within a test or staging environment leading into a production release. These activities typically happen in shared, remote environments and will take a lot longer than running the inner dev loop - a reason why we should strive to run it as few times as possible.
These loops create inherent trade-offs for developers. For example, working on a microservice allows for rapid inner loop iterations but often sacrifices the quality of the local development environment, as running all necessary services locally is impractical. On the other hand, developing within a monolithic code base may mean you can run the full stack on your local machine and get high-quality testing, but this slows down the inner loop due to longer compile times and a large premium on compute resources.
Another trade-off is autonomy and specialization.
Typically the inner dev loop is the domain of a developer while the outer loop falls more within the wheelhouse of platform engineers. While self-sufficient teams capable of both developing an API as well as managing their infrastructure might seem ideal, it puts a high demand on developers to have those infrastructure skills.
This often leads to specialized teams for API development and platform engineering, which can introduce silos and friction when running the dev loops. Together, these trade-offs highlight the complexity of creating a seamless developer experience while balancing speed, quality, and collaboration.
Now, to the Cheat Codes
Whether you are new to API development or a seasoned engineer, it’s important to know the hazards that keep us from building high-quality APIs. Fortunately, I have some cheat codes that anyone can use to help avoid these hazards.
As I discuss the cheat codes, I’ll be taking the perspective of a software engineer tasked with building an API - let’s assume I need to build an AI Chatbot API. Let’s also pretend that it needs to be a microservice, consumable by some kind of front end, and able to integrate with another third-party API, something like OpenAI for example. Walking through this example will help round out the concepts in the cheat codes and hopefully will inspire you to build your own API as you follow along.
Cheat Code #1: Design First With AI
During our time at API World 2024, we asked all attendees the question of “What is your greatest source of frustration as it relates to APIs?” After security, 23% noted that manual work was the next great frustration. The foundation of great API development starts with a well-designed spec, and AI is your secret weapon here. Instead of spending hours handcrafting specs, leverage AI tools (like Blackbird) to generate them quickly and accurately. Imagine being able to produce a high-quality API spec by asking the following:
“Hey, I want an API spec for a chatbot microservice. I want to add an endpoint for submitting a chat message. Also, I want a bunch of examples for submitting a chat message and include handling for all potential types of status codes.”
Now, AI won’t get everything right, but it’s far better than editing just raw JSON or YAML, and I do believe it's the next step above using form editors to create these API specs. If we apply things like validation and linting we can have AI produce results that are compliant with OpenAPI spec standards. We can even pipe the errors and warnings from a linter back into an AI assistant to automatically fix them within the spec! AI is good at generating content, but also good at producing a structured output, like OpenAPI. With a little prompt engineering, we can significantly speed up the process of spec creation and editing.
On top of that, we can use AI with API style guides to see if specs are following the same patterns, reusing shared schemas, or enforcing the right security protocols. If they aren’t, an AI assistant can recommend and make the changes.
The key here is that we need to treat AI as a helpful assistant so that it can recommend different changes that we want to make to our API specs, and then we as the developers can decide whether or not to accept or reject those changes. We’re simply automating the tedium out of generating the content of these specs while still retaining control over what that content should be.
Cheat Code #2: Generate API code from Specs
When I’ve built APIs in the past I usually jumped straight into the implementation and worried about creating the API spec after the fact. I know many developers and teams that regularly follow that process too.
I think we should flip that process. If we can arrive at that high quality API spec really fast, why not just use that as a template for generating server-side boilerplate code?
Here are some benefits you may be missing out on by not generating server-side code from the API spec:
- Compliance with your Spec: Your implementation of your API code will match the spec that you've generated from. This also ensures that your implementation is already passing all the tests that you might have created against that API spec.
- Templated Services: Many APIs are powered by microservices. Using a spec file and a project template ensures you get new API microservices that follow your organization’s conventions and standards.
- Fewer Bugs: Not only can you eliminate copy and paste bugs by generating server-side code but you’ll also not forget to do the important things like apply security schemes.
- Time Saved: Since we’re generating boilerplate client and server-side from API specs, think of the time saved that you can invest elsewhere in your development process.
Cheat Code #3: Test With Spec-Driven Mocks
Carrying on with the AI Chatbot example, if I start implementing the API code I may quickly run into a few challenges: a front-end engineer might want to test against my API before it’s ready. And the backend code I’m writing needs to integrate with a 3rd party API. Both are perfect use cases for some robust mock servers.
Mocks are extremely powerful tools, but can often be an additional investment for most developer teams in terms of time and resources. Since we already have the high-quality API spec from the first cheat code, why not just have a mock server-generated straight from that API spec?
With mocks, we can enable parallel development for the teams working on building the API as well as consuming the API. We can also be confident that the client and server side code will integrate with each other.
Tightly coupling the mock to the spec file also has advantages. A tool that can create a mock directly from the API spec and mock out all aspects of that spec essentially turns that spec into an interactive contract. Changes to the spec can immediately be reflected in the mock.
One thing to keep in mind is that the quality of your spec will dictate the quality of your mock - something that the first cheat code should help you with. But, in a similar fashion to spec-driven server-side code, I would rather API developers focus on creating a quality API spec first that can be used to generate things like mocks after the fact.
Cheat Code #4: Develop Locally, Test Remotely
Let’s bring it back to those API Rainbow Road dev loops, and imagine I'm developing that AI Chatbot API in my inner dev loop. I’m at the point where I've committed and pushed my code (and ideally–it's all working great!). The process shifts to the slow outer dev loop where my CI workflow will deploy my API into an integration environment.
Unfortunately, after all that waiting around, I get the dreaded angry Slack message from a front-end engineer, saying, “hey, Matt, your API is broken.” I know many of you have been in my shoes before, where you thought your code was working only to find a bug farther down the line. And as I mentioned in the hazards earlier, it may not have been a bug within your API code, but in how it integrates with other components.
And yes, you could always hit them with the old ‘it works on my machine” excuse (we’ve all been there, no judgement!), but I think there’s a cheat code here where instead we can say: “it works on my machine, and I can prove it!”.
Traditionally, I would have to return to the inner loop to fix this bug and then re-execute the outer development loop to see if my changes worked. Since we know from our conversations that outer dev loops are rather expensive, I want to avoid executing that multiple times if possible.
The solution lies in moving the test activity from the outer dev loop into the inner dev loop. This is where the cheat code and concept of developing locally, and testing remotely, comes in.
How can we enable remote testing of my API under development? We can aim for a setup that produces a public URL that anyone could call to hit the API running on my local machine. Tools like Blackbird or Telepresence can accomplish this by bridging a remote environment’s network to my local machine. The remote environment manages the public host on which anyone can make a request to my API and have it routed to the code I’m running locally.
This process allows me to collaborate with other engineers, like a front-end developer for example, during my fast and efficient inner dev loop. We can find bugs and get an early look at how my API is integrating before committing to the expensive cycle on the outer loop. This way, I’m staying in my inner dev loop flow state which saves costs, keeps my front-end engineers happy, and creates a higher quality API.
Cheat Code #5: Use Production Like Dev Environments
Piggybacking off of the previous cheat code, let’s discuss the power of making your development environments look closer to your production environment.
Teams commonly create production-like environments in the outer dev loop to test and integrate changes before they go live. But, what if we took that idea and also applied it to our inner loop development environments? Thus, producing greater confidence in higher-quality testing in development before we even get to things like staging or production.
The catch is, once again, we need to conduct all of this without increasing the time a developer spends on the inner loop. Most developers can’t afford to build and run entire production-grade applications on their local machine, especially in microservice architectures. But, if it was a shared development environment that was remote, developers could reap the benefits of testing on a production-quality environment that includes all the infrastructure, such as API gateways, proxies, etc. as well as the latest copies of microservices and dependencies.
In order to share a prod-like development environment with other devs we’d leverage cheat code four and grant the ability to route traffic from that remote dev environment to local developer machines. In this way, a whole team could develop APIs locally and confidently test them against a prod-like development environment. And the best part is that developers would get high-quality testing in the inner dev loop without increasing the time! An additional benefit to this approach too is that you’re not creating a copy of a remote production environment for every single developer, which will cut costs significantly.
One Final Easter Egg…
Knowing what hazards to avoid and what cheat codes to apply will help you ensure that you don't get stuck on the Rainbow Road of API development. The last easter egg I’d like to leave with you is a final power up for your API development strategy.
Blackbird is Ambassador’s new API development platform that uses these cheat codes in real life. From an AI assistant that helps build and edit API specs and then immediately takes those specs to create hosted mocks to being able to generate server-side API code from those API specs. Blackbird does it all.
Plus, on the infrastructure side, Blackbird comes with an out-of-the-box hosted environment that allows you to do things like develop locally but test remotely with shareable URLs and deploy and test your API code before it enters the outer dev loop. This is a developer-friendly tool that comes with both a UI and CLI - it meets developers where they are at.
The final note I’ll leave with you to help you level up is this: You can’t manage your way into API quality & consistency...you develop it.
The journey to API excellence is full of challenges, but the right tools and strategies make the path smoother. Use these cheat codes, embrace innovation, and let your team shine. Try Blackbird for free for yourself if you’re entering your own API rainbow road level.