Skip to content

Commit 996d418

Browse files
Refactor XML comment support to support more standard tags and enable build-time OpenAPI document generation
1 parent b5a54d2 commit 996d418

File tree

19 files changed

+730
-333
lines changed

19 files changed

+730
-333
lines changed

examples/AspNetCore/WebApi/MinimalOpenApiExample/MinimalOpenApiExample.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10+
<PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="10.0.*">
11+
<PrivateAssets>all</PrivateAssets>
12+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
13+
</PackageReference>
1014
<PackageReference Include="Scalar.AspNetCore" Version="2.12.*" />
1115
<PackageReference Include="Scalar.AspNetCore.Microsoft" Version="2.12.*" />
1216
</ItemGroup>
1317

1418
<ItemGroup>
15-
<ProjectReference Include="..\..\..\..\src\AspNetCore\WebApi\src\Asp.Versioning.OpenApi\Asp.Versioning.OpenApi.csproj" />
19+
<ProjectReference Include="..\..\..\..\src\AspNetCore\WebApi\src\Asp.Versioning.OpenApi\Asp.Versioning.OpenApi.csproj" />
1620
</ItemGroup>
1721

1822
</Project>

examples/AspNetCore/WebApi/MinimalOpenApiExample/Program.cs

Lines changed: 3 additions & 254 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
using Asp.Versioning;
22
using Scalar.AspNetCore;
3+
using ApiVersioning.Examples.Services;
34
using System.Reflection;
4-
using OrderV1 = ApiVersioning.Examples.Models.V1.Order;
5-
using OrderV2 = ApiVersioning.Examples.Models.V2.Order;
6-
using OrderV3 = ApiVersioning.Examples.Models.V3.Order;
7-
using PersonV1 = ApiVersioning.Examples.Models.V1.Person;
8-
using PersonV2 = ApiVersioning.Examples.Models.V2.Person;
9-
using PersonV3 = ApiVersioning.Examples.Models.V3.Person;
105

116
[assembly: AssemblyDescription( "An example API" )]
127

@@ -45,255 +40,9 @@
4540
.EnableApiVersionBinding();
4641

4742
var app = builder.Build();
48-
var orders = app.NewVersionedApi( "Orders" );
49-
var people = app.NewVersionedApi( "People" );
5043

