Skip to content

Commit 9072106

Browse files
authored
More DI feature for OpenApiConfigurationOptions (#466)
1 parent 1ac4a84 commit 9072106

File tree

26 files changed

+1127
-661
lines changed

26 files changed

+1127
-661
lines changed

docs/openapi-core.md

+8-59
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ If the above conditions are met, add the following key to your `local.settings.j
6666
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:
6767

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

104104
```csharp
105-
public class OpenApiConfigurationOptions : IOpenApiConfigurationOptions
105+
public class MyOpenApiConfigurationOptions : IOpenApiConfigurationOptions
106106
{
107107
...
108108

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

129129
```csharp
130-
public class OpenApiConfigurationOptions : IOpenApiConfigurationOptions
130+
public class MyOpenApiConfigurationOptions : IOpenApiConfigurationOptions
131131
{
132132
...
133133

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

147147
```csharp
148-
public class OpenApiConfigurationOptions : IOpenApiConfigurationOptions
148+
public class MyOpenApiConfigurationOptions : IOpenApiConfigurationOptions
149149
{
150150
...
151151

@@ -198,65 +198,14 @@ public class MyOpenApiConfigurationOptions : DefaultOpenApiConfigurationOptions
198198
}
199199
```
200200

201-
### Dynamically configuring `IOpenApiConfigurationOptions` at Runtime ###
202201

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

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

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

209-
```csharp
210-
public override void Configure(IFunctionsHostBuilder builder)
211-
{
212-
var fixture = new Fixture();
213-
builder.Services.AddSingleton(fixture);
214-
215-
// Example: If you want to change the configuration during startup of your function you can use the following code:
216-
services.AddSingleton<IOpenApiConfigurationOptions>(x =>
217-
{
218-
return new OpenApiConfigurationOptions()
219-
{
220-
Info = new Microsoft.OpenApi.Models.OpenApiInfo
221-
{
222-
Title = "A dynamic title generated at runtime",
223-
Description = "Dynamic Open API information at runtime"
224-
}
225-
};
226-
});
227-
}
228-
```
229-
230-
#### Out of Proc ####
231-
232-
```csharp
233-
public static void Main()
234-
{
235-
var host = new HostBuilder()
236-
.ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson())
237-
.ConfigureOpenApi()
238-
.ConfigureServices(services => services.AddSingleton<Fixture>())
239-
.ConfigureServices(services => {
240-
services.AddSingleton<Fixture>();
241-
242-
// Example: If you want to change the configuration during startup of your function you can use the following code:
243-
services.AddSingleton<IOpenApiConfigurationOptions>(x =>
244-
{
245-
return new OpenApiConfigurationOptions()
246-
{
247-
Info = new Microsoft.OpenApi.Models.OpenApiInfo
248-
{
249-
Title = "A dynamic title generated at runtime",
250-
Description = "Dynamic Open API information at runtime"
251-
}
252-
};
253-
});
254-
})
255-
.Build();
256-
257-
host.Run();
258-
}
259-
```
260209

261210
## Swagger UI Customisation ##
262211

docs/openapi-in-proc.md

+49
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,52 @@ For detailed getting started document, find this [Enable OpenAPI Endpoints on Az
3131
## Advanced Configuration in General ##
3232

3333
If you look for the advanced configurations in general, please find the document, [Advanced Configurations for OpenAPI Extension](./openapi.md)
34+
35+
36+
### Injecting `OpenApiConfigurationOptions` during Startup ###
37+
38+
You may want to inject the `OpenApiConfigurationOptions` instance during startup, through the `Startup.cs` class. Here's the example:
39+
40+
```csharp
41+
[assembly: FunctionsStartup(typeof(MyFunctionApp.Startup))]
42+
namespace MyFunctionApp
43+
{
44+
public class Startup : FunctionsStartup
45+
{
46+
public override void Configure(IFunctionsHostBuilder builder)
47+
{
48+
builder.Services.AddSingleton<IOpenApiConfigurationOptions>(_ =>
49+
{
50+
var options = new OpenApiConfigurationOptions()
51+
{
52+
Info = new OpenApiInfo()
53+
{
54+
Version = "1.0.0",
55+
Title = "Swagger Petstore",
56+
Description = "This is a sample server Petstore API designed by [http://swagger.io](http://swagger.io).",
57+
TermsOfService = new Uri("https://github.com/Azure/azure-functions-openapi-extension"),
58+
Contact = new OpenApiContact()
59+
{
60+
Name = "Enquiry",
61+
Email = "[email protected]",
62+
Url = new Uri("https://github.com/Azure/azure-functions-openapi-extension/issues"),
63+
},
64+
License = new OpenApiLicense()
65+
{
66+
Name = "MIT",
67+
Url = new Uri("http://opensource.org/licenses/MIT"),
68+
}
69+
},
70+
Servers = DefaultOpenApiConfigurationOptions.GetHostNames(),
71+
OpenApiVersion = OpenApiVersionType.V2,
72+
IncludeRequestingHostName = true,
73+
ForceHttps = false,
74+
ForceHttp = false,
75+
};
76+
77+
return options;
78+
});
79+
}
80+
}
81+
}
82+
```

docs/openapi-out-of-proc.md

+59
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,62 @@ For detailed getting started document, find this [Enable OpenAPI Endpoints on Az
2525
## Advanced Configuration in General ##
2626

2727
If you look for the advanced configurations in general, please find the document, [Advanced Configurations for OpenAPI Extension](./openapi.md)
28+
29+
30+
### Injecting `OpenApiConfigurationOptions` during Startup ###
31+
32+
You may want to inject the `OpenApiConfigurationOptions` instance during startup, through the `Program.cs` class. Here's the example:
33+
34+
```csharp
35+
namespace MyFunctionApp
36+
{
37+
public class Program
38+
{
39+
public static void Main()
40+
{
41+
var host = new HostBuilder()
42+
.ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson())
43+
.ConfigureOpenApi()
44+
/* ⬇️⬇️⬇️ Add this ⬇️⬇️⬇️ */
45+
.ConfigureServices(services =>
46+
{
47+
services.AddSingleton<IOpenApiConfigurationOptions>(_ =>
48+
{
49+
var options = new OpenApiConfigurationOptions()
50+
{
51+
Info = new OpenApiInfo()
52+
{
53+
Version = "1.0.0",
54+
Title = "Swagger Petstore",
55+
Description = "This is a sample server Petstore API designed by [http://swagger.io](http://swagger.io).",
56+
TermsOfService = new Uri("https://github.com/Azure/azure-functions-openapi-extension"),
57+
Contact = new OpenApiContact()
58+
{
59+
Name = "Enquiry",
60+
Email = "[email protected]",
61+
Url = new Uri("https://github.com/Azure/azure-functions-openapi-extension/issues"),
62+
},
63+
License = new OpenApiLicense()
64+
{
65+
Name = "MIT",
66+
Url = new Uri("http://opensource.org/licenses/MIT"),
67+
}
68+
},
69+
Servers = DefaultOpenApiConfigurationOptions.GetHostNames(),
70+
OpenApiVersion = OpenApiVersionType.V2,
71+
IncludeRequestingHostName = true,
72+
ForceHttps = false,
73+
ForceHttp = false,
74+
};
75+
76+
return options;
77+
});
78+
})
79+
/* ⬆️⬆️⬆️ Add this ⬆️⬆️⬆️ */
80+
.Build();
81+
82+
host.Run();
83+
}
84+
}
85+
}
86+
```

docs/openapi.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ As a default, all endpoints to render Swagger UI and OpenAPI documents have the
2727
}
2828
```
2929

