Skip to content

More DI feature for OpenApiConfigurationOptions #466

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 8 additions & 59 deletions docs/openapi-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ If the above conditions are met, add the following key to your `local.settings.j
To generate an OpenAPI document, [OpenApiInfo object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#infoObject) needs to be defined. ***It's totally optional***, but if you want, you can implement the `IOpenApiConfigurationOptions` interface within your Azure Functions project to provide OpenAPI metadata like below:

```csharp
public class OpenApiConfigurationOptions : IOpenApiConfigurationOptions
public class MyOpenApiConfigurationOptions : IOpenApiConfigurationOptions
{
public OpenApiInfo Info { get; set; } = new OpenApiInfo()
{
Expand Down Expand Up @@ -102,7 +102,7 @@ It's often required for the API app to have more than one base URL, with differe
Alternatively, add `OpenApiServer` details to the `Servers` property like:

```csharp
public class OpenApiConfigurationOptions : IOpenApiConfigurationOptions
public class MyOpenApiConfigurationOptions : IOpenApiConfigurationOptions
{
...

Expand All @@ -127,7 +127,7 @@ public class OpenApiConfigurationOptions : IOpenApiConfigurationOptions
The default version of OpenAPI document rendered is V2 (AKA Swagger). However, you can override the default rendering behaviour by implementing the `OpenApiVersion` property.

```csharp
public class OpenApiConfigurationOptions : IOpenApiConfigurationOptions
public class MyOpenApiConfigurationOptions : IOpenApiConfigurationOptions
{
...

Expand All @@ -145,7 +145,7 @@ public class OpenApiConfigurationOptions : IOpenApiConfigurationOptions
If you want to force either HTTP or HTTPS, configure the following properties on the `IOpenApiConfigurationOptions` interface.

```csharp
public class OpenApiConfigurationOptions : IOpenApiConfigurationOptions
public class MyOpenApiConfigurationOptions : IOpenApiConfigurationOptions
{
...

Expand Down Expand Up @@ -198,65 +198,14 @@ public class MyOpenApiConfigurationOptions : DefaultOpenApiConfigurationOptions
}
```

### Dynamically configuring `IOpenApiConfigurationOptions` at Runtime ###

There may be instances where you want to configure the `IOpenApiConfigurationOptions` at runtime.
### Injecting `OpenApiConfigurationOptions` during Startup ###

To dynamically modify your configuration options at runtime you can use the following examples:
You may want to inject the `OpenApiConfigurationOptions` instance during startup:

#### In of Proc ####
* [in-proc worker](./openapi-in-proc.md#injecting-openapiconfigurationoptions-during-startup)
* [out-of-proc worker](./openapi-out-of-proc.md#injecting-openapiconfigurationoptions-during-startup)

```csharp
public override void Configure(IFunctionsHostBuilder builder)
{
var fixture = new Fixture();
builder.Services.AddSingleton(fixture);

// Example: If you want to change the configuration during startup of your function you can use the following code:
services.AddSingleton<IOpenApiConfigurationOptions>(x =>
{
return new OpenApiConfigurationOptions()
{
Info = new Microsoft.OpenApi.Models.OpenApiInfo
{
Title = "A dynamic title generated at runtime",
Description = "Dynamic Open API information at runtime"
}
};
});
}
```

#### Out of Proc ####

```csharp
public static void Main()
{
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson())
.ConfigureOpenApi()
.ConfigureServices(services => services.AddSingleton<Fixture>())
.ConfigureServices(services => {
services.AddSingleton<Fixture>();

// Example: If you want to change the configuration during startup of your function you can use the following code:
services.AddSingleton<IOpenApiConfigurationOptions>(x =>
{
return new OpenApiConfigurationOptions()
{
Info = new Microsoft.OpenApi.Models.OpenApiInfo
{
Title = "A dynamic title generated at runtime",
Description = "Dynamic Open API information at runtime"
}
};
});
})
.Build();

host.Run();
}
```

## Swagger UI Customisation ##

Expand Down
49 changes: 49 additions & 0 deletions docs/openapi-in-proc.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,52 @@ For detailed getting started document, find this [Enable OpenAPI Endpoints on Az
## Advanced Configuration in General ##

If you look for the advanced configurations in general, please find the document, [Advanced Configurations for OpenAPI Extension](./openapi.md)


### Injecting `OpenApiConfigurationOptions` during Startup ###

You may want to inject the `OpenApiConfigurationOptions` instance during startup, through the `Startup.cs` class. Here's the example:

```csharp
[assembly: FunctionsStartup(typeof(MyFunctionApp.Startup))]
namespace MyFunctionApp
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton<IOpenApiConfigurationOptions>(_ =>
{
var options = new OpenApiConfigurationOptions()
{
Info = new OpenApiInfo()
{
Version = "1.0.0",
Title = "Swagger Petstore",
Description = "This is a sample server Petstore API designed by [http://swagger.io](http://swagger.io).",
TermsOfService = new Uri("https://github.com/Azure/azure-functions-openapi-extension"),
Contact = new OpenApiContact()
{
Name = "Enquiry",
Email = "[email protected]",
Url = new Uri("https://github.com/Azure/azure-functions-openapi-extension/issues"),
},
License = new OpenApiLicense()
{
Name = "MIT",
Url = new Uri("http://opensource.org/licenses/MIT"),
}
},
Servers = DefaultOpenApiConfigurationOptions.GetHostNames(),
OpenApiVersion = OpenApiVersionType.V2,
IncludeRequestingHostName = true,
ForceHttps = false,
ForceHttp = false,
};

return options;
});
}
}
}
```
59 changes: 59 additions & 0 deletions docs/openapi-out-of-proc.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,62 @@ For detailed getting started document, find this [Enable OpenAPI Endpoints on Az
## Advanced Configuration in General ##

If you look for the advanced configurations in general, please find the document, [Advanced Configurations for OpenAPI Extension](./openapi.md)


### Injecting `OpenApiConfigurationOptions` during Startup ###

You may want to inject the `OpenApiConfigurationOptions` instance during startup, through the `Program.cs` class. Here's the example:

```csharp
namespace MyFunctionApp
{
public class Program
{
public static void Main()
{
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson())
.ConfigureOpenApi()
/* ⬇️⬇️⬇️ Add this ⬇️⬇️⬇️ */
.ConfigureServices(services =>
{
services.AddSingleton<IOpenApiConfigurationOptions>(_ =>
{
var options = new OpenApiConfigurationOptions()
{
Info = new OpenApiInfo()
{
Version = "1.0.0",
Title = "Swagger Petstore",
Description = "This is a sample server Petstore API designed by [http://swagger.io](http://swagger.io).",
TermsOfService = new Uri("https://github.com/Azure/azure-functions-openapi-extension"),
Contact = new OpenApiContact()
{
Name = "Enquiry",
Email = "[email protected]",
Url = new Uri("https://github.com/Azure/azure-functions-openapi-extension/issues"),
},
License = new OpenApiLicense()
{
Name = "MIT",
Url = new Uri("http://opensource.org/licenses/MIT"),
}
},
Servers = DefaultOpenApiConfigurationOptions.GetHostNames(),
OpenApiVersion = OpenApiVersionType.V2,
IncludeRequestingHostName = true,
ForceHttps = false,
ForceHttp = false,
};

return options;
});
})
/* ⬆️⬆️⬆️ Add this ⬆️⬆️⬆️ */
.Build();

host.Run();
}
}
}
```
2 changes: 1 addition & 1 deletion docs/openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ As a default, all endpoints to render Swagger UI and OpenAPI documents have the
}
```

You can have granular controls to both Swagger UI and OpenAPI documents by setting the authorisation level to `Anonymous`, `User`, `Function`, `System` or `Admin`. Make sure that you MUST provide the `OpenApi__AuthKey` value, if you choose the `OpenApi__AuthLevel__Document` value other than `Anonymous`. Otherwise, it will throw an error.
You can have granular controls to both Swagger UI and OpenAPI documents by setting the authorisation level to `Anonymous`, `User`, `Function`, `System` or `Admin`. Make sure that you MUST provide the `OpenApi__ApiKey` value, if you choose the `OpenApi__AuthLevel__Document` value other than `Anonymous`. Otherwise, it will throw an error.

> **NOTE**: Both Swagger UI and OpenAPI document pages are allowed `Anonymous` access by default.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi.FunctionApp.OutOfProc.Configurations
{
public class OpenApiConfigurationOptions : DefaultOpenApiConfigurationOptions
public class MyOpenApiConfigurationOptions : DefaultOpenApiConfigurationOptions
{
public override OpenApiInfo Info { get; set; } = new OpenApiInfo()
{
Version = GetOpenApiDocVersion(),
Title = GetOpenApiDocTitle(),
Description = "This is a sample server Petstore API designed by [http://swagger.io](http://swagger.io).",
Description = GetOpenApiDocDescription(),
TermsOfService = new Uri("https://github.com/Azure/azure-functions-openapi-extension"),
Contact = new OpenApiContact()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,62 @@
using AutoFixture;

using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Extensions;
using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.FunctionApp.OutOfProc.Configurations;
using System;

using AutoFixture;

using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Extensions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi.FunctionApp.OutOfProc
{
public class Program
{
public static void Main()
{
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson())
.ConfigureOpenApi()
.ConfigureServices(services => {
services.AddSingleton<Fixture>();
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;

namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi.FunctionApp.OutOfProc
{
public class Program
{
public static void Main()
{
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson())
.ConfigureOpenApi()
.ConfigureServices(services =>
{
services.AddSingleton<Fixture>()
.AddSingleton<IOpenApiConfigurationOptions>(_ =>
{
var options = new OpenApiConfigurationOptions()
{
Info = new OpenApiInfo()
{
Version = DefaultOpenApiConfigurationOptions.GetOpenApiDocVersion(),
Title = $"{DefaultOpenApiConfigurationOptions.GetOpenApiDocTitle()} (Injected)",
Description = DefaultOpenApiConfigurationOptions.GetOpenApiDocDescription(),
TermsOfService = new Uri("https://github.com/Azure/azure-functions-openapi-extension"),
Contact = new OpenApiContact()
{
Name = "Enquiry",
Email = "[email protected]",
Url = new Uri("https://github.com/Azure/azure-functions-openapi-extension/issues"),
},
License = new OpenApiLicense()
{
Name = "MIT",
Url = new Uri("http://opensource.org/licenses/MIT"),
}
},
Servers = DefaultOpenApiConfigurationOptions.GetHostNames(),
OpenApiVersion = DefaultOpenApiConfigurationOptions.GetOpenApiVersion(),
IncludeRequestingHostName = DefaultOpenApiConfigurationOptions.IsFunctionsRuntimeEnvironmentDevelopment(),
ForceHttps = DefaultOpenApiConfigurationOptions.IsHttpsForced(),
ForceHttp = DefaultOpenApiConfigurationOptions.IsHttpForced(),
};

// Example: If you want to change the configuration during startup of your function you can use the following code:
return options;
})
;
})
.Build();

//services.AddSingleton<IOpenApiConfigurationOptions>(x =>
//{
// return new OpenApiConfigurationOptions()
// {
// Info = new Microsoft.OpenApi.Models.OpenApiInfo
// {
// Title = "A dynamic title generated at runtime",
// Description = "Dynamic Open API information at runtime"
// }
// };
//});
})
.Build();

host.Run();
}
}
}
host.Run();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

"OpenApi__Version": "v3",
"OpenApi__DocVersion": "1.0.0",
"OpenApi__DocTitle": "Swagger Petstore"
"OpenApi__DocTitle": "Swagger Petstore",
"OpenApi__DocDescription": "This is a sample server Petstore API designed by [http://swagger.io](http://swagger.io)."
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
using System;

using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.OpenApi.Models;

namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.InProc.Configurations
{
public class OpenApiConfigurationOptions : DefaultOpenApiConfigurationOptions
public class MyOpenApiConfigurationOptions : DefaultOpenApiConfigurationOptions
{
public override OpenApiInfo Info { get; set; } = new OpenApiInfo()
{
Version = GetOpenApiDocVersion(),
Title = GetOpenApiDocTitle(),
Description = "This is a sample server Petstore API designed by [http://swagger.io](http://swagger.io).",
Description = GetOpenApiDocDescription(),
TermsOfService = new Uri("https://github.com/Azure/azure-functions-openapi-extension"),
Contact = new OpenApiContact()
{
Expand Down
Loading