API Mocking Options with Azure API Management

Jose Reyes
• 11 min read

Software Development with Azure API Management

About 4 years ago, Azure introduced Azure API Management (APIM) and it paved the way for enabling companies to productize and monetize their APIs. APIM served as a proxy or an API gateway with typical gateway functionalitities such as data transformations, rate-limiting or throttling, API key protection, and API management through the publisher and developer portals. It enabled companies an additional revenue stream by making their APIs available to a larger audience.

Azure API Management

APIM has had numerous features added since then. At the start, APIM was limited to interfacing with on-premise and Azure-hosted APIs. It has now expanded to the serverless architecture space in Function Apps and Logic Apps. The developer portal is still there, however the publisher portal has slowly been phased out and merged into the main Azure portal. To complement all these features, a couple of options was added for creating mocks for our APIs. I will dedicate the rest of this post to this feature.

Azure function appAzure logic app

Typical software development

In a typical agile software development environment, a cross-functional team works together to deliver the sprint goals. Tasks are developed in parallel as much as possible. Take front-end work for example. Normally the UI front-end team has this dependency on the back-end API team due to the APIs being consumed by the front-end. How can the front-end team develop in a timely manner taking into account this dependency? An API contract will need to be defined.

Enter OpenAPI (previously Swagger)

OpenAPI is a specification for machine-readable interface files for describing, producing, consuming, and visualizing RESTful web services. It promotes collaboration in a project, as it defines the API contract that the API adheres to, and allows the front-end to confidently work in parallel with the backend development.

SwaggerOpenAPI

Traditionally, OpenAPI was simply used to document an API after it has been developed. In the traditional waterfall approach, the API gets developed first, before the front end efforts starts and consumes the API. This is what is commonly called the Code first approach.

As more development teams move to agile methodology, where emphasis is given to more collaboration and efficient team-based development, another approach developed - Design first. This method required the definition of the API contract at the start of development, and facilitated both the front end and back end developers working on the project in parallel.

Because the API contract is now available, the team can now quickly create API mocks based on the OpenAPI contract, while the backend team are hard at work. This unblocks the front end team and allows them to continue with their usual flow of development.

APIM Mocking options

A. Mocking using Azure hosted API

The first option in API mocking is to simply create an API using a server language (C#, Javascript, Go, etc…) and host it in Azure. We are not going to discuss deeply on this as this topic is already heavily discussed everywhere on the web, however it is worth mentioning that there are code gen tools out there to automatically generate stubs for you, using your favorite server language.

This is the most flexible method, in terms of being able to create infinitely dynamic APIs, however, the overhead of writing this code and hosting it, may be too much for the current requirement.

B. Static Mocking using APIM

For basic mocking scenarios, where returning static data is enough, an APIM policy called mock-response can be used in your inbound policy. As a backbround, here is a link that discusses all the different APIM policies available for us to use.

Add mock-response

Adding mock-response to the input processing pipeline.

Mocking is enabled

Adding the mock-response policy short circuits the pipeline, effectively bypassing the backend processing and the outbound processing. As handy as it is in swiftly creating simple mocks, that's all it is good for - creating simple mocks. But if that is all you need, then this is perfect!

Testing mock response

APIM conveniently has a tab for testing our APIs, so you can easily switch to that tab, and test your API, much like how you normally do it with tools like Postman, or some other similar REST client. Here was can see that the API responded with the sample data as it is in the swagger document.

If you like a bit more dynamic behaviour in your mocks, then continue reading.

C. Dynamic mocking using APIM

For a bit more dynamic mocking behaviour an APIM policy called return-response can be used instead. It is not the 'official' policy for mocking however, this has been typically used for a bit more flexible API mocking behaviour. If you combine it with all the other advanced policy options and policy expressions, you can go a long way without having to spin up a proper web api server, which is what you should do if you really have very specific dynamic API mocking requirements.

For example, below is some script I added in the inbound processing:

<inbound>
    <base />
    <choose>
        <when condition="@((context.Request.MatchedParameters.GetValueOrDefault("petId")) == "dog12345")">
            <return-response>
                <set-status code="200" reason="OK" />
                <set-header name="content-type" exists-action="override">
                    <value>"application/json"</value>
                </set-header>
                <set-header name="correlationid" exists-action="skip">
                    <value>@{ 
                        var guidBinary = new byte[16];
                        Array.Copy(Guid.NewGuid().ToByteArray(), 0, guidBinary, 0, 10);
                        long time = DateTime.Now.Ticks;
                        byte[] bytes = new byte[6];
                        unchecked
                        {
                            bytes[5] = (byte)(time >> 40);
                            bytes[4] = (byte)(time >> 32);
                            bytes[3] = (byte)(time >> 24);
                            bytes[2] = (byte)(time >> 16);
                            bytes[1] = (byte)(time >> 8);
                            bytes[0] = (byte)(time);
                        }
                        Array.Copy(bytes, 0, guidBinary, 10, 6);
                        return new Guid(guidBinary).ToString();
                    }</value>
                </set-header>
                <set-body>{
                    "id": "dog12345",
                    "name": "Scooby",
                    "tag": "Funny Dog"
                }</set-body>
            </return-response>
        </when>
        <when condition="@((context.Request.MatchedParameters.GetValueOrDefault("petId")) == "cat12345")">
            <return-response>
                <set-status code="200" reason="OK" />
                <set-header name="content-type" exists-action="override">
                    <value>"application/json"</value>
                </set-header>
                <set-body>{
                    "id": "cat12345",
                    "name": "Garfield",
                    "tag": "Sleepy Cat"
                }</set-body>
            </return-response>
        </when>
        <otherwise>
            <return-response>
                <set-status code="404" reason="Not Found" />
                <set-header name="content-type" exists-action="override">
                    <value>"application/json"</value>
                </set-header>
                <set-body>{
                        "error":"Not Found"
                    }</set-body>
            </return-response>
        </otherwise>
    </choose>
</inbound>

Look for Scooby Doo

The mock API returns data depending on user input.

Error not found

For more flexibility, you can add multiple lines by putting your code in enclosing curly brackets. See example above where I have added another header called correlationid where I added the multiple line C# script.

Summary

So there you have it.

We have explored Azure API management, and have identified a useful feature that can be used to make software development more efficient.

The ability to create API mocks quite easily in APIM has been there for a while now, however I do not think it is widely used, specially the ability to add some dynamic behaviours. And we have seen how quick and easy it is, and this is the key, because at the end of the day, mocks are throw away assets, and we can't spend too much time and resources on them.

Resources

Azure API Management

APIM Policy Expressions

Mocking Responses

Swagger workflow for today's API economy


Jose Reyes

Software Engineer with many years of experience in the development of mission-critical software for a broad range of industries. Jose currently works as a consultant with Readify in Sydney, Australia.

Website: https://www.linkedin.com/in/joreyes/