Giter VIP home page Giter VIP logo

azure / azure-functions-openapi-extension Goto Github PK

View Code? Open in Web Editor NEW
356.0 37.0 183.0 13.88 MB

This extension provides an Azure Functions app with Open API capability for better discoverability to consuming parties

Home Page: https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi/

License: MIT License

C# 98.63% Dockerfile 0.12% PowerShell 0.64% Shell 0.62%
azure-functions swagger-ui hacktoberfest azure openapi power-platform

azure-functions-openapi-extension's Introduction

Azure Functions OpenAPI Extension

Out-of-Proc Worker In-Proc Worker

Acknowledgement

Getting Started

  • Generic CI/CD Pipeline Support: This document shows how to generate the OpenAPI document within a CI/CD pipeline, using either PowerShell or bash shell script.

GitHub Actions Support

If you are using GitHub Actions as your preferred CI/CD pipeline, you can run the GitHub Action into your workflow to automatically generate the OpenAPI document. Find more details at the Build OpenAPI action page.

GitHub Codespaces Support

If you want to run your Azure Functions app on GitHub Codespaces, you might want to accommodate local.settings.json. The following PowerShell script may help you for the accommodation:

# Update local.settings.json
pwsh -c "Invoke-RestMethod https://aka.ms/azfunc-openapi/add-codespaces.ps1 | Invoke-Expression"

Sample Azure Function Apps with OpenAPI Document Enabled

Here are sample apps using the project references:

## Azure Functions V1 Support ##

This library supports Azure Functions V3 and onwards. If you still want to get your v1 and v2 runtime app supported, find the community contribution or the proxy feature.

Known Issues

Missing .dll Files

Due to the Azure Functions Runtime limitation, sometimes some of .dll files are removed while publishing the function app. In this case, try the following workaround with your function app .csproj file.

<Project Sdk="Microsoft.NET.Sdk">
  ...
  <PropertyGroup>
    ...
    <_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
  </PropertyGroup>
  ...
</Project>

Empty Swagger UI When Deployed through Azure Pipelines

Swagger UI Error When Empty Project Referenced

Issues?

While using this library, if you find any issue, please raise an issue on the Issue page.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

azure-functions-openapi-extension's People

Contributors

ahmadtantowi avatar aieatassam avatar choipureum avatar cistusf avatar danielabbatt avatar derich367 avatar deserve82 avatar emrekara37 avatar flcdrg avatar gsteenpa avatar haileymoon avatar hnnynh avatar jackbatzner avatar justinyoo avatar kendaleiv avatar kwonsunjae avatar lee-wonjun avatar level120 avatar microsoftopensource avatar sarah2234 avatar sersoc avatar sinantutan avatar soniacomp avatar spboyer avatar ssa3512 avatar thomasbleijendaal avatar tony-xia avatar tsolbjor avatar vincentbitter avatar william-froelich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

azure-functions-openapi-extension's Issues

Active Directory B2C Auth Configuration

I've configured Azure Active directory B2C auth flow by adding a new class 'B2CAuth' derived from the 'OpenApiOAuthSecurityFlows' interface. Unfortunately, the API Authorization is unsuccessful and returned 401 - UnAuthorized error in the swagger UI.
The code is given below. Not sure if I am missing any config settings. Could anyone please advise?
`
class B2CConfigAuth : OpenApiOAuthSecurityFlows
{
public B2CConfigAuth()
{
Implicit = new OpenApiOAuthFlow()
{
// Add b2C auth url.
AuthorizationUrl = new Uri(""),
// Add b2c API scope
Scopes = new Dictionary<string, string> { { "openid", "OpenID" }, { "","AppIDURI" } }
};
}
}

// HTTP Get Method
public static class B2CAuthTest
{
    [OpenApiOperation(operationId: "OpenAPITest", tags: new[] { "name" })]
    [OpenApiSecurity("b2cAuth", SecuritySchemeType.OAuth2, In = OpenApiSecurityLocationType.Header, Scheme = OpenApiSecuritySchemeType.Bearer, Flows = typeof(B2CConfigAuth))]
    [OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Description = "The **Name** parameter")]
    [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "text/plain", bodyType: typeof(string), Description = "The OK response")]
    [FunctionName("OpenAPITest")]
    public static async Task<IActionResult> OpenAPITest(
        [HttpTrigger(AuthorizationLevel.Function, "get", 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);
    }
}`

