.NET 5 Support of Azure Functions OpenAPI Extension

Published Aug 15 2021 05:00 PM 4,292 Views
Microsoft

In May this year at //Build, Azure Functions OpenAPI support feature (preview) was officially announced. At that time, it supported up to the v3 runtime – .NET Core 3.1 version. Recently, it has released .NET 5 isolated worker supporting package as a preview. Throughout this post, I'm going to review how to use it and deploy it to Azure.

 

NOTE: You can find the sample code used in this post at this GitHub repository: https://github.com/justinyoo/azfunc-openapi-dotnet

 

Creating Azure Functions App in .NET 5

 

Let's use Visual Studio for this exercise. While creating the app, use the ".NET 5 (Isolated)" runtime and "Http trigger".

 

Choose .NET 5 (Isolated) then Http trigger

 

Then you'll find out the HTTP endpoint with default codes. Now, select the NuGet Package Manager menu at Solution Explorer.

 

Select NuGet Package Manager menu

 

In the NuGet Package Manager screen, tick the "Include prerelease" checkbox and search up the Microsoft.Azure.Functions.Worker.Extensions.OpenApi package. As of this writing, the NuGet packager version is v0.8.1-preview.

 

Search up the OpenAPI extension in the NuGet Package Manager screen

 

OpenAPI extension has now been installed.

 

Configuring HostBuilder

 

After installing the OpenAPI extension, let's configure the HostBuilder. First, open the Program.cs file and remove the existing ConfigureFunctionsWorkerDefaults() method. It's because this method uses System.Text.Json by default, which we're not going to use.

 

    public static void Main()
    {
        var host = new HostBuilder()
            // 👇👇👇👇👇 Remove this line below 👇👇👇👇👇
            .ConfigureFunctionsWorkerDefaults()
            // 👆👆👆👆👆 Remove this line above 👆👆👆👆👆
            .Build();
    
        host.Run();
    }

 

Then, add both ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson()) and ConfigureOpenApi() method in this order. The first method explicitly declares to use the Newtonsoft.Json package and the next one imports the additional OpenAPI related endpoints.

 

    public static void Main()
    {
        var host = new HostBuilder()
            // 👇👇👇👇👇 Add these lines below 👇👇👇👇👇
            .ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson())
            .ConfigureOpenApi()
            // 👆👆👆👆👆 Add these lines above 👆👆👆👆👆
            .Build();
    
        host.Run();
    }

 

NOTE: Currently, using System.Text.Json doesn't guarantee whether the app works appropriately or not. Therefore, Newtonsoft.Json is highly recommended.

 

Now, the configuration is over. Let's move on.

 

Adding OpenAPI Decorators

 

Add OpenAPI related decorators like below. It's precisely the same exercise as the existing approach, so I'm not going too deep.

 

    // 👇👇👇👇👇 Add OpenAPI related decorators below 👇👇👇👇👇
    [OpenApiOperation(operationId: "greeting", tags: new[] { "greeting" }, Summary = "Greetings", Description = "This shows a welcome message.", Visibility = OpenApiVisibilityType.Important)]
    [OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
    [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "text/plain", bodyType: typeof(string), Summary = "The response", Description = "This returns the response")]
    // 👆👆👆👆👆 Add OpenAPI related decorators above 👆👆👆👆👆
    
    [Function("Function1")]
    public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
        FunctionContext executionContext)
    {
        ...
    }

 

Once you complete adding the decorators, you're all done! Let's run the app.

 

Running Swagger UI

 

Run the Function app by entering the F5 key or clicking the debug button on Visual Studio.

 

Run Azure Function app with the debug mode

 

You'll see the OpenAPI related endpoints added in the console.

 

OpenAPI related endpoints added

 

Run the http://localhost:7071/api/swagger/ui endpoint on your web browser, and you'll see the Swagger UI page.

 

Swagger UI page

 

Your Azure Function app with OpenAPI capability has now been implemented correctly.

 

