azure-functions-openapi-extension icon indicating copy to clipboard operation
azure-functions-openapi-extension copied to clipboard

[Draft] Add support for multiple HTTP verbs in one Function

Open tevoinea opened this issue 2 years ago • 0 comments

I'm opening this PR to gauge interest in supporting the scenario discussed in #68. It's in a draft state because it was written to demonstrate a proof of concept.

Here is an example of what this PR enables:

    [OpenApiOperation(operationId: "containerOperations", tags: new[] { "container" }, Summary = "Operations on containers", Description = "Operations on containers", Visibility = OpenApiVisibilityType.Important)]
    //GetOperations
    [OpenApiRequestBody(verb: "Get", contentType: "application/json", bodyType: typeof(ContainerGet), Required = true, Description = "Container to get")]
    [OpenApiResponseWithBody(verb: "Get", statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(ContainerGet), Description = "Gets container info")]
    [OpenApiResponseWithoutBody(verb: "Get", statusCode: HttpStatusCode.BadRequest, Summary = "Invalid container supplied", Description = "Invalid container supplied")]
    //DeleteOperations
    [OpenApiRequestBody(verb: "Delete", contentType: "application/json", bodyType: typeof(ContainerDelete), Required = true, Description = "Container to delete")]
    [OpenApiResponseWithBody(verb: "Delete", statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(ContainerInfo), Description = "Deletes container")]
    [OpenApiResponseWithoutBody(verb: "Delete", statusCode: HttpStatusCode.BadRequest, Summary = "Invalid container supplied", Description = "Invalid container supplied")]
    //PostOperations
    [OpenApiRequestBody(verb: "Post", contentType: "application/json", bodyType: typeof(ContainerCreate), Required = true, Description = "Container to create")]
    [OpenApiResponseWithBody(verb: "Post", statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(ContainerInfo), Description = "Created container")]
    [OpenApiResponseWithoutBody(verb: "Post", statusCode: HttpStatusCode.BadRequest, Summary = "Invalid container supplied", Description = "Invalid container supplied")]
    [Function("Containers")]
    public Async.Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Anonymous, "GET", "POST", "DELETE")] HttpRequestData req)
        => _auth.CallIfUser(req, r => r.Method switch {
            "GET" => Get(r),
            "POST" => Post(r),
            "DELETE" => Delete(r),
            _ => throw new NotSupportedException(),
        });

The 'core' of the changes can be found in:

  • src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Document.cs
  • src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Extensions/DocumentHelperExtensions.cs
  • src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IDocumentHelper.cs
  • src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Attributes/
  • src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/DocumentHelper.cs
  • src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/DocumentHelperExtensions.cs
  • src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/DocumentHelperExtensions.cs
  • src/Microsoft.Azure.WebJobs.Extensions.OpenApi/Document.cs

Some notable callouts:

  • It is a breaking change -- many of the attributes would required a Verb property to be set
  • Some tests are still broken

tevoinea avatar Mar 29 '23 18:03 tevoinea