OAuth2 Workflow - oauth2-redirect.html not found

During Implementing an OAuth2 Workflow for the api documentation i'm getting the issue that the redirect page can't be found.
E.g. for local running function http://localhost:7071/oauth2-redirect.html can't be found (404) after successful authentication.

My OpenApiOAuthSecurityFlows looks like this:

class TestOAuth2 : OpenApiOAuthSecurityFlows
    {
        public TestOAuth2 ()
        {
            this.Implicit = new OpenApiOAuthFlow()
            {
                AuthorizationUrl = new Uri("https://xxxx.b2clogin.com/xxxx.onmicrosoft.com/oauth2/v2.0/authorize?p=workflow_id"),
                Scopes = { { "https://xxxx.onmicrosoft.com/xxxx-xxx/API.User", "API Access" } },
                TokenUrl = new Uri("https://xxxx.b2clogin.com/xxxx.onmicrosoft.com/oauth2/v2.0/token?p=workflow_id")
                
            };
        }
    }

Am i missing some configuration for the redirect page?

Arrays of arrays doesn't work

Hi, models that have List<List<string>> or Dictionary<string, List<string>> properties get generated incorrectly

For example, if i have a function like this

public class Foo
{
	public List<List<string>> Items { get; set; }
}

public class TestFunction
{
	[FunctionName("Test")]
	[OpenApiOperation(operationId: "Test")]
	[OpenApiResponseWithBody(HttpStatusCode.OK, "application/json", typeof(Foo))]
	public IActionResult GetTest(
		[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "test")] HttpRequest req)
	{
		return new OkResult();
	}
}

Then the Items property will become an string array, and not an array of arrays.

image

The same happens if i have a Dictionary<string, List<string>> .
Then the property will become Dictionary<string, string>

Range annotation not respected

Is there a way to annotate models so the Open API spec show constraints like minimum and maximum in description section?

Using
[Range(-90.0, 90.0)]
public double latitude { get; set; }

Does not reflected latitude in the spec description with a "minimum": -90 or "maximum": 90.

default "Code" query string on all functions

Hey, I get this parameter on requests of all my functions, and I don't know where it is coming from, since I am not specifying it with the data annotations:
"parameters": [
{
"in": "query",
"name": "code",
"type": "string"
}]

I am using default functionality to retrieve the swagger.json. With this I mean I haven't changed any setting after I installed the nuget package and added some data annotations to my functions.

Swagger.json using HTTP instead of HTTPS

I am using "Microsoft.Azure.WebJobs.Extensions.OpenApi" version "0.5.1-preview" and having problems when I publish my Function App. Swagger UI is using HTTPS but swagger.json is using HTTP. My Function App is configured to use "HTTPS Only" and "Minimum TLS Version" as "1.2".

Swagger UI

image

Swagger.json

image

I tried to override the list of openapi servers creating a class that inherit from "DefaultOpenApiConfigurationOptions". But I needed the HttpRequest object, and this class does not permit inject values, it is created using Activator.CreateInstance.

What should I do?

GetSwaggerAuthKey should not return nullable string

I'm using the OpenApi Extensions in a Azure Functions app, netcoreapp3.1 with nullability enabled and nullability warnings are treated as errors.

My csproj contains this:

<PropertyGroup>
  <TargetFramework>netcoreapp3.1</TargetFramework>
  <AzureFunctionsVersion>V3</AzureFunctionsVersion>
  <LangVersion>9.0</LangVersion>
  <Nullable>enable</Nullable>
  <WarningsAsErrors>nullable</WarningsAsErrors>
</PropertyGroup>

