Dynamically expose Open API definitions in Azure API Management

Open API is currently the most common used API standard out there.  API Management has full support for this standard.  The basis of this standard is the Open API definition (often referred to as “Swagger” – the tooling), which describes all the functionality that a certain API supports.

Standard Open API Support

In case API consumers want to connect to your API, they typically ask for that definition.  That definition can often be imported into systems to generate code classes or integration endpoints.  The out-of-the-box capabilities of API Management to offer that definition include:

  • Copy the definition from the Azure portal (most of your API consumers don’t have access to this):

  • Export the definition from the API Management Developer Portal:

Create your own Open API endpoint

In some cases, you just want to share an endpoint where the Open API definition is available, without the need to setup and configure the Developer Portal.  Let’s have a look on how this can be done.

  • Enable managed identity in API Management

  • Grant that identity the API Management Service Reader Role role on its own API Management instance

  • Create a new and empty API (e.g. Documentation API)
  • Add an operation to download the Open API specification, by providing the api-id

<inbound>
   <base />
   <!--Dynamically call the APIM Management API-->
   <send-request mode="new" response-variable-name="result" timeout="60" ignore-error="true">
      <set-url>@("https://management.azure.com/subscriptions/xxxx/resourceGroups/xxxx/providers/Microsoft.ApiManagement/service/xxxx"  + "/apis/" + context.Request.MatchedParameters.GetValueOrDefault("api-id","") + "?export=true&format=openapi&api-version=2021-01-01-preview")</set-url>
      <set-method>GET</set-method>
      <authentication-managed-identity resource="https://management.azure.com/" />
   </send-request>
   <!--Return the response-->
   <return-response>
      <set-status code="200" reason="OK" />
      <set-header name="Content-Type" exists-action="override">
         <value>application/yaml</value>
      </set-header>
      <set-body>@((string)(((IResponse)context.Variables["result"]).Body.As<JObject>()["value"]))</set-body>
   </return-response>
</inbound>

It is advised to configure the API Management resource id as a named value and use it within this policy

  • You have now create a generic API endpoint that returns the Open API definition of every API

This is implemented as an API, so you can add any type of security, depending on your requirements

Conclusion

This is a simple solution for a feature that many folks expect out-of-the-box.  Please, keep in mind that sharing an Open API specification holds some security risks.  That’s why it is highly advised to apply a simple kind of authentication (e.g. subscription key).

I hope you’ve like this one!
Adios!
Toon

 

ABOUT

MEET THE YOUR AZURE COACH TEAM

Your Azure Coach is specialized in organizing Azure trainings that are infused with real-life experience. All our coaches are active consultants, who are very passionate and who love to share their Azure expertise with you.