Deploying Azure Function App – Windows

 

You confirmed that your Azure Function app is working fine. It's time for deployment. First of all, click the "Publish" menu at Solution Explorer.

 

Azure Functions publish menu

 

Choose "Azure", followed by "Azure Functions App (Windows)".

 

Choose deployment method for Windows

 

You can use the existing Function app instance or create a new one by clicking the :heavy_plus_sign: button. This time, let's use the current instance.

 

Choose existing instance

 

Once deployment is done, open the Azure Functions URL on your web browser, and you'll see the Swagger UI page.

 

Swagger UI on Azure

 

Deploying Azure Function App – Linux

 

This time, let's deploy the same app to the Linux instance. In addition to that, let's use GitHub Actions. In order to do so, you must upload this app to a GitHub repository. So, move to the "Git Changes" pane and create a Git repository.

 

Git Changes pane

 

If you've already logged in to GitHub within Visual Studio, you'll be able to create a repository and push the codes.

 

Create GitHub repository

 

Once pushed all codes, visit GitHub to check your repository whether all codes have actually been uploaded.

 

Complete creating GitHub repository

 

Let's go back to the publish screen and click the ":heavy_plus_sign: New" button to create a new publish profile.

 

New publish profile

 

Then a similar pop-up appears to before. This time let's use the "Azure Function App (Linux)" menu.

 

Choose the deployment method for Linux

 

As mentioned before, you can use an existing instance or create a new one. Let's use the existing one.

 

Choose existing instance

 

In the previous deployment exercise, we haven't got a GitHub repository. Therefore, we had to use the local deployment method. But this time, we've got the GitHub repository, meaning we've got choices. Therefore, instead of choosing the same deployment method, let's choose GitHub Actions for this time.

 

Choose GitHub Actions

 

GitHub Actions workflow has now been automatically generated. But this needs a new commit.

 

GitHub Actions commit & push

 

Move to the "Git Changes" pane, enter the commit message like below, click the "Commit All" button, and push the change.

 

Commit & push the GitHub Actions workflow

 

When you actually visit your GitHub repository, your GitHub Actions workflow runs the build and deployment.

 

Deploying Function app with GitHub Actions

 

Once the deployment is over, open a new web browser, visit the Azure Functions app URL, and find out the Swagger UI page is correctly rendered.

 

Swagger UI on Azure

 


 

So far, we've walked through how to create an OpenAPI enabled Azure Functions app, running on .NET 5 isolated worker environment, and deploy it to Azure without having to leave Visual Studio. I'm guessing that it will run OK on .NET 6, theoretically. If you're curious, please deploy it and let us know at https://github.com/Azure/azure-functions-openapi-extension/issues!

 

Call to Action

 

 


 

This article was originally published on Dev Kimchi.