But when the Microsoft.Azure.WebJobs.Extensions.OpenApi (version: 0.4.0-preview) NuGet package is included, it won't compile anymore.
It's caused by the template file OpenApiHttpTriggerContext.cs that is included in the project. It contains a GetSwaggerAuthKey method, which returns a string.

public virtual string GetSwaggerAuthKey(string key = "OpenApi__ApiKey")
{
  var value = Environment.GetEnvironmentVariable(key);

  return value;
}

But Environment.GetEnvironmentVariable(key) returns a nullable string: string?
So now my compiler is unhappy and returns this error:

Error	CS8603	Possible null reference return.
microsoft.azure.webjobs.extensions.openapi\0.4.0-preview\contentFiles\any\netstandard2.0\OpenApi\OpenApiHttpTriggerContext.cs	121	Active

I submitted a fix in PR #49

Configure default OpenAPI document version

The swagger.json endpoint, /api/swagger.json renders OpenAPI v2 spec as default and nowhere can it override to v3 spec. It can be configureable through IOpenApiConfigurationOptions ๐Ÿค”:

public interface IOpenApiConfigurationOptions
{
/// <summary>
/// Gets or sets the <see cref="OpenApiInfo"/> instance.
/// </summary>
OpenApiInfo Info { get; set; }
/// <summary>
/// Gets or sets the list of <see cref="OpenApiServer"/> instances.
/// </summary>
List<OpenApiServer> Servers { get; set; }
}

Customised String Enum Member

Enums decorated with [JsonConverter(typeof(StringEnumConverter))] needs to respect both System.Runtime.Serialization.EnumMemberAttribute and Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes.DisplayAttribute.

If both attributes are declared to a certain enum field, System.Runtime.Serialization.EnumMemberAttribute takes precedence over Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes.DisplayAttribute.

StackOverflow Exception on circular reference

Here is a code sample to reproduce the issue:

    public class Function1
    {
        private const string ContentType = "application/json";
        public List<Book> Lib { get; set; } = new List<Book>();

        [FunctionName(nameof(AddBook))]
        [OpenApiOperation(operationId: nameof(AddBook), Visibility = OpenApiVisibilityType.Important)]
        [OpenApiRequestBody(contentType: ContentType, bodyType: typeof(Book), Required = true)]
        [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: ContentType, bodyType: typeof(List<Book>))]
        public IActionResult AddBook([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)][FromBody] Book req, ILogger log)
        {
            Lib.Add(req);
            return new OkObjectResult(Lib);
        }
    }

    public class Book
    {
        public string Name { get; set; }
        public DateTime PublicationDate { get; set; }
        public Author Author { get; set; }
    }

    public class Author
    {
        public string Name { get; set; }
        public List<Book> Books { get; set; }
    }

It seems like recursion happens in Visit method of ObjectTypeVisitor class.

The same can be reproduced in Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3IoC project by adding a new class Owner:

       public class Owner
    {
        public string Name { get; set; }
        public List<Pet> Pets { get; set; }
    }

And introducing new property "public Owner Owner { get; set; }" in Pet class

Allow extensibility of swagger UI with custom stylesheets

As a consumer of this package, I would like the ability to override some of the CSS contained in the dist folder with some of my own to be able to provide some custom branding on the swagger UI site.

It would be great to have some methods that can be overridden in SwaggerUI to enable the inclusion of custom stylesheets to be included above the [[SWAGGER_UI_CSS]] placeholder in index.html.

"offline" generation of OpenAPI definition for use in build pipeline

When working with a solution containing a PowerPlatform custom connector that uses an OpenAPI definition generated from an Azure Function it would be good to be able to output the OpenAPI definition (v2 currently only for custom connectors) within a build pipeline.

This would remove the manual step of having to update the custom connector YAML, then export the solution containing the custom connector.

Generated swagger documentation includes only the first function in a file

When i try to generate the swagger documentation for the code below i get only see the endpoint of the first function in my swagger ui (and in the generated swagger / openAPI files.) The first endpoint of a second file is also shown, but the following functions in that file is not included as well. Any suggestion of what i do wrong?

using ...

