yotiky Tech Blog

とあるエンジニアの備忘録

Azure Functions で Swagger UI

NSwag は NSwag.SwaggerGeneration.AzureFunctionsV2 が更新されておらず、V3ではエラーが出て動かなかったため、Swashbuckle を使用する。

目次

検証環境

  • Azure Functions v3
  • AzureExtensions.Swashbuckle v3.2.2

古いライブラリに注意

  • AzureFunctions.Extensions.Swashbuckle は更新されておらずエラーが出て動かない

github.com

実装

NuGet でライブラリをインストールする。

Statup クラスを追加する。

using AzureFunctions.Extensions.Swashbuckle;
...

[assembly: FunctionsStartup(typeof(Startup))]

namespace FunctionApp1
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.AddSwashBuckle(Assembly.GetExecutingAssembly());
        }
    }
}

Open API と Swagger UI の Functions を追加する。

public static class SwaggerFunctions
{
    [SwaggerIgnore]
    [FunctionName("Swagger")]
    public static Task<HttpResponseMessage> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", Route = "Swagger/json")] HttpRequestMessage req,
        [SwashBuckleClient] ISwashBuckleClient swashBuckleClient)
    {
        return Task.FromResult(swashBuckleClient.CreateSwaggerDocumentResponse(req));
    }

    [SwaggerIgnore]
    [FunctionName("SwaggerUi")]
    public static Task<HttpResponseMessage> Run2(
        [HttpTrigger(AuthorizationLevel.Function, "get", Route = "Swagger/ui")] HttpRequestMessage req,
        [SwashBuckleClient] ISwashBuckleClient swashBuckleClient)
    {
        return Task.FromResult(swashBuckleClient.CreateSwaggerUIResponse(req, "swagger/json"));
    }
}

対象の Functions に属性をつける。

public class Function1
{
    [QueryStringParameter("name", "User Name", DataType = typeof(string), Required = false)]
    [ProducesResponseType(typeof(string), (int)HttpStatusCode.OK)]
    [ProducesResponseType((int)HttpStatusCode.InternalServerError, Type = typeof(Error))]
    [FunctionName("Function1")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
        ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        string name = req.Query["name"];

        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);
        name = name ?? data?.name;

        string responseMessage = string.IsNullOrEmpty(name)
            ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
            : $"Hello, {name}. This HTTP triggered function executed successfully.";

        return new OkObjectResult(responseMessage);
    }
}
public class Error
{
    public string Title { get; set; }

    public string Description { get; set; }
}

http://localhost:7071/api/Swagger/ui で Swagger UI にアクセス。

f:id:yotiky:20210224092449p:plain

参考

ASP.NET Core の場合に参考になりそうな記事。