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
.
{
"$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
.
{
"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
.
{
"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.
Lastly, let's deploy the template above.
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.
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.