namespace IngestionApi.Functions
{
    public class DatasetsApi
    {
        private ILogger<DatasetsApi> _logger;
        private IDatasetService _DatasetService;
        /// <summary> Initializes a new instance of DatasetsApi. </summary>
        /// <param name="logger"> Class logger. </param>
        /// <exception cref="ArgumentNullException"> <paramref name="logger"/> is null. </exception>
        public DatasetsApi(ILogger<DatasetsApi> logger)
        {
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            _logger = logger;
            //_IDatasetService = new DatasetsApi();
        }

        // /// <summary> 1) validate data 2) generate datasetId 3) add meta data to `datasetMeta` bucket + update `createdAt` and `datasetID` field 4) create new container(s) in storage and store `containerId/Url` to meta data (raw and processed) 5) return `datasetId`?. </summary>
        // /// <param name="body"> Meta data to create new datasset. </param>
        // /// <param name="req"> Raw HTTP Request. </param>
        // /// <param name="cancellationToken"> The cancellation token provided on Function shutdown. </param>
        // /// <exception cref="ArgumentNullException"> <paramref name="body"/> is null. </exception>
        
        [FunctionName(nameof(DatasetsApi.CreateDatasetAsync))]
        [OpenApiOperation(operationId: "CreateDatasetAsync", tags: new[] { "datasets" }, Summary = "Gets the name")]
        public async Task<IActionResult> CreateDatasetAsync([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "datasets")] HttpRequest req, CancellationToken cancellationToken = default)
        {
            _logger.LogInformation("HTTP trigger function processed a request.");

            // TODO: Handle Documented Responses.
            // Spec Defines: HTTP 200
            // Spec Defines: HTTP 400

            Console.WriteLine("HTTP trigger function: CreateDatasetAsync");
            Console.WriteLine( req.Query);
            string requestBody = String.Empty;
            using (StreamReader streamReader =  new  StreamReader(req.Body))
            {
                requestBody = await streamReader.ReadToEndAsync();
            }
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            Console.WriteLine(data);

            throw new NotImplementedException();
        }

        [FunctionName(nameof(DatasetsApi.CreateNewDatasetVersionAsync))]
        [OpenApiOperation(operationId: "CreateNewDatasetVersionAsync", tags: new[] { "datasets" }, Summary = "Gets the name 1", Description = "This gets the name.", Visibility = OpenApiVisibilityType.Important)]
        //[OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Summary = "The name", Description = "The name", 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")]
        public async Task<IActionResult> CreateNewDatasetVersionAsync(string datasetId, [HttpTrigger(AuthorizationLevel.Anonymous, "put", Route = "datasets1/{datasetId}")] HttpRequest req, CancellationToken cancellationToken = default)
        {
            _logger.LogInformation("HTTP trigger function processed a request.");

            // TODO: Handle Documented Responses.
            // Spec Defines: HTTP 200
            // Spec Defines: HTTP 400


            throw new NotImplementedException();
        }

....more fumctions with same tag.....
    }
}

How to include POST actions' object info in swagger's web page

I have a class like the following one that will be submitted to my HTTP-triggered function by POST action:

internal class MyPOCO
{
	public int Id { get; set; }
	public string Name { get; set; }
}

How can it be defined as the open api input parameter like the following example? It simply does not work as I think this kind of parameter definition applies to GET requests.

[OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(MyPOCO), Description = "The **Name** parameter")]

Add broader support for Microsoft's Custom Connector annotations

Related to: aliencube/AzureFunctions.Extensions#116

There are already samples how to make use of this library to make some more advanced annotations for Custom Connectors in Logic Apps or Power Automate.

It would be really cool to get support for trigger annotations along with dynamic schema and so on. Microsoft has it quite well documented here: https://docs.microsoft.com/en-us/connectors/custom-connectors/openapi-extensions

In the past, there was a project called T-Rex which did exactly that, however it was only for ASP.NET on .NET Framework and doesn't support ASP.NET Core or Azure Functions.

openapisettings.json not honored

I created a new Functions project and added the NuGet package to it, then worked up some code and got it running. However, when I would try to load up the Swagger or Open API URLs or the Swagger UI page, I would get the following error message:

Hosting environment: Production
Content root path: /Users/bradygaster/source/WeatherService/WeatherService/bin/output
Now listening on: http://0.0.0.0:7071
Application started. Press Ctrl+C to shut down.

Functions:

	RenderOpenApiDocument: [GET] http://localhost:7071/api/openapi/{version}.{extension}

	RenderSwaggerUI: [GET] http://localhost:7071/api/swagger/ui

	GetForecasts: [GET] http://localhost:7071/api/GetForecasts

	RenderSwaggerDocument: [GET] http://localhost:7071/api/swagger.{extension}

[10/6/2020 5:09:04 PM] Executing HTTP request: {
[10/6/2020 5:09:04 PM]   requestId: "a8c6a055-14a6-4d46-8465-13846e48b93a",
[10/6/2020 5:09:04 PM]   method: "GET",
[10/6/2020 5:09:04 PM]   userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 Edg/85.0.564.68",
[10/6/2020 5:09:04 PM]   uri: "/api/swagger/ui"
[10/6/2020 5:09:04 PM] }
[10/6/2020 5:09:04 PM] Executing 'RenderSwaggerUI' (Reason='This function was programmatically called via the host APIs.', Id=466cf7e3-62fc-4c78-a7f6-59bc00c9d21c)
[10/6/2020 5:09:04 PM] SwaggerUI page was requested.
[10/6/2020 5:09:04 PM] Executed 'RenderSwaggerUI' (Failed, Id=466cf7e3-62fc-4c78-a7f6-59bc00c9d21c, Duration=133ms)
[10/6/2020 5:09:04 PM] System.Private.CoreLib: Exception while executing function: RenderSwaggerUI. WeatherService: The type initializer for 'Microsoft.Azure.WebJobs.Extensions.OpenApi.OpenApiHttpTrigger' threw an exception. Microsoft.Azure.WebJobs.Extensions.OpenApi.Core: Open API metadata not found.
[10/6/2020 5:09:05 PM] Executed HTTP request: {
[10/6/2020 5:09:05 PM]   requestId: "a8c6a055-14a6-4d46-8465-13846e48b93a",
[10/6/2020 5:09:05 PM]   identities: "(WebJobsAuthLevel:Admin)",
[10/6/2020 5:09:05 PM]   status: "500",
[10/6/2020 5:09:05 PM]   duration: "271"
[10/6/2020 5:09:05 PM] }

I deleted the openapisettings.json file and moved the Open API info JSON data from that file into the host.json file:

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingExcludedTypes": "Request",
      "samplingSettings": {
        "isEnabled": true
      }
    }
  },
  "openApi": {
    "info": {
      "version": "1.0.0",
      "title": "Open API Sample on Azure Functions",
      "description": "An API that provides the Weather Forecast via HTTP",
      "termsOfService": "https://github.com/Azure/azure-functions-openapi-extension",
      "contact": {
        "name": "Customer Name",
        "email": "[email protected]",
        "url": "https://github.co/my-git-remote-url.git"
      },
      "license": {
        "name": "MIT",
        "url": "http://opensource.org/licenses/MIT"
      }
    }
  }
}

Once I did this, everything worked just fine - the Swagger UI page would load and the JSON/YAML URLs would also load just fine.

My personal feeling is we should have one option here, and not bifurcate the ways of offering customers the ability to customize. I would move for total deletion of the openapisettings.json file. Also not a fan of the syntax required in local.settings.json - my favorite is the host.json approach, but I truly don't think adding a new file, openapisettings.json, is a good idea - feels too bloated, like too many concepts being added.

I think the best course of action would be to support the Open API style of including the JSON as works in host.json in both that file and in local.settings.json.

Docs omit Servers property

I followed the docs - which are MUCH-improved and getting exciting - and ran into one issue. When I follow the tutorial explicitly the OpenApiConfigurationOptions class I created lacks the Servers property, so I get a compilation error.

image

I can add this manually, but I think this approach to hard-coding it is sub-optimal and I'd prefer us not recommend someone hard-code localhost into their C# code.

