/ Azure

Changes to OpenAPI interpretation in Azure API Management

TL;DR - Azure API Management released a new version that changes the OpenAPI interpretation. This article dives into the potential impact on of the consumer experience of your APIs.

Providing clean and well-documented APIs is a must. This allows your consumers to know what capabilities you provide, what they are for and what to expect.

This is where the OpenAPI specification, aka Swagger, comes in and defines how APIs should be defined across the industry, regardless of what technology is underneath it.

Recently, the Azure API Management team started releasing a new version of the product with some new features and some important changes in how they interpret the OpenAPI specification while importing/exporting them.

Before we dive into the changes to OpenAPI interpretation. I'd like to highlight that they've also added the capability to the display id of a specific operation. In the past, you still had to use the old Publisher portal for this but now you can find it via API > Operation > Frontend.

Next to that, as of last Sunday, the old Publisher portal should be fully gone now, except for the analytics part.

OpenAPI Interpretation

The latest version also changes the way OpenAPI specifications are being interpreted and are now fully based on operation as defined by the OpenAPI spec.

Here are the changes in a nutshell:

  • Id of the operation - Operation Id is based on operation.operationId, otherwise it is being generated similar to get-foo
  • Name of the operation - Display name is based on operation.summary, otherwise it will use operation.operationId. If that is not specified, it will generate a name similar to Get - /foo
  • Description of the operation - Description is based on operation.description

I like this change because it makes sense, however, this can be a breaking change in your API documentation depending on how you achieved it in the past.

The reason for this is that before rolling out this change the interpretation was different:

  • Id of the operation was a generated id
  • Name of the operation was based on operation.operationId
  • Description of the operation was based on operation.description and falls back on operation.summary

How I did it in the past

For all the projects I work on I use Swashbuckle because it's very easy to setup, use and ties into the standard XML documentation.

Here is an example of the documentation I provide for my health endpoint for Sello, which I use for demos.

/// <summary>
///     Gets the current health status of the API
/// </summary>
[HttpGet]
[Route("health")]
[SwaggerOperation("Get Health")]
[SwaggerResponse(HttpStatusCode.OK, "API is up & running")]
[SwaggerResponse(HttpStatusCode.InternalServerError, "API is not available")]
public IHttpActionResult Get()
{
    return Ok();
}

As you notice, everything is right there and via the operation I specify what the operation is called and give a brief summary of what it does and what my consumers can expect as responses.

The OpenAPI specification that is generated will look like this:

{
    "swagger": "2.0",
    "info": { ... }
    },
    "host": "localhost:1337",
    "schemes": ["https"],
    "paths": {
        "/api/v1/health": {
            "get": {
                "tags": ["Health"],
                "summary": "Gets the current health status of the API",
                "operationId": "Get Health",
                "consumes": [],
                "produces": ["application/json"],
                "responses": {
                    "200": {
                        "description": "API is up & running"
                    },
                    "500": {
                        "description": "API is not available"
                    }
                }
            }
        }
    },
    "definitions": { }
}

Once this is imported into Azure API Management the developer experience was similar to this:
API based on old OpenAPI import and old interpretation

However, this approach is no longer what I'd like to offer to my consumers because if you import it after the new version it looks like this:
API based on old OpenAPI import and new interpretation

How I'm doing it today

Aligning with the latest interpretation was fairly easy to be honest, instead of providing a description what the operation does via summary I started using remarks instead.

Next to that, I'm now using summary to give the operation a friendly name and assigned a better operationId via SwaggerOperation.

This is how it looks in code:

/// <summary>
///     Get Health
/// </summary>
/// <remarks>Gets the current health status of the API</remarks>
[HttpGet]
[Route("health")]
[SwaggerOperation("get-health")]
[SwaggerResponse(HttpStatusCode.OK, "API is up & running")]
[SwaggerResponse(HttpStatusCode.InternalServerError, "API is not available")]
public IHttpActionResult Get()
{
    return Ok();
}

The new OpenAPI specification is compatible with the recent changes and will look like this:

{
    "swagger": "2.0",
    "info": { ... }
    },
    "host": "localhost:1337",
    "schemes": ["https"],
    "paths": {
        "/api/v1/health": {
            "get": {
                "tags": ["Health"],
                "summary": "Get Health",
                "description": "Gets the current health status of the API",
                "operationId": "get-health",
                "consumes": [],
                "produces": ["application/json"],
                "responses": {
                    "200": {
                        "description": "API is up & running"
                    },
                    "500": {
                        "description": "API is not available"
                    }
                }
            }
        }
    },
    "definitions": { }
}

Once this is imported the developer experience is maintained and looks similar to this:
API based on new OpenAPI import and new interpretation

When you go to the details of the new operation in the Azure portal, you will see that all our information is succesfully imported:
APIM-Admin

Conclusion

Azure API Management rolled out a change to the OpenAPI interpretation to provide more flexibility so you can define the operation id to use and align with the general specification.

This change is great, but it might have an impact on your current API documentation, similar to what I've experienced. With the above changes, you are good to go and your consumers will not even notice it.

Thanks for reading,

Tom.

Tom Kerkhove

Tom Kerkhove works for Codit as an Azure Consultant, is a member of the AZUG crew and has been a Microsoft MVP & Azure Advisor since 2014. He turns coffee into scalable & secure cloud systems.

Read More