%3CLINGO-SUB%20id%3D%22lingo-sub-2647383%22%20slang%3D%22en-US%22%3E.NET%205%20Support%20of%20Azure%20Functions%20OpenAPI%20Extension%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2647383%22%20slang%3D%22en-US%22%3E%3CP%3EIn%20May%20this%20year%20at%20%3CA%20href%3D%22https%3A%2F%2Fmybuild.microsoft.com%2Fhome%3FWT.mc_id%3Ddotnet-38365-juyoo%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3E%2F%2FBuild%3C%2FA%3E%2C%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fazure%2Fazure-functions%2Ffunctions-overview%3FWT.mc_id%3Ddotnet-38365-juyoo%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EAzure%20Functions%3C%2FA%3E%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FAzure%2Fazure-functions-openapi-extension%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EOpenAPI%20support%20feature%20(preview)%3C%2FA%3E%20was%20%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fapps-on-azure%2Fcreate-and-publish-openapi-enabled-azure-functions-with-visual%2Fba-p%2F2381067%3FWT.mc_id%3Ddotnet-38365-juyoo%22%20target%3D%22_blank%22%3Eofficially%20announced%3C%2FA%3E.%20At%20that%20time%2C%20it%20supported%20up%20to%20the%20v3%20runtime%20%E2%80%93%20.NET%20Core%203.1%20version.%20Recently%2C%20it%20has%20released%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FAzure%2Fazure-functions-openapi-extension%2Freleases%2Ftag%2Fv0.8.1-preview%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3E.NET%205%20isolated%20worker%20supporting%20package%3C%2FA%3E%20as%20a%20preview.%20Throughout%20this%20post%2C%20I'm%20going%20to%20review%20how%20to%20use%20it%20and%20deploy%20it%20to%20Azure.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CBLOCKQUOTE%3E%0A%3CP%3ENOTE%3A%20You%20can%20find%20the%20sample%20code%20used%20in%20this%20post%20at%20this%20GitHub%20repository%3A%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fjustinyoo%2Fazfunc-openapi-dotnet%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgithub.com%2Fjustinyoo%2Fazfunc-openapi-dotnet%3C%2FA%3E%3C%2FP%3E%0A%3C%2FBLOCKQUOTE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId--381911193%22%20id%3D%22toc-hId--381193506%22%3ECreating%20Azure%20Functions%20App%20in%20.NET%205%3C%2FH2%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ELet's%20use%20%3CA%20href%3D%22https%3A%2F%2Fvisualstudio.microsoft.com%2F%3FWT.mc_id%3Ddotnet-38365-juyoo%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EVisual%20Studio%3C%2FA%3E%20for%20this%20exercise.%20While%20creating%20the%20app%2C%20use%20the%20%22.NET%205%20(Isolated)%22%20runtime%20and%20%22Http%20trigger%22.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-01.png%22%20border%3D%220%22%20alt%3D%22Choose%20.NET%205%20(Isolated)%20then%20Http%20trigger%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThen%20you'll%20find%20out%20the%20HTTP%20endpoint%20with%20default%20codes.%20Now%2C%20select%20the%20NuGet%20Package%20Manager%20menu%20at%20Solution%20Explorer.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-02.png%22%20border%3D%220%22%20alt%3D%22Select%20NuGet%20Package%20Manager%20menu%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIn%20the%20NuGet%20Package%20Manager%20screen%2C%20tick%20the%20%22Include%20prerelease%22%20checkbox%20and%20search%20up%20the%3CCODE%3EMicrosoft.Azure.Functions.Worker.Extensions.OpenApi%3C%2FCODE%3Epackage.%20As%20of%20this%20writing%2C%20the%20NuGet%20packager%20version%20is%3CCODE%3Ev0.8.1-preview%3C%2FCODE%3E.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-03.png%22%20border%3D%220%22%20alt%3D%22Search%20up%20the%20OpenAPI%20extension%20in%20the%20NuGet%20Package%20Manager%20screen%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EOpenAPI%20extension%20has%20now%20been%20installed.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId-2105601640%22%20id%3D%22toc-hId-2106319327%22%3EConfiguring%20HostBuilder%3C%2FH2%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAfter%20installing%20the%20OpenAPI%20extension%2C%20let's%20configure%20the%3CCODE%3EHostBuilder%3C%2FCODE%3E.%20First%2C%20open%20the%3CCODE%3EProgram.cs%3C%2FCODE%3Efile%20and%20remove%20the%20existing%3CCODE%3EConfigureFunctionsWorkerDefaults()%3C%2FCODE%3Emethod.%20It's%20because%20this%20method%20uses%3CCODE%3ESystem.Text.Json%3C%2FCODE%3Eby%20default%2C%20which%20we're%20not%20going%20to%20use.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3E%20%20%20%20public%20static%20void%20Main()%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20var%20host%20%3D%20new%20HostBuilder()%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%20Remove%20this%20line%20below%20%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20.ConfigureFunctionsWorkerDefaults()%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%20Remove%20this%20line%20above%20%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20.Build()%3B%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20host.Run()%3B%0A%20%20%20%20%7D%0A%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThen%2C%20add%20both%3CCODE%3EConfigureFunctionsWorkerDefaults(worker%20%3D%26gt%3B%20worker.UseNewtonsoftJson())%3C%2FCODE%3Eand%3CCODE%3EConfigureOpenApi()%3C%2FCODE%3Emethod%20in%20this%20order.%20The%20first%20method%20explicitly%20declares%20to%20use%20the%3CCODE%3ENewtonsoft.Json%3C%2FCODE%3Epackage%20and%20the%20next%20one%20imports%20the%20additional%20OpenAPI%20related%20endpoints.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3E%20%20%20%20public%20static%20void%20Main()%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20var%20host%20%3D%20new%20HostBuilder()%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%20Add%20these%20lines%20below%20%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20.ConfigureFunctionsWorkerDefaults(worker%20%3D%26gt%3B%20worker.UseNewtonsoftJson())%0A%20%20%20%20%20%20%20%20%20%20%20%20.ConfigureOpenApi()%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%20Add%20these%20lines%20above%20%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20.Build()%3B%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20host.Run()%3B%0A%20%20%20%20%7D%0A%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CBLOCKQUOTE%3E%0A%3CP%3E%3CSTRONG%3ENOTE%3C%2FSTRONG%3E%3A%20Currently%2C%20using%3CCODE%3ESystem.Text.Json%3C%2FCODE%3Edoesn't%20guarantee%20whether%20the%20app%20works%20appropriately%20or%20not.%20Therefore%2C%3CCODE%3ENewtonsoft.Json%3C%2FCODE%3Eis%20highly%20recommended.%3C%2FP%3E%0A%3C%2FBLOCKQUOTE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ENow%2C%20the%20configuration%20is%20over.%20Let's%20move%20on.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId-298147177%22%20id%3D%22toc-hId-298864864%22%3EAdding%20OpenAPI%20Decorators%3C%2FH2%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAdd%20OpenAPI%20related%20decorators%20like%20below.%20It's%20precisely%20the%20same%20exercise%20as%20the%20existing%20approach%2C%20so%20I'm%20not%20going%20too%20deep.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3E%20%20%20%20%2F%2F%20%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%20Add%20OpenAPI%20related%20decorators%20below%20%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%3Abackhand_index_pointing_down%3A%3C%2Fimg%3E%0A%20%20%20%20%5BOpenApiOperation(operationId%3A%20%22greeting%22%2C%20tags%3A%20new%5B%5D%20%7B%20%22greeting%22%20%7D%2C%20Summary%20%3D%20%22Greetings%22%2C%20Description%20%3D%20%22This%20shows%20a%20welcome%20message.%22%2C%20Visibility%20%3D%20OpenApiVisibilityType.Important)%5D%0A%20%20%20%20%5BOpenApiSecurity(%22function_key%22%2C%20SecuritySchemeType.ApiKey%2C%20Name%20%3D%20%22code%22%2C%20In%20%3D%20OpenApiSecurityLocationType.Query)%5D%0A%20%20%20%20%5BOpenApiResponseWithBody(statusCode%3A%20HttpStatusCode.OK%2C%20contentType%3A%20%22text%2Fplain%22%2C%20bodyType%3A%20typeof(string)%2C%20Summary%20%3D%20%22The%20response%22%2C%20Description%20%3D%20%22This%20returns%20the%20response%22)%5D%0A%20%20%20%20%2F%2F%20%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%20Add%20OpenAPI%20related%20decorators%20above%20%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%3Abackhand_index_pointing_up%3A%3C%2Fimg%3E%0A%20%20%20%20%0A%20%20%20%20%5BFunction(%22Function1%22)%5D%0A%20%20%20%20public%20static%20HttpResponseData%20Run(%5BHttpTrigger(AuthorizationLevel.Function%2C%20%22get%22%2C%20%22post%22)%5D%20HttpRequestData%20req%2C%0A%20%20%20%20%20%20%20%20FunctionContext%20executionContext)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20...%0A%20%20%20%20%7D%0A%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EOnce%20you%20complete%20adding%20the%20decorators%2C%20you're%20all%20done!%20Let's%20run%20the%20app.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId--1509307286%22%20id%3D%22toc-hId--1508589599%22%3ERunning%20Swagger%20UI%3C%2FH2%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ERun%20the%20Function%20app%20by%20entering%20the%3CCODE%3EF5%3C%2FCODE%3Ekey%20or%20clicking%20the%20debug%20button%20on%20%3CA%20href%3D%22https%3A%2F%2Fvisualstudio.microsoft.com%2F%3FWT.mc_id%3Ddotnet-38365-juyoo%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EVisual%20Studio%3C%2FA%3E.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-04.png%22%20border%3D%220%22%20alt%3D%22Run%20Azure%20Function%20app%20with%20the%20debug%20mode%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EYou'll%20see%20the%20OpenAPI%20related%20endpoints%20added%20in%20the%20console.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-05.png%22%20border%3D%220%22%20alt%3D%22OpenAPI%20related%20endpoints%20added%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ERun%20the%3CCODE%3E%3CA%20href%3D%22http%3A%2F%2Flocalhost%3A7071%2Fapi%2Fswagger%2Fui%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3Ehttp%3A%2F%2Flocalhost%3A7071%2Fapi%2Fswagger%2Fui%3C%2FA%3E%3C%2FCODE%3Eendpoint%20on%20your%20web%20browser%2C%20and%20you'll%20see%20the%20Swagger%20UI%20page.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-06.png%22%20border%3D%220%22%20alt%3D%22Swagger%20UI%20page%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EYour%20Azure%20Function%20app%20with%20OpenAPI%20capability%20has%20now%20been%20implemented%20correctly.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId-978205547%22%20id%3D%22toc-hId-978923234%22%3EDeploying%20Azure%20Function%20App%20%E2%80%93%20Windows%3C%2FH2%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EYou%20confirmed%20that%20your%20Azure%20Function%20app%20is%20working%20fine.%20It's%20time%20for%20deployment.%20First%20of%20all%2C%20click%20the%20%22Publish%22%20menu%20at%20Solution%20Explorer.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-07.png%22%20border%3D%220%22%20alt%3D%22Azure%20Functions%20publish%20menu%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EChoose%20%22Azure%22%2C%20followed%20by%20%22Azure%20Functions%20App%20(Windows)%22.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-08.png%22%20border%3D%220%22%20alt%3D%22Choose%20deployment%20method%20for%20Windows%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EYou%20can%20use%20the%20existing%20Function%20app%20instance%20or%20create%20a%20new%20one%20by%20clicking%20the%20%3Aheavy_plus_sign%3A%20button.%20This%20time%2C%20let's%20use%20the%20current%20instance.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-09.png%22%20border%3D%220%22%20alt%3D%22Choose%20existing%20instance%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EOnce%20deployment%20is%20done%2C%20open%20the%20Azure%20Functions%20URL%20on%20your%20web%20browser%2C%20and%20you'll%20see%20the%20Swagger%20UI%20page.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-10.png%22%20border%3D%220%22%20alt%3D%22Swagger%20UI%20on%20Azure%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId--829248916%22%20id%3D%22toc-hId--828531229%22%3EDeploying%20Azure%20Function%20App%20%E2%80%93%20Linux%3C%2FH2%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThis%20time%2C%20let's%20deploy%20the%20same%20app%20to%20the%20Linux%20instance.%20In%20addition%20to%20that%2C%20let's%20use%20GitHub%20Actions.%20In%20order%20to%20do%20so%2C%20you%20must%20upload%20this%20app%20to%20a%20GitHub%20repository.%20So%2C%20move%20to%20the%20%22Git%20Changes%22%20pane%20and%20create%20a%20Git%20repository.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-11.png%22%20border%3D%220%22%20alt%3D%22Git%20Changes%20pane%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIf%20you've%20already%20logged%20in%20to%20GitHub%20within%20%3CA%20href%3D%22https%3A%2F%2Fvisualstudio.microsoft.com%2F%3FWT.mc_id%3Ddotnet-38365-juyoo%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EVisual%20Studio%3C%2FA%3E%2C%20you'll%20be%20able%20to%20create%20a%20repository%20and%20push%20the%20codes.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-12.png%22%20border%3D%220%22%20alt%3D%22Create%20GitHub%20repository%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EOnce%20pushed%20all%20codes%2C%20visit%20GitHub%20to%20check%20your%20repository%20whether%20all%20codes%20have%20actually%20been%20uploaded.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-13.png%22%20border%3D%220%22%20alt%3D%22Complete%20creating%20GitHub%20repository%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ELet's%20go%20back%20to%20the%20publish%20screen%20and%20click%20the%20%22%3Aheavy_plus_sign%3A%20New%22%20button%20to%20create%20a%20new%20publish%20profile.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-14.png%22%20border%3D%220%22%20alt%3D%22New%20publish%20profile%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThen%20a%20similar%20pop-up%20appears%20to%20before.%20This%20time%20let's%20use%20the%20%22Azure%20Function%20App%20(Linux)%22%20menu.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-15.png%22%20border%3D%220%22%20alt%3D%22Choose%20the%20deployment%20method%20for%20Linux%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAs%20mentioned%20before%2C%20you%20can%20use%20an%20existing%20instance%20or%20create%20a%20new%20one.%20Let's%20use%20the%20existing%20one.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-16.png%22%20border%3D%220%22%20alt%3D%22Choose%20existing%20instance%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIn%20the%20previous%20deployment%20exercise%2C%20we%20haven't%20got%20a%20GitHub%20repository.%20Therefore%2C%20we%20had%20to%20use%20the%20local%20deployment%20method.%20But%20this%20time%2C%20we've%20got%20the%20GitHub%20repository%2C%20meaning%20we've%20got%20choices.%20Therefore%2C%20instead%20of%20choosing%20the%20same%20deployment%20method%2C%20let's%20choose%20GitHub%20Actions%20for%20this%20time.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-17.png%22%20border%3D%220%22%20alt%3D%22Choose%20GitHub%20Actions%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EGitHub%20Actions%20workflow%20has%20now%20been%20automatically%20generated.%20But%20this%20needs%20a%20new%20commit.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-18.png%22%20border%3D%220%22%20alt%3D%22GitHub%20Actions%20commit%20%26amp%3B%20push%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EMove%20to%20the%20%22Git%20Changes%22%20pane%2C%20enter%20the%20commit%20message%20like%20below%2C%20click%20the%20%22Commit%20All%22%20button%2C%20and%20push%20the%20change.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-19.png%22%20border%3D%220%22%20alt%3D%22Commit%20%26amp%3B%20push%20the%20GitHub%20Actions%20workflow%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EWhen%20you%20actually%20visit%20your%20GitHub%20repository%2C%20your%20GitHub%20Actions%20workflow%20runs%20the%20build%20and%20deployment.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-20.png%22%20border%3D%220%22%20alt%3D%22Deploying%20Function%20app%20with%20GitHub%20Actions%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EOnce%20the%20deployment%20is%20over%2C%20open%20a%20new%20web%20browser%2C%20visit%20the%20Azure%20Functions%20app%20URL%2C%20and%20find%20out%20the%20Swagger%20UI%20page%20is%20correctly%20rendered.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fsa0blogs.blob.core.windows.net%2Fdevkimchi%2F2021%2F08%2Fazure-functions-openapi-on-net5-21.png%22%20border%3D%220%22%20alt%3D%22Swagger%20UI%20on%20Azure%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CHR%20%2F%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ESo%20far%2C%20we've%20walked%20through%20how%20to%20create%20an%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FAzure%2Fazure-functions-openapi-extension%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EOpenAPI%20enabled%3C%2FA%3E%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fazure%2Fazure-functions%2Ffunctions-overview%3FWT.mc_id%3Ddotnet-38365-juyoo%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EAzure%20Functions%3C%2FA%3E%20app%2C%20running%20on%20.NET%205%20isolated%20worker%20environment%2C%20and%20deploy%20it%20to%20Azure%20without%20having%20to%20leave%20%3CA%20href%3D%22https%3A%2F%2Fvisualstudio.microsoft.com%2F%3FWT.mc_id%3Ddotnet-38365-juyoo%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EVisual%20Studio%3C%2FA%3E.%20I'm%20guessing%20that%20it%20will%20run%20OK%20on%20.NET%206%2C%20theoretically.%20If%20you're%20curious%2C%20please%20deploy%20it%20and%20let%20us%20know%20at%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FAzure%2Fazure-functions-openapi-extension%2Fissues%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgithub.com%2FAzure%2Fazure-functions-openapi-extension%2Fissues%3C%2FA%3E!%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId-1658263917%22%20id%3D%22toc-hId-1658981604%22%3ECall%20to%20Action%3C%2FH2%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3EGitHub%20Repository%3A%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FAzure%2Fazure-functions-openapi-extension%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EAzure%20Functions%20OpenAPI%20Extension%3C%2FA%3E%3C%2FLI%3E%0A%3CLI%3EMicrosoft%20Docs%3A%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fazure%2Fazure-functions%2Fopenapi-apim-integrate-visual-studio%3FWT.mc_id%3Ddotnet-38365-juyoo%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3ECreate%20serverless%20APIs%20in%20Visual%20Studio%20using%20Azure%20Functions%20and%20API%20Management%20integration%20(preview)%3C%2FA%3E%3C%2FLI%3E%0A%3CLI%3EMicrosoft%20Learn%20TV%3A%20%3CA%20href%3D%22https%3A%2F%2Fwww.youtube.com%2Fplaylist%3Flist%3DPLlrxD0HtieHgTvUJGCtActXrPAI0XfXOa%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%3EAzure%20Functions%3A%20Discover%20OpenAPI%20and%20Power%20Apps%3C%2FA%3E%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CHR%20%2F%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%20style%3D%22text-align%3A%20center%3B%22%3EThis%20article%20was%20originally%20published%20on%20%3CA%20href%3D%22https%3A%2F%2Fdevkimchi.com%2F2021%2F08%2F13%2Fazure-functions-openapi-on-net5%2F%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%3EDev%20Kimchi%3C%2FA%3E.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-2647383%22%20slang%3D%22en-US%22%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-right%22%20image-alt%3D%22azure-functions-openapi-on-net5-00%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F303232i9658BC4CB2AF2C02%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22azure-functions-openapi-on-net5-00%22%20alt%3D%22Azure%20Functions%20with%20OpenAPI%20on%20.NET%205%22%20%2F%3E%3CSPAN%20class%3D%22lia-inline-image-caption%22%20onclick%3D%22event.preventDefault()%3B%22%3EAzure%20Functions%20with%20OpenAPI%20on%20.NET%205%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CDIV%3E%0A%3CDIV%3E%3CSPAN%3EIn%20this%20post%2C%20I'm%20going%20to%20show%20how%20to%20run%20the%20OpenAPI%20extension%20for%20Azure%20Functions%20on%20the%20.NET%205%20isolated%20worker%20environment.%3C%2FSPAN%3E%3C%2FDIV%3E%0A%3C%2FDIV%3E%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-2647383%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3E.NET%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EAzure%20Functions%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EServerless%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E
Co-Authors
Version history
Last update:
‎Aug 15 2021 07:31 PM
Updated by: