在Azure API管理器中管理版本化的API

时间:2018-07-09 11:42:00

标签: azure asp.net-core-webapi azure-resource-manager azure-api-management azure-api-apps

我正在考虑使用API​​应用程序在Azure中托管我们的Web API。我正在API应用程序前面使用Azure API管理器,以将开发人员门户暴露给某些消费者。该Web API内置于.NET核心中,并且具有使用URL(https://example.com/api/v2/controller..。)的版本支持。我已经给予了swagger支持,并且为每个版本创建了一个swagger.json。我在ARM模板中使用了这些庞大的文件来设置API管理器并公开此版本化的API。将版本添加到API Manager时,我必须提供一个路径,该路径对于Im Im添加而言必须是唯一的。因此,对于版本v1,我给出“ api / v1”,对于版本v2,我给出“ api / v2”。到目前为止,一切都很好。问题是当尝试使用API​​ Manager调用API时,URL最终变为:https://foo-api-manager-dev.azure-api.net/api/v2/api/v2/tests 因此,我复制了“ api / v2”部分。我想这与API Manager的工作方式以及Web API中的版本控制有关。直接将控制器调用到API App时,URL是正确的。

我进行了很多搜索,并尝试了不同的方法,但是这里确实需要一些输入。感谢所有建议!

我的路由是在基本控制器中管理的,看起来像这样

[Produces("application/json")]
[Route("api/v{version:apiVersion}/[controller]")]
public abstract class VersionBaseController : ApiController
{
    protected VersionBaseController()
       : base()
    {
    }
}

像这样的控制器:

[ApiVersion("2.0")]
public class TestsController : VersionBaseController
{
    [HttpGet]
    public string Get()
    {
        return "Get works V2";
    }

用于创建api管理器的整个模板:

//Create API Manager
{
  "apiVersion": "2018-06-01-preview",
  "name": "[parameters('apim_name')]",
  "location": "[parameters('location')]",
  "type": "Microsoft.ApiManagement/service",
  "sku": {
    "name": "[parameters('apim_tier')]",
    "capacity": 1
  },
  "properties": {
    "publisherEmail": "[parameters('apim_adminEmail')]",
    "publisherName": "[parameters('apim_orgName')]"
  },
  "resources": [
    //Create version set
    {
      "apiVersion": "2017-03-01",
      "type": "Microsoft.ApiManagement/service/api-version-sets",
      "name": "[concat(parameters('apim_name'), '/', parameters('VersionSetName'))]",
      "dependsOn": [
        "[concat('Microsoft.ApiManagement/service/', parameters('apim_name'))]"
      ],
      "properties": {
        "description": "Version configuration",
        "displayName": "Api set 1",
        "versioningScheme": "Segment"
      }
    },
    //Link version 1
    {
      "apiVersion": "2017-03-01",
      "type": "apis",
      "name": "AvidaAPIV1",
      "dependsOn": [
        "[resourceId('Microsoft.ApiManagement/service/api-version-sets', parameters('apim_name'), parameters('VersionSetName'))]",
        "[concat('Microsoft.ApiManagement/service/', parameters('apim_name'))]"
      ],
      "properties": {
        "contentFormat": "swagger-link-json",
        "contentValue": "[concat(parameters('ExternalApiBaseUrl'),'/swagger/v1/swagger.json')]",
        "path": "/api/v1",
        "isCurrent": true,
        "apiVersion": "v1",
        "apiVersionName": "v1",
        "apiVersionDescription": "string",
        "apiVersionSetId": "[concat('Microsoft.ApiManagement/service/api-version-sets', parameters('VersionSetName'))]"
      }
    },
    //Link version 2
    {
      "apiVersion": "2017-03-01",
      "type": "apis",
      "name": "AvidaAPIV2",
      "dependsOn": [
        "[resourceId('Microsoft.ApiManagement/service/api-version-sets', parameters('apim_name'), parameters('VersionSetName'))]",
        "[concat('Microsoft.ApiManagement/service/', parameters('apim_name'))]"
      ],
      "properties": {
        "contentFormat": "swagger-link-json",
        "contentValue": "[concat(parameters('ExternalApiBaseUrl'),'/swagger/v2/swagger.json')]",
        "path": "/api/v2",
        "isCurrent": false,
        "apiVersion": "v2",
        "apiVersionName": "v2",
        "apiVersionDescription": "string",
        "apiVersionSetId": "[concat('Microsoft.ApiManagement/service/api-version-sets', parameters('VersionSetName'))]"
      }
    },
    //Create unlimited product
    {
      "apiVersion": "2017-03-01",
      "type": "products",
      "name": "[concat('UnlimitedProduct', parameters('ProductNameSuffix'))]",
      "dependsOn": [
        "[concat('Microsoft.ApiManagement/service/', parameters('apim_name'))]"
      ],
      "properties": {
        "displayName": "[concat('UnlimitedProduct', parameters('ProductNameSuffix'))]",
        "description": "Unlimited external access",
        "terms": "",
        "subscriptionRequired": false,
        "state": "published"
      },
      "resources": [
        {
          "apiVersion": "2017-03-01",
          "type": "apis",
          "name": "AvidaAPIV1",
          "dependsOn": [
            "[concat('Microsoft.ApiManagement/service/', parameters('apim_name'))]",
            "[concat('Microsoft.ApiManagement/service/', parameters('apim_name'), '/apis/AvidaAPIV1')]",
            //"[concat('Microsoft.ApiManagement/service/', parameters('apim_name'), '/apis/AvidaAPIV2')]",
            "[concat('Microsoft.ApiManagement/service/', parameters('apim_name'), '/products/UnlimitedProduct', parameters('ProductNameSuffix'))]"
          ]
        }
      ]
    }

3 个答案:

答案 0 :(得分:0)

这取决于您配置版本集的方式。最初,Azure APIM中的每个API仅具有URI后缀-即部分路径紧随主机之后以标识被调用的API。当您将API添加到版本集并将此版本集的方案设置为“路径”时,您还需要为每个API指定版本字符串。查看API的设置,应该有一个名为“已识别版本”的字段。该标识符会自动添加到API URL后缀。

因此,假设您有一个后缀为“ httpbin”的API,并将其添加到一个版本集中,并将其版本标识为“ v0”,这意味着可以通过调用https://xxx.xxx/httpbin/v0/来访问此API。

查看您的配置。我觉得您已经将“ api / v1”作为API后缀和版本标识符。尝试将其分为API后缀“ api”和版本标识符“ v1”。

答案 1 :(得分:0)

要能够识别问题,将自动化脚本的api部分包含在内将很有帮助。 通过这种方式,我们可以了解APIM实际用作链接的API版本1和2的ARM模板的方式。

答案 2 :(得分:0)

所以我意识到在APIM中根本没有创建任何版本集: The resulting APIs from my above template scripts

然后,我手动创建了版本集,并在Azure门户中将其链接到我的2张招贴,然后看起来正确: Manually created in portal

但是,即使手动创建版本,URL也存在相同的问题。我需要复制“ api / v2 / api / v2 / [controller]”

现在版本2的设置对我来说似乎是正确的: enter image description here