public List<OpenApiServer> Servers 
{ 
    get
    {
      return ( new OpenApiServer[] { new OpenApiServer { Url = "https://localhost:7071" }}).ToList();
    }
    set => throw new NotImplementedException(); 
}

Is there a way that the Functions runtime can provide this? Something we could do to mitigate the customer's need to have to do this OR provide some sort of guidance that wouldn't require hard-coding?

Programming language support of this extension

Hello, currently we are also working on generating swagger from Azure Function.
Do you have any plans to support other languages recently? We are looking for a solution to typescript.

IConfiguration Support for Open API Metadata

Currently model relies on host.json, openapisettings.json or environment variables, which is less intuitive for devs to implement. It also has a tight coupling with AppSettings model, which forces devs to use it.

Instead, creating a middleware like IServiceCollection.AddOpenApi(xxx) might provide devs with more flexibility.

Guidance On Plugging Into OpenApiSecurity For JWT Bearer Tokens

Can you point me to documentation/code samples of how to plug into the OpenApiSecurity attribute? Our scenario is where we have our own attribute that inherits from the AuthorizeAttribute that we decorate our functions with. How do we wire up the OpenApiSecurity attribute so that the "Try It Now" feature will work?

NullReferenceException in RenderSwaggerDocument with simplest Function HttpTrigger

Following the guide at https://github.com/Azure/azure-functions-openapi-extension/blob/main/docs/enable-open-api-endpoints.md

  1. Create the functions project, add the HttpTrigger, make changes to host.json and add the OpenApi* attributes as listed to the HttpTrigger.
  2. Run the func.exe locally
  3. Try to browse to the [localhosturl]/swagger/ui page

RESULT:
NullReferenceException in a call to Linq (SelectMany related)

EXPECT:
The page to render with the one HttpTrigger listed.

Swagger "try it out" with funcktion / host key

How can I use or extend the "try it out" functionality from swagger ui, if i I deployed the solution to Azure function, while using AuthorizationLevel.Function. "Try it out" does not respect the OpenApi__ApiKey settings and sends the request without key, which causes 401 Unauthorized.

Is there any way or attribute to configure it, that "try it out" sends the request with the function key or with the OpenApi__ApiKey from the settings.

Integration with OpenAPI.NET.CSharpAnnotations

Hi! I'm just looking into different options to better document Azure Functions API projects and I think the project seems pretty useful.

Although the use of attributes to document seems to be working good, I was wondering if there is any plan (or has been considered) to integrate with https://github.com/microsoft/OpenAPI.NET.CSharpAnnotations to allow retrieving OpenAPI specs from a method's annotations.

It feels counter productive if one wants to document both the OpenAPI and the method to duplicate content on both annotations and attributes.

Just a thought anyway.

Cheers!

When to expecte 1.0?

Hi,

Could you please share the timeline for this project?
I'd love to start using it, would be very helpful to know when to expect a prod ready version.

Ignore code analysis warnings in extension files

I'm using the 0.1.0-preview version in a C# Azure Functions V3 project, running on Linux with .NET Core SDK 3.1

Our project uses Roslyn-based code analysis during the build. This extension adds some source files for compilation, but unfortunately, these are also picked up for analysis. I cannot find a way to ignore them (tried the .editorconfig approach, but that only works for files inside the repository).