30-
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.
30+
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.
3131

3232
> **NOTE**: Both Swagger UI and OpenAPI document pages are allowed `Anonymous` access by default.
3333
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66

77
namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi.FunctionApp.OutOfProc.Configurations
88
{
9-
public class OpenApiConfigurationOptions : DefaultOpenApiConfigurationOptions
9+
public class MyOpenApiConfigurationOptions : DefaultOpenApiConfigurationOptions
1010
{
1111
public override OpenApiInfo Info { get; set; } = new OpenApiInfo()
1212
{
1313
Version = GetOpenApiDocVersion(),
1414
Title = GetOpenApiDocTitle(),
15-
Description = "This is a sample server Petstore API designed by [http://swagger.io](http://swagger.io).",
15+
Description = GetOpenApiDocDescription(),
1616
TermsOfService = new Uri("https://github.com/Azure/azure-functions-openapi-extension"),
1717
Contact = new OpenApiContact()
1818
{
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,62 @@
1-
using AutoFixture;
2-
3-
using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Extensions;
4-
using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.FunctionApp.OutOfProc.Configurations;
1+
using System;
2+
3+
using AutoFixture;
4+
5+
using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Extensions;
56
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
6-
using Microsoft.Extensions.DependencyInjection;
7-
using Microsoft.Extensions.Hosting;
8-
9-
namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi.FunctionApp.OutOfProc
10-
{
11-
public class Program
12-
{
13-
public static void Main()
14-
{
15-
var host = new HostBuilder()
16-
.ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson())
17-
.ConfigureOpenApi()
18-
.ConfigureServices(services => {
19-
services.AddSingleton<Fixture>();
7+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
8+
using Microsoft.Extensions.DependencyInjection;
9+
using Microsoft.Extensions.Hosting;
10+
using Microsoft.OpenApi.Models;
11+
12+
namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi.FunctionApp.OutOfProc
13+
{
14+
public class Program
15+
{
16+
public static void Main()
17+
{
18+
var host = new HostBuilder()
19+
.ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson())
20+
.ConfigureOpenApi()
21+
.ConfigureServices(services =>
22+
{
23+
services.AddSingleton<Fixture>()
24+
.AddSingleton<IOpenApiConfigurationOptions>(_ =>
25+
{
26+
var options = new OpenApiConfigurationOptions()
27+
{
28+
Info = new OpenApiInfo()
29+
{
30+
Version = DefaultOpenApiConfigurationOptions.GetOpenApiDocVersion(),
31+
Title = $"{DefaultOpenApiConfigurationOptions.GetOpenApiDocTitle()} (Injected)",
32+
Description = DefaultOpenApiConfigurationOptions.GetOpenApiDocDescription(),
33+
TermsOfService = new Uri("https://github.com/Azure/azure-functions-openapi-extension"),
34+
Contact = new OpenApiContact()
35+
{
36+
Name = "Enquiry",
37+
Email = "[email protected]",
38+
Url = new Uri("https://github.com/Azure/azure-functions-openapi-extension/issues"),
39+
},
40+
License = new OpenApiLicense()
41+
{
42+
Name = "MIT",
43+
Url = new Uri("http://opensource.org/licenses/MIT"),
44+
}
45+
},
46+
Servers = DefaultOpenApiConfigurationOptions.GetHostNames(),
47+
OpenApiVersion = DefaultOpenApiConfigurationOptions.GetOpenApiVersion(),
48+
IncludeRequestingHostName = DefaultOpenApiConfigurationOptions.IsFunctionsRuntimeEnvironmentDevelopment(),
49+
ForceHttps = DefaultOpenApiConfigurationOptions.IsHttpsForced(),
50+
ForceHttp = DefaultOpenApiConfigurationOptions.IsHttpForced(),
51+
};
2052

21-
// Example: If you want to change the configuration during startup of your function you can use the following code:
53+
return options;
54+
})
55+
;
56+
})
57+
.Build();
2258

23-
//services.AddSingleton<IOpenApiConfigurationOptions>(x =>
24-
//{
25-
// return new OpenApiConfigurationOptions()
26-
// {
27-
// Info = new Microsoft.OpenApi.Models.OpenApiInfo
28-
// {
29-
// Title = "A dynamic title generated at runtime",
30-
// Description = "Dynamic Open API information at runtime"
31-
// }
32-
// };
33-
//});
34-
})
35-
.Build();
36-
37-
host.Run();
38-
}
39-
}
40-
}
59+
host.Run();
60+
}
61+
}
62+
}

samples/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.FunctionApp.OutOfProc/local.settings.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
"OpenApi__Version": "v3",
88
"OpenApi__DocVersion": "1.0.0",
9-
"OpenApi__DocTitle": "Swagger Petstore"
9+
"OpenApi__DocTitle": "Swagger Petstore",
10+
"OpenApi__DocDescription": "This is a sample server Petstore API designed by [http://swagger.io](http://swagger.io)."
1011
}
1112
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
using System;
2+
23
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
34
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
45
using Microsoft.OpenApi.Models;
56

67
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.InProc.Configurations
78
{
8-
public class OpenApiConfigurationOptions : DefaultOpenApiConfigurationOptions
9+
public class MyOpenApiConfigurationOptions : DefaultOpenApiConfigurationOptions
910
{
1011
public override OpenApiInfo Info { get; set; } = new OpenApiInfo()
1112
{
1213
Version = GetOpenApiDocVersion(),
1314
Title = GetOpenApiDocTitle(),
14-
Description = "This is a sample server Petstore API designed by [http://swagger.io](http://swagger.io).",
15+
Description = GetOpenApiDocDescription(),
1516
TermsOfService = new Uri("https://github.com/Azure/azure-functions-openapi-extension"),
1617
Contact = new OpenApiContact()
1718
{

0 commit comments

Comments
 (0)