51-
// 1.0
52-
var ordersV1 = orders.MapGroup( "/api/orders" )
53-
.HasDeprecatedApiVersion( 0.9 )
54-
.HasApiVersion( 1.0 );
55-
56-
ordersV1.MapGet( "/{id:int}", ( int id ) => new OrderV1() { Id = id, Customer = "John Doe" } )
57-
.WithSummary( "Get Order" )
58-
.WithDescription( "Gets a single order." )
59-
.Produces<OrderV1>()
60-
.Produces( 404 );
61-
62-
ordersV1.MapPost( "/", ( HttpRequest request, OrderV1 order ) =>
63-
{
64-
order.Id = 42;
65-
var scheme = request.Scheme;
66-
var host = request.Host;
67-
var location = new Uri( $"{scheme}{Uri.SchemeDelimiter}{host}/api/orders/{order.Id}" );
68-
return Results.Created( location, order );
69-
} )
70-
.WithSummary( "Place Order" )
71-
.WithDescription( "Places a new order." )
72-
.Accepts<OrderV1>( "application/json" )
73-
.Produces<OrderV1>( 201 )
74-
.Produces( 400 )
75-
.MapToApiVersion( 1.0 );
76-
77-
ordersV1.MapPatch( "/{id:int}", ( int id, OrderV1 order ) => Results.NoContent() )
78-
.WithSummary( "Update Order" )
79-
.WithDescription( "Updates an order." )
80-
.Accepts<OrderV1>( "application/json" )
81-
.Produces( 204 )
82-
.Produces( 400 )
83-
.Produces( 404 )
84-
.MapToApiVersion( 1.0 );
85-
86-
// 2.0
87-
var ordersV2 = orders.MapGroup( "/api/orders" )
88-
.HasApiVersion( 2.0 );
89-
90-
ordersV2.MapGet( "/", () =>
91-
new OrderV2[]
92-
{
93-
new(){ Id = 1, Customer = "John Doe" },
94-
new(){ Id = 2, Customer = "Bob Smith" },
95-
new(){ Id = 3, Customer = "Jane Doe", EffectiveDate = DateTimeOffset.UtcNow.AddDays( 7d ) },
96-
} )
97-
.WithSummary( "Get Orders" )
98-
.WithDescription( "Retrieves all orders." )
99-
.Produces<IEnumerable<OrderV2>>()
100-
.Produces( 404 );
101-
102-
ordersV2.MapGet( "/{id:int}", ( int id ) => new OrderV2() { Id = id, Customer = "John Doe" } )
103-
.WithSummary( "Get Order" )
104-
.WithDescription( "Gets a single order." )
105-
.Produces<OrderV2>()
106-
.Produces( 404 );
107-
108-
ordersV2.MapPost( "/", ( HttpRequest request, OrderV2 order ) =>
109-
{
110-
order.Id = 42;
111-
var scheme = request.Scheme;
112-
var host = request.Host;
113-
var location = new Uri( $"{scheme}{Uri.SchemeDelimiter}{host}/api/orders/{order.Id}" );
114-
return Results.Created( location, order );
115-
} )
116-
.WithSummary( "Place Order" )
117-
.WithDescription( "Places a new order." )
118-
.Accepts<OrderV2>( "application/json" )
119-
.Produces<OrderV2>( 201 )
120-
.Produces( 400 );
121-
122-
123-
ordersV2.MapPatch( "/{id:int}", ( int id, OrderV2 order ) => Results.NoContent() )
124-
.WithSummary( "Update Order" )
125-
.WithDescription( "Updates an order." )
126-
.Accepts<OrderV2>( "application/json" )
127-
.Produces( 204 )
128-
.Produces( 400 )
129-
.Produces( 404 );
130-
131-
// 3.0
132-
var ordersV3 = orders.MapGroup( "/api/orders" )
133-
.HasApiVersion( 3.0 );
134-
135-
ordersV3.MapGet( "/", () =>
136-
new OrderV3[]
137-
{
138-
new(){ Id = 1, Customer = "John Doe" },
139-
new(){ Id = 2, Customer = "Bob Smith" },
140-
new(){ Id = 3, Customer = "Jane Doe", EffectiveDate = DateTimeOffset.UtcNow.AddDays( 7d ) },
141-
} )
142-
.WithSummary( "Get Orders" )
143-
.WithDescription( "Retrieves all orders." )
144-
.Produces<IEnumerable<OrderV3>>();
145-
146-
ordersV3.MapGet( "/{id:int}", ( int id ) => new OrderV3() { Id = id, Customer = "John Doe" } )
147-
.WithSummary( "Get Order" )
148-
.WithDescription( "Gets a single order." )
149-
.Produces<OrderV3>()
150-
.Produces( 404 );
151-
152-
ordersV3.MapPost( "/", ( HttpRequest request, OrderV3 order ) =>
153-
{
154-
order.Id = 42;
155-
var scheme = request.Scheme;
156-
var host = request.Host;
157-
var location = new Uri( $"{scheme}{Uri.SchemeDelimiter}{host}/api/orders/{order.Id}" );
158-
return Results.Created( location, order );
159-
} )
160-
.WithSummary( "Place Order" )
161-
.WithDescription( "Places a new order." )
162-
.Accepts<OrderV3>( "application/json" )
163-
.Produces<OrderV3>( 201 )
164-
.Produces( 400 );
165-
166-
ordersV3.MapDelete( "/{id:int}", ( int id ) => Results.NoContent() )
167-
.WithSummary( "Cancel Order" )
168-
.WithDescription( "Cancels an order." )
169-
.Produces( 204 );
170-
171-
// 1.0
172-
var peopleV1 = people.MapGroup( "/api/v{version:apiVersion}/people" )
173-
.HasDeprecatedApiVersion( 0.9 )
174-
.HasApiVersion( 1.0 );
175-
176-
peopleV1.MapGet( "/{id:int}", ( int id ) =>
177-
new PersonV1()
178-
{
179-
Id = id,
180-
FirstName = "John",
181-
LastName = "Doe",
182-
} )
183-
.WithSummary( "Get Person" )
184-
.WithDescription( "Gets a single person." )
185-
.Produces<PersonV1>()
186-
.Produces( 404 );
187-
188-
// 2.0
189-
var peopleV2 = people.MapGroup( "/api/v{version:apiVersion}/people" )
190-
.HasApiVersion( 2.0 );
191-
192-
peopleV2.MapGet( "/", () =>
193-
new PersonV2[]
194-
{
195-
new()
196-
{
197-
Id = 1,
198-
FirstName = "John",
199-
LastName = "Doe",
200-
Email = "john.doe@somewhere.com",
201-
},
202-
new()
203-
{
204-
Id = 2,
205-
FirstName = "Bob",
206-
LastName = "Smith",
207-
Email = "bob.smith@somewhere.com",
208-
},
209-
new()
210-
{
211-
Id = 3,
212-
FirstName = "Jane",
213-
LastName = "Doe",
214-
Email = "jane.doe@somewhere.com",
215-
},
216-
} )
217-
.WithSummary( "Get People" )
218-
.WithDescription( "Gets all people." )
219-
.Produces<IEnumerable<PersonV2>>();
220-
221-
peopleV2.MapGet( "/{id:int}", ( int id ) =>
222-
new PersonV2()
223-
{
224-
Id = id,
225-
FirstName = "John",
226-
LastName = "Doe",
227-
Email = "john.doe@somewhere.com",
228-
} )
229-
.WithSummary( "Get Person" )
230-
.WithDescription( "Gets a single person." )
231-
.Produces<PersonV2>()
232-
.Produces( 404 );
233-
234-
// 3.0
235-
var peopleV3 = people.MapGroup( "/api/v{version:apiVersion}/people" )
236-
.HasApiVersion( 3.0 );
237-
238-
peopleV3.MapGet( "/", () =>
239-
new PersonV3[]
240-
{
241-
new()
242-
{
243-
Id = 1,
244-
FirstName = "John",
245-
LastName = "Doe",
246-
Email = "john.doe@somewhere.com",
247-
Phone = "555-987-1234",
248-
},
249-
new()
250-
{
251-
Id = 2,
252-
FirstName = "Bob",
253-
LastName = "Smith",
254-
Email = "bob.smith@somewhere.com",
255-
Phone = "555-654-4321",
256-
},
257-
new()
258-
{
259-
Id = 3,
260-
FirstName = "Jane",
261-
LastName = "Doe",
262-
Email = "jane.doe@somewhere.com",
263-
Phone = "555-789-3456",
264-
},
265-
} )
266-
.WithSummary( "Get People" )
267-
.WithDescription( "Gets all people." )
268-
.Produces<IEnumerable<PersonV3>>();
269-
270-
peopleV3.MapGet( "/{id:int}", ( int id ) =>
271-
new PersonV3()
272-
{
273-
Id = id,
274-
FirstName = "John",
275-
LastName = "Doe",
276-
Email = "john.doe@somewhere.com",
277-
Phone = "555-987-1234",
278-
} )
279-
.WithSummary( "Get Person" )
280-
.WithDescription( "Gets a single person." )
281-
.Produces<PersonV3>()
282-
.Produces( 404 );
283-
284-
peopleV3.MapPost( "/", ( HttpRequest request, ApiVersion version, PersonV3 person ) =>
285-
{
286-
person.Id = 42;
287-
var scheme = request.Scheme;
288-
var host = request.Host;
289-
var location = new Uri( $"{scheme}{Uri.SchemeDelimiter}{host}/v{version}/api/people/{person.Id}" );
290-
return Results.Created( location, person );
291-
} )
292-
.WithSummary( "Add Person" )
293-
.WithDescription( "Adds a new person." )
294-
.Accepts<PersonV3>( "application/json" )
295-
.Produces<PersonV3>( 201 )
296-
.Produces( 400 );
44+
app.MapOrders().ToV1().ToV2().ToV3();
45+
app.MapPeople().ToV1().ToV2().ToV3();
29746

29847
if ( app.Environment.IsDevelopment() )
29948
{
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace ApiVersioning.Examples.Services;
2+
3+
/// <summary>
4+
/// Represents an API builder.
5+
/// </summary>
6+
public static class ApiBuilder
7+
{
8+
extension( IEndpointRouteBuilder app )
9+
{
10+
/// <summary>
11+
/// Creates and returns an API builder for the Orders service.
12+
/// </summary>
13+
/// <returns>A new <see cref="OrdersApiBuilder">Orders API builder</see>.</returns>
14+
public OrdersApiBuilder MapOrders() => new( app.NewVersionedApi( "Orders" ) );
15+
16+
/// <summary>
17+
/// Creates and returns an API builder for the Orders service.
18+
/// </summary>
19+
/// <returns>A new <see cref="OrdersApiBuilder">Orders API builder</see>.</returns>
20+
public PeopleApiBuilder MapPeople() => new( app.NewVersionedApi( "People" ) );
21+
}
22+
}

0 commit comments

Comments
 (0)