/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTrigger.cs(29,121): warning MEN002: Line must be no longer than 120 characters (now 130). [/path/to/my/Project.csproj]
/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTrigger.cs(48,121): warning MEN002: Line must be no longer than 120 characters (now 122). [/path/to/my/Project.csproj]
/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTrigger.cs(66,121): warning MEN002: Line must be no longer than 120 characters (now 130). [/path/to/my/Project.csproj]
/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTrigger.cs(86,121): warning MEN002: Line must be no longer than 120 characters (now 127). [/path/to/my/Project.csproj]
/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTrigger.cs(23,60): warning SA1311: Static readonly fields should begin with upper-case letter [/path/to/my/Project.csproj]
/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTrigger.cs(23,26): warning SA1206: The 'static' modifier should appear before 'readonly' [/path/to/my/Project.csproj]
/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTriggerContext.cs(31,13): warning SX1101: Do not prefix local calls with 'this.' [/path/to/my/Project.csproj]
/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTriggerContext.cs(32,13): warning SX1101: Do not prefix local calls with 'this.' [/path/to/my/Project.csproj]
/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTriggerContext.cs(38,13): warning SX1101: Do not prefix local calls with 'this.' [/path/to/my/Project.csproj]
/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTriggerContext.cs(39,13): warning SX1101: Do not prefix local calls with 'this.' [/path/to/my/Project.csproj]
/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTriggerContext.cs(78,20): warning SX1101: Do not prefix local calls with 'this.' [/path/to/my/Project.csproj]
/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTriggerContext.cs(99,20): warning SX1101: Do not prefix local calls with 'this.' [/path/to/my/Project.csproj]
/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTrigger.cs(19,30): warning CA1823: Unused field 'V3' [/path/to/my/Project.csproj]
/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTrigger.cs(20,30): warning CA1823: Unused field 'JSON' [/path/to/my/Project.csproj]
/home/basilfx/.nuget/packages/microsoft.azure.webjobs.extensions.openapi/0.1.0-preview/contentFiles/any/netstandard2.0/OpenApi/OpenApiHttpTrigger.cs(21,30): warning CA1823: Unused field 'YAML' [/path/to/my/Project.csproj]

I manually modified the files and added // <auto-generated> on the first line, which solves it 'temporary'.

Doesn't support multiple operations (for example, GET, POST) for one endpoint

When I scanned the generated file swagger.json I found desription for one endpoint:
swagger: '2.0'
info:
title: Azure Functions Open API Extension
version: 1.0.0
host: localhost:7071
basePath: /api
schemes:

  • http
    paths:
    /HttpTriggerCSharp1:
    get:
    tags:
    - name
    operationId: Run
    produces:
    - text/plain
    parameters:
    - in: query
    name: name
    description: The Name parameter
    required: true
    type: string
    responses:
    '200':
    description: The OK response
    schema:
    type: string
    security:
    - function_key: [ ]
    securityDefinitions:
    function_key:
    type: apiKey
    name: code
    in: query

But in C# code we have support two types HTTP request GET and POST:

namespace Company.Function
{
public static class HttpTriggerCSharp1
{
[FunctionName("HttpTriggerCSharp1")]
[OpenApiOperation(operationId: "Run", tags: new[] { "name" })]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
[OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Description =
"The Name parameter")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "text/plain", bodyType: typeof(string),
Description = "The OK response")]
public static async Task Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "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);
    }
}

}

Model casing is changed

I defined an XML request like the following :
[OpenApiRequestBody(contentType: "text/xml", bodyType: typeof(Model.MyClass))]

public class MyClass
{
    public MySubClass MySubClass { get; set; }
}

public class MySubClass
{
    public string MyProperty { get; set; }
}

Then when I look in the generated UI, the casing I have defined has changed:
<?xml version="1.0" encoding="UTF-8"?>
<myClass>
<mySubClass>
<myProperty>string</myProperty>
</mySubClass>
</myClass>

So far, the only solution I have found is to redefine the name of each property using the JsonProperty decorator.
For instance: [JsonProperty("MyProperty")]

Also does it make sense to use that decorator when my request is 'text/xml' ?
It looks like this extension is made for JSON and XML is an afterthought.

Support "catch all" http trigger route

Writing a route like {*path} and {**path} to get all subsequent path parameters did not correctly output the OpenAPI definition.

Microsoft.Azure.WebJobs.Extensions.OpenApi: 0.5.1-preview

Repro code

[FunctionName("CatchAll")]
[OpenApiOperation(operationId: "CatchAll", tags: new[] { "name" })]
[OpenApiParameter("path", In = ParameterLocation.Path, Type = typeof(string))]
[OpenApiResponseWithoutBody(HttpStatusCode.OK)]
public static ActionResult CatchAll([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "catchall/{*path}")]
                                                 HttpRequest req,
                                                 string path)
{
    return new OkObjectResult(path);
}

