1
votes

so I have fiddled around a bit with Azure API Management Portal. I have followed the tutorial on how the import the conference api and managed to get it to work.

Then I created a WebApi app that uses swagger. My configuration is as follows:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
    });
    ...
}
public void Configure(IApplicationBuilder app,
    IServiceProvider services, 
    IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

    app.UseSwagger();

    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "Address Service API");
    });

    app.UseHttpsRedirection();
    app.UseMvc();
}

If I run this and navigate to https://my-api/swagger, I can see the swagger UI and I can also see the specification when I click on the link on the swagger UI or visit the url https://my-api.azurewebsites.net/swagger/v1/swagger.json

So my problem is, I have no idea on how to actually import this into AAMP. I can publish it to a app service and it works from there, but if I try to import the url https://my-api.azurewebsites.net/swagger/v1/swagger.json into the AAMP, I get an error:

enter image description here

So I wait an hour and try again, only the be greeted by the same error and I think I am missing something because when I imported the conference api specification, it had a different url than mine, yet I cannot find anything or I am searching for the wrong things. Can anybody please give me a heads up here?

I have also tried searching for the sources of the conference API so I can deduct what I am doing wrong but I didn't have any luck on finding those.

1

1 Answers

0
votes

Importing Swagger document into APIM is pretty straight forward by following this Azure document. There’s no issue when you import Swagger 1.2 documents. However, if you’re intending to import Swagger 2.0 ones, you might be facing these kind of issue

If you’re building an API app with .NET Framework 4.5+, using Swashbuckle library, it would be fine. However, if you’re building the app with ASP.NET Core, it does bring you a headache. Firstly, look at your Startup.cs file. The ConfigureService method looks like:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    ...

    services.AddSwaggerGen();

    services.ConfigureSwaggerDocument(
        options =>
        {
            options.SingleApiVersion(new Info() { Version = "v1", Title = "Swagger UI" });
            options.IgnoreObsoleteActions = true;
            options.OperationFilter(new ApplyXmlActionComments(GetXmlPath(appEnv)));
        });

    services.ConfigureSwaggerSchema(
        options =>
        {
            options.DescribeAllEnumsAsStrings = true;
            options.IgnoreObsoleteProperties = true;
            options.CustomSchemaIds(type => type.FriendlyId(true));
            options.ModelFilter(new ApplyXmlTypeComments(GetXmlPath(appEnv)));
        });

    ...
}

private static string GetXmlPath(IApplicationEnvironment appEnv)
{
    var assembly = typeof(Startup).GetTypeInfo().Assembly;
    var assemblyName = assembly.GetName().Name;

    var path = $@"{appEnv.ApplicationBasePath}\{assemblyName}.xml";
    if (File.Exists(path))
    {
        return path;
    }

    var config = appEnv.Configuration;
    var runtime = $"{appEnv.RuntimeFramework.Identifier.ToLower()}{appEnv.RuntimeFramework.Version.ToString().Replace(".", string.Empty)}";
    path = $@"{appEnv.ApplicationBasePath}\..\..\artifacts\bin\{assemblyName}\{config}\{runtime}\{assemblyName}.xml";
    return path;
}

In addition to this, the Configure method might look like:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseSwaggerGen();
    app.UseSwaggerUi();

    ...
}

Wen need to include two additional properties – host and schemes. Swagger specification clearly declares that both are NOT required. However, APIM DOES require both properties to be included in the swagger.json document.

So, how can we sort this out?

For your app in .NET 4.5+, just make sure that your SwaggerConfig.cs has activated those options with proper settings:

SwaggerDocsConfig.Schemes(new[] { “http”, “https” });
SwaggerDocsConfig.RootUrl(req => GetRootUrlFromAppConfig());

In your ASP.NET Core app, it might be tricky as you should implement the IDocumentFilter interface. Here’s a sample code:

  public class SchemaDocumentFilter : IDocumentFilter
    {
      public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
      {
        swaggerDoc.Host = "localhost:44321";
        swaggerDoc.BasePath = "/";
        swaggerDoc.Schemes = new List<string>() { "https" };
      }
    }

And this SchemaDocumentFilter should be added into your ConfigureService method in Startup.cs:

public static void ConfigureServices(this IServiceCollection services)
{
  ...

  services.AddSwaggerGen();

  services.ConfigureSwaggerDocument(
    options =>
      {
        options.SingleApiVersion(new Info() { Version = "v1", Title = "Swagger UI" });
        options.IgnoreObsoleteActions = true;
        options.OperationFilter(new ApplyXmlActionComments(GetXmlPath(appEnv)));

        options.DocumentFilter<SchemaDocumentFilter>();
      });

  services.ConfigureSwaggerSchema(
    options =>
      {
        options.DescribeAllEnumsAsStrings = true;
        options.IgnoreObsoleteProperties = true;
        options.CustomSchemaIds(type => type.FriendlyId(true));
        options.ModelFilter(new ApplyXmlTypeComments(GetXmlPath(appEnv)));
      });

  ...
}

Once you complete this, then import your swagger.json to APIM then it should work.

Reference:

Hope it helps.