Conecte el back-end a Azure API Management

Este artículo fue publicado hace más de un año. La información puede estar desactualizada.
Aprenda a usar la ARM Template para agregar API a API Management .
Use recursos como operations , policy y backend para conectar las API a su backend.
En este artículo asumimos que el backend se implementa en las Azure functions .
Definir la API
Primero, configure la definición de API Management en API Management .
En API Management , cada API está definida por un recurso llamado operations .
Definir operations
operations es un recurso correspondiente a una API. Puede definir la ruta de API y los parámetros aquí en este recurso.
Echemos un vistazo a la ARM Template para las operations .
1{2 "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), ';rev=', parameters('apiRevision'), '/', parameters('operationName'))]",3 "type": "Microsoft.ApiManagement/service/apis/operations",4 "apiVersion": "2018-01-01",5 "dependsOn": [6 "[resourceId('Microsoft.ApiManagement/service/apis', parameters('serviceName'), concat(parameters('apiName'), ';rev=', parameters('apiRevision')))]",7 "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), parameters('backendName'))]"8 ],9 "properties": {10 "description": "GET Order",11 "templateParameters": [12 {13 "name": "orderId",14 "type": "string",15 "values": []16 }17 ],18 "responses": [],19 "policies": null,20 "displayName": "GetOrder",21 "method": "GET",22 "urlTemplate": "orders/{orderId}"23 },24 "resources": []25}Tenga en cuenta que el nombre se agrega con rev;={apiRevision} , ya que se implementará como una revisión específica como se menciona en otro artículo 1.
Url se especifica en urlTemplate . Los parámetros variables se expresan en formato {orderId} . Los detalles de los parámetros se describen en templateParameters .
El ejemplo anterior define que el tipo de orderId es una cadena.
Para el method , especifique el Método HTTP.
La API creada a partir del ejemplo anterior será GET http(s)://{API Management FQDN}/api/v1/orders/{orderId} . Lo que definimos esta vez es la parte /orders/{orderId} , y la parte /api/v1 se definió en los apis y apiVersionSets 1.
Puede importar OpenAPI.yaml para definir API. Cubriré eso en un artículo separado.
Definir backends
A continuación, defina los backends .
1{2 "name": "[concat(variables('serviceName'), '/', parameters('backendName'))]",3 "type": "Microsoft.ApiManagement/service/backends",4 "apiVersion": "2018-01-01",5 "dependsOn": [6 "[resourceId('Microsoft.ApiManagement/service/properties', parameters('serviceName'), parameters('propertyName'))]"7 ],8 "properties": {9 "title": null,10 "description": "Backend of API management",11 "url": "[concat('https://', parameters('functionsAppName'),'.azurewebsites.net/api')]",12 "protocol": "http",13 "credentials": {14 "query": {15 "code": ["[concat('{{', parameters('propertyName'), '}}')]"]16 }17 },18 "resourceId": "[concat('https://management.azure.com/subscriptions/', subscription().id, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Web/sites/', parameters('functionsAppName'))]"19 }20}backends son literalmente recursos equivalentes a los servicios de backend que componen la API. Esta vez, asumimos la función HTTPTrigger funciones de Azure functions como back-end.
La url de las Azure functions se especifica en la url , y el recurso de las Azure functions se especifica por resourceId . En este caso, la ruta de HTTPTrigger de las Azure functions de Azure functions debe ser orders/{orderId} .
En las credentials , especifique la clave API para conectarse con las Azure functions . El ejemplo de plantilla anterior significa que las credenciales se especifican en forma de un parámetro de consulta como ?code=xxx , y se establece la cadena de caracteres especificada por propertyName . El valor de las credenciales está en forma de doble cerramiento, como {{credential}} .
Las credenciales como la clave API se almacenan en el recurso de properties que se describe a continuación. El nombre de propertyName especificado aquí es el nombre que indica las credenciales guardadas en las properties .
Por cierto, para especificar la clave API de las Azure functions aquí, debe obtener la clave de las Azure functions .
Es común usar las funciones de Plantilla listSecrets o listKeys para obtener claves en la ARM Template , pero no funciona como se esperaba para las Azure functions v2 2. Es mejor obtenerlo con anticipación usando la Azure CLI 3.
1$resourceId = "/subscriptions/$subscriptionid/resourceGroups/$resourceGroup/providers/Microsoft.Web/sites/$functionsAppName"2$url = "$resourceId/host/default/listKeys?api-version=2016-03-01"3$ret = az rest --method post --uri $url | ConvertFrom-Json4$key = $ret.functionKeys.defaultAzure functions tienen una tecla de host y una tecla de función. En este caso, se usa la clave de host. En pocas palabras, la tecla de función es una tecla para cada función, y la tecla de host es una tecla que se puede conectar a todas las funciones.
Para conectar las API con el back-end, también debe especificar el back-end en la policy .
Definir policy
Finalmente, establezca una policy para conectar backend y API Management.
Policy es una característica importante que puede agregar varios procesamientos a API Management .
Aquí usamos uno de ellos para conectarse al backend.
1{2 "variables": {3 "backendPolicy": "[concat('<policies>\r\n <inbound>\r\n <base />\r\n <set-backend-service id=\"apim-generated-', 'policy','\" backend-id=\"', parameters('backendName'), '\" />\r\n </inbound>\r\n <backend>\r\n <base />\r\n </backend>\r\n <outbound>\r\n <base />\r\n </outbound>\r\n <on-error>\r\n <base />\r\n </on-error>\r\n</policies>')]"4 },5 "resources": [6 {7 "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), ';rev=', parameters('apiRevision'), '/', 'policy')]",8 "type": "Microsoft.ApiManagement/service/apis/policies",9 "apiVersion": "2018-01-01",10 "properties": {11 "policyContent": "[variables('backendPolicy')]",12 "contentFormat": "xml"13 }14 }15 ]16}policy se especifica en xml en policyContent . backendPolicy se define en variables y puede ver que la cadena xml está definida.
El punto es que el recurso backend está especificado por backend-id .
Como resultado, el recurso de fondo creado anteriormente se especifica en la policy .
Definir properties
properties es un recurso para guardar el valor de configuración utilizado en API Management en formato clave-valor. Aquí, utilizaremos este recurso para mantener la clave API para conectarse a las funciones de fondo azul.
1{2 "type": "Microsoft.ApiManagement/service/properties",3 "name": "[concat(parameters('serviceName'), '/', parameters('propertyName'))]",4 "apiVersion": "2018-06-01-preview",5 "scale": null,6 "properties": {7 "displayName": "[parameters('propertyName')]",8 "value": "[parameters('functionHostKey')]",9 "tags": ["key", "function"],10 "secret": true11 }12}Sustituya displayName con el nombre de la propiedad que especificó anteriormente en backends.
Especifique un valor secreto para el value . En este caso, especifique la clave API de las Azure functions obtenidas anteriormente con la Azure CLI .
tags es una etiqueta para usar cuando se buscan propiedades más adelante. Especifiquemos una cadena de caracteres arbitraria.
Al establecer el secret en true , la propiedad se cifrará y se mantendrá segura.
Desplegar
Entonces, implementemos la ARM Template basada en lo que hemos explicado hasta ahora.
1{2 "$schema": "https://schema.management.azure.com/schemas/2018-05-01/deploymentTemplate.json#",3 "contentVersion": "1.0.0.0",4 "parameters": {5 "serviceName": {6 "type": "string",7 "metadata": {8 "description": "Service Name"9 }10 },11 "apiName": {12 "type": "string",13 "metadata": {14 "description": "API Name"15 }16 },17 "apiRevision": {18 "type": "string",19 "metadata": {20 "description": "API Revision"21 }22 },23 "operationName": {24 "type": "string",25 "metadata": {26 "description": "Operation name"27 }28 },29 "backendName": {30 "type": "string",31 "metadata": {32 "description": "Backend Name"33 }34 },35 "functionHostKey": {36 "type": "securestring",37 "metadata": {38 "description": "Host key for the functions app"39 }40 },41 "functionAppName": {42 "type": "string",43 "metadata": {44 "description": "Functions App Name"45 }46 },47 "propertyName": {48 "type": "string",49 "metadata": {50 "description": "Property Name"51 }52 }53 },54 "variables": {55 "backendPolicy": "[concat('<policies>\r\n <inbound>\r\n <base />\r\n <set-backend-service id=\"apim-generated-', 'policy','\" backend-id=\"', parameters('backendName'), '\" />\r\n </inbound>\r\n <backend>\r\n <base />\r\n </backend>\r\n <outbound>\r\n <base />\r\n </outbound>\r\n <on-error>\r\n <base />\r\n </on-error>\r\n</policies>')]"56 },57 "resources": [58 {59 "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), ';rev=', parameters('apiRevision'), '/', parameters('operationName'))]",60 "type": "Microsoft.ApiManagement/service/apis/operations",61 "apiVersion": "2019-01-01",62 "dependsOn": [63 "[resourceId('Microsoft.ApiManagement/service/backends', parameters('serviceName'), parameters('backendName'))]"64 ],65 "properties": {66 "description": "GET Order",67 "templateParameters": [68 {69 "name": "orderId",70 "type": "string",71 "values": []72 }73 ],74 "responses": [],75 "policies": null,76 "displayName": "GetOrder",77 "method": "GET",78 "urlTemplate": "orders/{orderId}"79 },80 "resources": []81 },82 {83 "name": "[concat(parameters('serviceName'), '/', parameters('apiName'), ';rev=', parameters('apiRevision'), '/', 'policy')]",84 "type": "Microsoft.ApiManagement/service/apis/policies",85 "apiVersion": "2018-01-01",86 "properties": {87 "policyContent": "[variables('backendPolicy')]",88 "contentFormat": "xml"89 }90 },91 {92 "name": "[concat(parameters('serviceName'), '/', parameters('backendName'))]",93 "type": "Microsoft.ApiManagement/service/backends",94 "apiVersion": "2018-01-01",95 "dependsOn": [96 "[resourceId('Microsoft.ApiManagement/service/properties', parameters('serviceName'), parameters('propertyName'))]"97 ],98 "properties": {99 "title": null,100 "description": "Backend of API management",101 "url": "[concat('https://', parameters('functionAppName'),'.azurewebsites.net/api')]",102 "protocol": "http",103 "credentials": {104 "query": {105 "code": ["[concat('{{', parameters('propertyName'), '}}')]"]106 }107 },108 "resourceId": "[concat('https://management.azure.com/subscriptions/', subscription().id, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Web/sites/', parameters('functionAppName'))]"109 }110 },111 {112 "type": "Microsoft.ApiManagement/service/properties",113 "name": "[concat(parameters('serviceName'), '/', parameters('propertyName'))]",114 "apiVersion": "2018-06-01-preview",115 "scale": null,116 "properties": {117 "displayName": "[parameters('propertyName')]",118 "value": "[parameters('functionHostKey')]",119 "tags": ["key", "function"],120 "secret": true121 }122 }123 ]124}Ahora la API se puede implementar en la instancia de servicio utilizando la plantilla anterior.