Actual behavior

image

Do all functions in the project have to be configured?

I have a single function app/project. Some of the functions are queue trigger functions others I don't have and don't want Open API configuration for. I'm not sure if that's what's causing the error below but I tried setting up Open API on a test project/function app that I have (which has only one function that I setup OpneAPI for) and it worked fine so I am wondering if my problem is having queue triggers and undefined http trigger functions in the same function app.

The below error is what I get when running the function app locally I try to access the swagger UI.

[2021-03-29T20:39:51.921Z] Executing 'RenderSwaggerUI' (Reason='This function was programmatically called via the host APIs.')

[2021-03-29T20:39:51.931Z] SwaggerUI page was requested.

[2021-03-29T20:39:52.077Z] Executed 'RenderSwaggerUI' [2021-03-29T20:39:52.079Z] System.Private.CoreLib: Exception while executing function: RenderSwaggerUI. System.Linq: Value cannot be null. (Parameter 'source').

Java support (examples)

This is great!
will there be examples for different languages, specifically Java, GoLang?

Overwriting Base URL

Related to: aliencube/AzureFunctions.Extensions#136

We're also using an Azure API Management Instance and Azure Front Door in front of our API which changes the base url, however on the Swagger UI this is still pointing to the original Azure Function URL, is there a way to override the baseUrl as well?

Yeah adjusting the base URL would be pretty important for us, the Azure Function base URL is fairly different from the API Management base URL.

Invalid Route Path Error

Initializing the Route parameter in the HTTPAttribute is resulting in undefined path errors in the generated swagger file. Could you please advise?

// Swagger Errors
{"messages":[""attribute paths.'/AddUserAccount'(post).responses is missing","attribute paths.'/Account/DeleteUserAccount'(delete).responses is missing","attribute]
}
public async Task<IActionResult> AddUserAccount( [HttpTrigger(AuthorizationLevel.Function, "post", Route = "AddUserAccount")] HttpRequest req, ILogger log) { // await azureAccount.AddUserAccount(req.Claims()); return new OkResult(); }
`

Property descriptions of models

Hi there,

First off, this is a super great project and I'm glad it's being developed!

I'm trying it one of my projects and I was wondering (maybe its a question for the main .NET OpenAPI package) if there is a way to add property descriptions to the open api output.

For example, say I have a model:

class UserResponse
{
    public string Name { get; set; }
    public string Id { get; set; }
}

When I specify

[OpenApiResponseWithBody(HttpStatusCode.OK, "application/json", typeof(UserResponse)]

I would like to have it output

  UserResponse:
    type: object
    properties:
      Name:
        type: string
        description: The name of the user
      Id:
        type: string
        description: The id of the user (GUID)

Is there any attributes I can add to the model to give the properties descriptions and have them included in the output?

Thanks!

Would be nice to be able to specify multiple content types?

Currently the OpenApiRequestBodyAttribute only accepts one content type string. The output of this in the openapi.json is:

"consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],

But this attribute accepts multiple values, so the following is valid Openai syntax:

"consumes": [
          "application/json",
         "test/html"
        ],
        "produces": [
          "application/json"
        ],

etc. There is no way to currently add these open api attributes using this plugin.

CLI tool as a .NET Tool

For API Management integration, we generate OpenAPI specs at build time and push these specs to APIM during deployment.
This works very well with the CI/CD paradigm, much more so than manually importing the spec into APIM as suggested in the APIM integration article.

For WebAPI projects we use the Swashbuckle CLI tool which is a .net core tool and can be installed easily into an Azure DevOps pipeline agent. I'd love to have a similar solution using the CLI tool from this project for Azure Functions.

Is that in the plans? I'm willing to pitch in if that helps.

support for operation version

In order to support multiple versions of an operation, I would like to annotate on each method the version of the api its related.

(similar to aspnet core)

E.g.

        [ApiVersion("1")]
        [Route("api/v{version:apiVersion}")]
        public async Task<IActionResult> GetTickets_v1(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
       {  }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.