Skip to content

Commit 0a432fb

Browse files
authored
Example for request/response payload (#95)
1 parent 6915cc6 commit 0a432fb

File tree

28 files changed

+545
-14
lines changed

28 files changed

+545
-14
lines changed

samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models/Category.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
2+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models.Examples;
3+
14
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
25
{
36
/// <summary>
47
/// This represents the model entity for category of Swagger Pet Store.
58
/// </summary>
9+
[OpenApiExample(typeof(CategoryExample))]
610
public class Category
711
{
812
/// <summary>

samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models/DummyStringModel.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
using System;
22

3+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
4+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models.Examples;
5+
36
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
47
{
8+
[OpenApiExample(typeof(DummyStringModelExample))]
59
public class DummyStringModel
610
{
711
public string StringValue { get; set; }
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
2+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
3+
4+
using Newtonsoft.Json.Serialization;
5+
6+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models.Examples
7+
{
8+
public class CategoryExample : OpenApiExample<Category>
9+
{
10+
public override IOpenApiExample<Category> Build(NamingStrategy namingStrategy = null)
11+
{
12+
this.Examples.Add(OpenApiExampleResolver.Resolve("first", new Category() { Id = (long)123, Name = "Hello World" }, namingStrategy));
13+
14+
return this;
15+
}
16+
}
17+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System;
2+
3+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
4+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
5+
6+
using Newtonsoft.Json.Serialization;
7+
8+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models.Examples
9+
{
10+
public class DummyStringModelExample : OpenApiExample<DummyStringModel>
11+
{
12+
public override IOpenApiExample<DummyStringModel> Build(NamingStrategy namingStrategy = null)
13+
{
14+
this.Examples.Add(OpenApiExampleResolver.Resolve("lorem", new DummyStringModel() { StringValue = "Hello World", UriValue = new Uri("http://localhost:80") }, namingStrategy));
15+
this.Examples.Add(OpenApiExampleResolver.Resolve("ipsum", new DummyStringModel() { StringValue = "Hello World 2", UriValue = new Uri("https://localhost:443") }, namingStrategy));
16+
17+
return this;
18+
}
19+
}
20+
}

samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static/DummyHttpTrigger.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
99
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
1010
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models;
11+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models.Examples;
12+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static.Examples;
1113
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static.ResponseHeaders;
1214
using Microsoft.Extensions.Logging;
1315
using Microsoft.OpenApi.Models;
@@ -58,9 +60,10 @@ public static async Task<IActionResult> AddDummy(
5860
[FunctionName(nameof(DummyHttpTrigger.UpdateDummies))]
5961
[OpenApiOperation(operationId: "updateDummies", tags: new[] { "dummy" }, Summary = "Updates a list of dummies", Description = "This updates a list of dummies.", Visibility = OpenApiVisibilityType.Advanced)]
6062
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
61-
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyListModel), Required = true, Description = "Dummy list model")]
63+
[OpenApiRequestBody(contentType: "application/json", bodyType: typeof(DummyListModel), Example = typeof(DummyListModelExample), Required = true, Description = "Dummy list model")]
64+
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DummyArrayResponseModel), Summary = "Dummy response", Description = "This returns the dummy response", Deprecated = true, CustomHeaderType = typeof(DummyResponseHeader))]
6265
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(List<DummyStringModel>), Summary = "Dummy response", Description = "This returns the dummy response", CustomHeaderType = typeof(DummyResponseHeader))]
63-
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DummyStringModel), Summary = "Dummy response", Description = "This returns the dummy response", Deprecated = true, CustomHeaderType = typeof(DummyResponseHeader))]
66+
[OpenApiResponseWithBody(statusCode: HttpStatusCode.Created, contentType: "application/json", bodyType: typeof(DummyStringModel), Example = typeof(DummyStringModelExample), Summary = "Dummy response", Description = "This returns the dummy response", CustomHeaderType = typeof(DummyResponseHeader))]
6467
public static async Task<IActionResult> UpdateDummies(
6568
[HttpTrigger(AuthorizationLevel.Function, "PUT", Route = "dummies")] HttpRequest req,
6669
ILogger log)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
5+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
6+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models;
7+
8+
using Newtonsoft.Json.Serialization;
9+
10+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static.Examples
11+
{
12+
public class DummyListModelExample : OpenApiExample<DummyListModel>
13+
{
14+
public override IOpenApiExample<DummyListModel> Build(NamingStrategy namingStrategy = null)
15+
{
16+
this.Examples.Add(
17+
OpenApiExampleResolver.Resolve(
18+
"dummy",
19+
new DummyListModel()
20+
{
21+
ListValues = new List<DummyStringModel>() { new DummyStringModel() { StringValue = "Hello World", UriValue = new Uri("https://localhost") } }
22+
},
23+
namingStrategy
24+
));
25+
26+
return this;
27+
}
28+
}
29+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System.Collections.Generic;
2+
3+
using Microsoft.OpenApi.Models;
4+
5+
using Newtonsoft.Json.Serialization;
6+
7+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions
8+
{
9+
/// <summary>
10+
/// This provides interfaces to classes to render example data.
11+
/// </summary>
12+
/// <typeparam name="T">Type of the example object.</typeparam>
13+
public interface IOpenApiExample<T>
14+
{
15+
/// <summary>
16+
/// Gets the collection of the <see cref="OpenApiExample"/> objects.
17+
/// </summary>
18+
IDictionary<string, OpenApiExample> Examples { get; }
19+
20+
/// <summary>
21+
/// Builds the example.
22+
/// </summary>
23+
/// <param name="namingStrategy"><see cref="NamingStrategy"/> instance.</param>
24+
/// <returns>Returns <see cref="IOpenApiExample{T}"/> instance.</returns>
25+
IOpenApiExample<T> Build(NamingStrategy namingStrategy = null);
26+
}
27+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Collections.Generic;
2+
3+
using Microsoft.OpenApi.Models;
4+
5+
using Newtonsoft.Json.Serialization;
6+
7+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions
8+
{
9+
/// <summary>
10+
/// This represents the example entity for models. This MUST be inherited.
11+
/// </summary>
12+
/// <typeparam name="T">Type of model as an example.</typeparam>
13+
public abstract class OpenApiExample<T> : IOpenApiExample<T>
14+
{
15+
/// <inheritdoc />
16+
public IDictionary<string, OpenApiExample> Examples { get; } = new Dictionary<string, OpenApiExample>();
17+
18+
/// <inheritdoc />
19+
public abstract IOpenApiExample<T> Build(NamingStrategy namingStrategy = null);
20+
}
21+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
3+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
4+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
5+
6+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes
7+
{
8+
/// <summary>
9+
/// This represents the attribute entity for the example.
10+
/// </summary>
11+
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
12+
public class OpenApiExampleAttribute : Attribute
13+
{
14+
/// <summary>
15+
/// Initializes a new instance of the <see cref="OpenApiExampleAttribute"/> class.
16+
/// </summary>
17+
public OpenApiExampleAttribute(Type example)
18+
{
19+
this.Example = example.ThrowIfNullOrDefault();
20+
}
21+
22+
/// <summary>
23+
/// Gets the type of the example. It SHOULD be inheriting the <see cref="OpenApiExample{T}"/> class.
24+
/// </summary>
25+
public virtual Type Example { get; }
26+
}
27+
}

src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Attributes/OpenApiPayloadAttribute.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
22

3+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
4+
35
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes
46
{
57
/// <summary>
@@ -32,5 +34,10 @@ protected OpenApiPayloadAttribute(string contentType, Type bodyType)
3234
/// Gets or sets the description.
3335
/// </summary>
3436
public virtual string Description { get; set; }
37+
38+
/// <summary>
39+
/// Gets or sets the type of the example. It SHOULD be inheriting the <see cref="OpenApiExample{T}"/> class.
40+
/// </summary>
41+
public virtual Type Example { get; set; }
3542
}
3643
}

0 commit comments

Comments
 (0)