Azure API Management 101
Published: 2022-01-07 08:05:40

# Summary
This is a note that walks you through the first step of [Azure Azure API Mamanagement](https://docs.microsoft.com/en-us/azure/api-management/api-management-key-concepts). Here is the code sample of Azure Pipelines Yaml and .NET6.
- [iac-pipeline-apim.yml](https://github.com/koheikawata/network-sample-app/blob/main/azure-devops/iac/iac-pipeline-apim.yml)
- [azuredeploy-apim.json](https://github.com/koheikawata/network-sample-app/blob/main/arm-templates/azuredeploy-apim.json)
- [dotnet-pipeline-travelapi.yml](https://github.com/koheikawata/network-sample-app/blob/main/azure-devops/dotnet/dotnet-pipeline-travelapi.yml)
- [TravelApi (.NET6)](https://github.com/koheikawata/network-sample-app/tree/main/src/TravelApi)

# TOC
- [Architecture](#architecture)
- [Step by Step](#step-by-step)
  - [1. Deploy](#deploy)
  - [2. Extract swagger.json](#extract)
  - [3. Import the API](#import)
  - [4. Test the API (Azure Portal)](#test-api1)
  - [5. Get a subsctiption key](#get-subscription-key)
  - [6. Test the API (Local)](#test-api2)
- [API Management purge](#purge)

# Architecture <a name="architecture"></a>

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nld8mszpxahkl3g7j4z3.png)

# Step by Step <a name="step-by-step"></a>
## Deploy <a name="deploy"></a>
1. Setup `BASE_NAME` and `ENVIRONMENT_SYMBOL` in [variables-template.yml](https://github.com/koheikawata/network-sample-app/blob/main/azure-devops/variables-template.yml)
1. Run Azure pipelines with [iac-pipeline-apim.yml](https://github.com/koheikawata/network-sample-app/blob/main/azure-devops/iac/iac-pipeline-apim.yml)
1. Run Azure pipelines with [dotnet-pipeline-travelapi.yml](https://github.com/koheikawata/network-sample-app/blob/main/azure-devops/dotnet/dotnet-pipeline-travelapi.yml)

## Extract swagger.json <a name="extract"></a>
OpenAPI format in API Management requires [swagger.json] file. You can extract the file by running the app [TravelApi](https://github.com/koheikawata/network-sample-app/tree/main/src/TravelApi) locally. The file location will be like `https://localhost:7228/swagger/v1/swagger.json`

**swagger.json example**
```
{
  "openapi": "3.0.1",
  "info": {
    "title": "TravelApi",
    "version": "1.0"
  },
  "paths": {
    "/TravelPlan": {
      "get": {
        "tags": [
          "TravelPlan"
        ],
        "summary": "Get a list of destinations",
        "description": "Sample request:\r\n            \r\n    GET /travelplan",
        "responses": {
          "400": {
            "description": "Bad Request"
          },
          "401": {
            "description": "Unauthorized"
          },
          "500": {
            "description": "Server Error"
          },
          "503": {
            "description": "Server Error"
          },
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Destination"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Destination": {
        "type": "object",
        "properties": {
          "country": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "food": {
            "type": "string",
            "nullable": true
          },
          "sightSeeing": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      }
    }
  }
}
```
**swagger.json when running locally**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b5m7yeonhg2rktcak0x5.png)

## Import the API <a name="import"></a>
The code sample already includes a `TravelApi` api in ARM template [azuredeploy-apim.json](https://github.com/koheikawata/network-sample-app/blob/main/arm-templates/azuredeploy-apim.json). It does not have the content of API, and you need to import and append swagger.json to it. 

**azuredeploy-apim.json**
```
{
  "type": "Microsoft.ApiManagement/service/apis",
  "apiVersion": "2021-08-01",
  "name": "[concat(variables('apim_name'), '/travelapi')]",
  "dependsOn": [
    "[resourceId('Microsoft.ApiManagement/service', variables('apim_name'))]"
  ],
  "properties": {
    "displayName": "TravelApi",
    "subscriptionRequired": true,
    "serviceUrl": "[variables('apim_service_url')]",
    "protocols": [
      "https"
    ],
    "path": ""
  }
}
```

Go to Azure Portal and the deployed Azure API Management. You will see `TravelApi` is already set by ARM template. You are going to add `swagger.json` here. `APIs` --> `TravelApi` --> Import

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h0pi0gwu7zjdcefug68z.png)

Select `OpenAPI`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kdf5t4ignqj5mtfesowv.png)

Select `swagger.json` extracted in the previous step. Select `Append` and `Postfix`, and `Import`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7qsf934umjr2yeaug1dk.png)

## Test the API (Azure Portal) <a name="test-api1"></a>
Go to API Management --> `APIs` --> `TravelApi` --> `Test` --> `GET /TravelPlan`, and `Send`. You will see the successful response from the deployed App Service.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vbzuxsu0l76g6h674ug4.png)
 
## Get subscription key <a name="get-subscription-key"></a>
In order to test the API from your local machine, you need to get a subscription key to access the API.

Go to API Management --> `Subscriptions` --> `Build-in all-access subscription`, and then keep Primary Key for later usage.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tfqn5rqjcfg54uv8oj7n.png)

## Test the API (Local) <a name="test-api2"></a>
Send HTTP request from the terminal like below.

**Bash example**
```
curl -H "Ocp-Apim-Subscription-Key: {Primary Key}" https://{API Management name}.azure-api.net/travelplan
```

**Example response**
```
[
  {
    "country": "France",
    "city": "Paris",
    "food": "Wine",
    "sightSeeing": "Eiffel Tower"
  },
  {
    "country": "Japan",
    "city": "Tokyo",
    "food": "Ramen",
    "sightSeeing": "Skytree"
  }
]
```

# API Management purge <a name="purge"></a>

According to [the Microsoft official document](https://docs.microsoft.com/en-us/azure/api-management/soft-delete#soft-delete-behavior) as of January 2022, an API Management instance is soft-deleted (Azure Resource Manager API 2020-06-01-preview or later). Retention interval of soft-deleted instance is 48 hours. You can also hard-delete the soft-deleted instance by using [the REST API](https://docs.microsoft.com/en-us/azure/api-management/soft-delete#purge-a-soft-deleted-apim-instance).

**Azure CLI Powershell sample**
```
az rest --method delete --header "Accept=application/json" `
-u 'https://management.azure.com/subscriptions/{Azure Subscription ID}/providers/Microsoft.ApiManagement/locations/{Location}/deletedservices/{API Management name}?api-version=2021-08-01'
```