Set version and revision with Azure API Management

Last Update: 12/6/2019
Azure
API Management

This article describes how to add versions and revisions with Azure API Management. To set API version and revision, deploy apis and apiVersionSets resources. Let's learn how to deploy these resources using the ARM Template.

ARM Template

First, let's take a look at the entire ARM Template.

apis.json
{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "apiRevision": {
      "type": "string",
      "metadata": {
        "description": "API Revision"
      }
    },
    "apiVersion": {
      "type": "string",
      "metadata": {
        "description": "API Version"
      }
    },
    "serviceName": {
      "type": "string",
      "metadata": {
        "description": "API Management Service Name"
      }
    },
    "apiVersionSetName": {
      "type": "string",
      "metadata": {
        "description": "API Management Version Set Name"
      }
    },
    "apiName": {
      "type": "string",
      "metadata": {
        "description": "API Name"
      }
    },
    "apiDisplayName": {
      "type": "string",
      "metadata": {
        "description": "API Display Name"
      }
    }
  },
  "variables": {},
  "resources": [
    {
      "name": "[concat(parameters('serviceName'), '/', parameters('apiVersionSetName'))]",
      "type": "Microsoft.ApiManagement/service/apiVersionSets",
      "apiVersion": "2019-01-01",
      "properties": {
        "description": "version sets of my apis.",
        "displayName": "[parameters('apiVersionSetName')]",
        "versioningScheme": "Segment"
      }
    },
    {
      "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), ';rev=', parameters('apiRevision'))]",
      "type": "Microsoft.ApiManagement/service/apis",
      "apiVersion": "2019-01-01",
      "dependsOn": [
        "[resourceId('Microsoft.ApiManagement/service/apiVersionSets', parameters('serviceName'), parameters('apiVersionSetName'))]"
      ],
      "properties": {
        "description": "my api",
        "displayName": "[parameters('apiDisplayName')]",
        "apiVersionSetId": "[resourceId('Microsoft.ApiManagement/service/apiVersionSets', parameters('serviceName'), parameters('apiVersionSetName'))]",
        "apiVersion": "[parameters('apiVersion')]",
        "apiRevision": "[parameters('apiRevision')]",
        "authenticationSettings": {
          "subscriptionKeyRequired": false
        },
        "path": "api",
        "protocols": ["https"],
        "isCurrent": false,
        "subscriptionRequired": false
      },
      "resources": []
    }
  ]
}

Let's take a closer look at apiVersionSets.

apiVersionSets
{
  "name": "[concat(parameters('serviceName'), '/', parameters('apiVersionSetName'))]",
  "type": "Microsoft.ApiManagement/service/apiVersionSets",
  "apiVersion": "2019-01-01",
  "properties": {
    "description": "version sets of my apis.",
    "displayName": "[parameters('apiVersionSetName')]",
    "versioningScheme": "Segment"
  }
}

Looking at name, it is expressed as concat(parameters('serviceName'), '/', parameters('apiVersionSetName')). concat is a kind of template function to concatenate strings. See the official document 1 for a description of the template function.

Looking at the argument of concat, serviceName and apiVersionSetName are connected with /. This is because the type of this resource is Microsoft.ApiManagement/service/apiVersionSets, so it is named according to the type hierarchy. Looking at type, it is described as service/apiVersionSet. Correspondingly, the name is also configured as {service name}/{apiVersionSet name}.

versioningScheme specifies how to specify the API version. Three values can be specified: Segment, Query, and Header.

  • Segment: Specify the version in the URL path. e.g. /api/v1/.
  • Query: Specify the version in the query parameter.
  • Header:Specify the version in the header of the request.

Next, take a look at apis.

apis
{
  "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), ';rev=', parameters('apiRevision'))]",
  "type": "Microsoft.ApiManagement/service/apis",
  "apiVersion": "2019-01-01",
  "dependsOn": [
    "[resourceId('Microsoft.ApiManagement/service/apiVersionSets', parameters('serviceName'), parameters('apiVersionSetName'))]"
  ],
  "properties": {
    "description": "my api",
    "displayName": "[parameters('apiDisplayName')]",
    "apiVersionSetId": "[resourceId('Microsoft.ApiManagement/service/apiVersionSets', parameters('serviceName'), parameters('apiVersionSetName'))]",
    "apiVersion": "[parameters('apiVersion')]",
    "apiRevision": "[parameters('apiRevision')]",
    "authenticationSettings": {
      "subscriptionKeyRequired": false
    },
    "path": "api",
    "protocols": ["https"],
    "isCurrent": false,
    "subscriptionRequired": false
  },
  "resources": []
}

name is specified according to the hierarchical structure of type as explained at apiVersionSet. One difference is that the string ;rev={apiRevision} is added. API Management has the concept of revisions, and only one revision is published outside (the published revision is called the current revision). If you deploy an API without specifying this ;rev={apiRevision}, the deployed API becomes the current revision. However, I think that the usual approach is to deploy the revision as a green environment, test it, and then switch it, like Blue/Green deployment. In such a case, instead of directly setting the deployed API as the current revision, it is better to create the revision behind the scenes and switch it as the current revision after necessary tests are passed. By specifying ;rev={apiRevision}, the API can be deployed without becoming the current revision. At this time, don't forget to specify isCurrent in properties as false.

Don't forget to specify dependsOn as well. This is a parameter that defines deployment dependencies. The version cannot be specified in apis if apiVersionSet does not exist first. Therefore, it is necessary to specify the dependency as dependsOn here.

Deploy

Lastly, let's deploy the template above.

deploy
az group deployment create --resource-group <resourceGroupName> --template-file ./apis.json --parameters apiRevision="20191206" apiVersion="v1" serviceName=<serviceName> apiVersionSetName=<versionSetName> apiName=<apiName> apiDisplayName=<displayName>

This will deploy API version v1, revision 20191206. As for the revision, there is no other revision at the time of the first deployment, so it is forcibly deployed as the current revision. However, if you already have a revision, you can deploy it without becoming current.

Summary

This article described how to add versions and revisions to API Management. The point is that by adding ;rev={revision} to the revision name, you can add a revision so that it does not become the current revision.

2019 Copyright Channel.241