Skip to content

Commit ad40788

Browse files
committed
enhance testing section with http files and swagger
1 parent b327c62 commit ad40788

File tree

6 files changed

+237
-62
lines changed

6 files changed

+237
-62
lines changed

Diff for: aspnetcore/tutorials/first-mongo-app.md

+211-17
Original file line numberDiff line numberDiff line change
@@ -265,41 +265,235 @@ The preceding web API controller:
265265

266266
## Test the web API
267267

268+
# [Visual Studio](#tab/visual-studio)
269+
270+
This tutorial uses [Endpoints Explorer and .http files](xref:test/http-files#use-endpoints-explorer) to test the API.
271+
268272
1. Build and run the app.
269273

270-
1. Navigate to `https://localhost:<port>/api/books`, where `<port>` is the automatically assigned port number for the app, to test the controller's parameterless `Get` action method. A JSON response similar to the following is displayed:
274+
1. In **Endpoints Explorer**, right-click the first **GET** endpoint `/api/books`, and select **Generate request**.
275+
276+
The following content is added to the `BookStoreApi.http` file.
277+
If this is the first time that a request is generated, the file is created in the project root.
278+
279+
```
280+
@BookStoreApi_HostAddress = https://localhost:<port>
281+
282+
GET {{BookStoreApi_HostAddress}}/api/books
283+
284+
###
285+
```
286+
287+
The port number should already be set to the port used by the app, for example, `https://localhost:56874`.
288+
If that's not the case you can find your port number in the output window when you launch the app.
289+
290+
1. Select the **Send request** link above the new `GET` request line.
291+
292+
The GET request is sent to the app and the response is displayed in the **Response** pane.
293+
294+
1. The response body shows the JSON result containing the book entries similar to the following:
271295

272296
```json
273297
[
274298
{
275-
"id": "61a6058e6c43f32854e51f51",
276-
"bookName": "Design Patterns",
277-
"price": 54.93,
278-
"category": "Computers",
279-
"author": "Ralph Johnson"
299+
"Id": "61a6058e6c43f32854e51f51",
300+
"Name": "Design Patterns",
301+
"Price": 54.93,
302+
"Category": "Computers",
303+
"Author": "Ralph Johnson"
280304
},
281305
{
282-
"id": "61a6058e6c43f32854e51f52",
283-
"bookName": "Clean Code",
284-
"price": 43.15,
285-
"category": "Computers",
286-
"author": "Robert C. Martin"
306+
"Id": "61a6058e6c43f32854e51f52",
307+
"Name": "Clean Code",
308+
"Price": 43.15,
309+
"Category": "Computers",
310+
"Author": "Robert C. Martin"
287311
}
288312
]
289313
```
290314

291-
1. Navigate to `https://localhost:<port>/api/books/{id here}` to test the controller's overloaded `Get` action method. A JSON response similar to the following is displayed:
315+
1. To retrieve a single book, right-click the `/api/books/{id}, params (string id)` **GET** endpoint in the **Endpoints Explorer**, and select **Generate request**.
316+
317+
The following content is appended to the `BookStoreApi.http` file:
318+
319+
```
320+
@id=string
321+
GET {{BookStoreApi_HostAddress}}/api/books/{{id}}
322+
323+
###
324+
```
325+
326+
1. Replace `id` variable with one of the IDs returned from the earlier request, for example:
327+
328+
```
329+
@id="61a6058e6c43f32854e51f52"
330+
GET {{BookStoreApi_HostAddress}}/api/books/{{id}}
331+
332+
###
333+
```
334+
335+
1. Select the **Send request** link above the new `GET` request line.
336+
337+
The GET request is sent to the app and the response is displayed in the **Response** pane.
338+
339+
1. The response body shows JSON similar to the following:
292340

293341
```json
294342
{
295-
"id": "61a6058e6c43f32854e51f52",
296-
"bookName": "Clean Code",
297-
"price": 43.15,
298-
"category": "Computers",
299-
"author": "Robert C. Martin"
343+
"Id": "61a6058e6c43f32854e51f52",
344+
"Name": "Clean Code",
345+
"Price": 43.15,
346+
"Category": "Computers",
347+
"Author": "Robert C. Martin"
300348
}
301349
```
302350

351+
1. To test the POST endpoint, right-click the `/api/books` **POST** endpoint and select **Generate request**.
352+
353+
The following content is added to the `BookStoreApi.http` file:
354+
355+
```
356+
POST {{BookStoreApi_HostAddress}}/api/books
357+
Content-Type: application/json
358+
359+
{
360+
//Book
361+
}
362+
363+
###
364+
```
365+
366+
1. Replace the Book comment with a book object as the JSON request body:
367+
368+
```
369+
POST {{BookStoreApi_HostAddress}}/api/books
370+
Content-Type: application/json
371+
372+
{
373+
"Name": "The Pragmatic Programmer",
374+
"Price": 49.99,
375+
"Category": "Computers",
376+
"Author": "Andy Hunt"
377+
}
378+
379+
###
380+
```
381+
382+
1. Select the **Send request** link above the `POST` request line.
383+
384+
The POST request is sent to the app, and the response is displayed in the **Response** pane. The response should include the newly created book with its assigned ID.
385+
386+
1. Lastly, to delete a book, right-click the `/api/books/{id}, params (string id)` **DELETE** endpoint and select **Generate request**.
387+
388+
The following content is appended to the `BookStoreApi.http` file:
389+
390+
```
391+
DELETE {{BookStoreApi_HostAddress}}/api/Books/{{id}}
392+
393+
###
394+
```
395+
396+
1. Replace the `id` variable with one of the IDs returned from the earlier request, and click **Send request**. For example:
397+
398+
```
399+
DELETE {{BookStoreApi_HostAddress}}/api/Books/67f417517ce1b36aeab71236
400+
401+
###
402+
```
403+
404+
# [Visual Studio Code](#tab/visual-studio-code)
405+
406+
This tutorial uses the [OpenAPI specification (openapi.json) and Swagger UI](xref:tutorials/web-api-help-pages-using-swagger) to test the API.
407+
408+
1. Install Swagger UI by running the following command:
409+
410+
```dotnetcli
411+
dotnet add package NSwag.AspNetCore
412+
```
413+
414+
The previous command adds the [NSwag.AspNetCore](https://www.nuget.org/packages/NSwag.AspNetCore/) package, which contains tools to generate Swagger documents and UI.
415+
Because our project is using OpenAPI, we only use the NSwag package to generate the Swagger UI.
416+
417+
1. Configure Swagger middleware
418+
419+
In `Program.cs`, add the following highlighted code:
420+
421+
:::code language="csharp" source="first-mongo-app/samples/9.x/BookStoreApi/Program.cs" id="snippet_UseSwagger" highlight="6-9":::
422+
423+
The previous code enables the Swagger middleware for serving the generated JSON document using the Swagger UI. Swagger is only enabled in a development environment. Enabling Swagger in a production environment could expose potentially sensitive details about the API's structure and implementation.
424+
425+
The app uses the OpenAPI document generated by OpenApi, located at `/openapi/v1.json`, to generate the UI.
426+
View the generated OpenAPI specification for the `WeatherForecast` API while the project is running by navigating to `https://localhost:<port>/openapi/v1.json` in your browser.
427+
428+
The OpenAPI specification is a document in JSON format that describes the structure and capabilities of your API, including endpoints, request/response formats, parameters, and more. It's essentially a blueprint of your API that can be used by various tools to understand and interact with your API.
429+
430+
1. Build and run the app.
431+
432+
1. Navigate to `https://localhost:<port>/swagger` in your browser. Swagger provides a UI to test all the API endpoints based on the OpenAPI document.
433+
434+
1. Expand the **GET /api/books** endpoint and click the **Try it out** button.
435+
436+
1. Click the **Execute** button to send the request to the API.
437+
438+
1. The **Response body** section displays a JSON array with books similar to the following:
439+
440+
```json
441+
[
442+
{
443+
"Id": "61a6058e6c43f32854e51f51",
444+
"Name": "Design Patterns",
445+
"Price": 54.93,
446+
"Category": "Computers",
447+
"Author": "Ralph Johnson"
448+
},
449+
{
450+
"Id": "61a6058e6c43f32854e51f52",
451+
"Name": "Clean Code",
452+
"Price": 43.15,
453+
"Category": "Computers",
454+
"Author": "Robert C. Martin"
455+
}
456+
]
457+
```
458+
459+
1. Next, expand the **GET /api/books/{id}** endpoint and click **Try it out**.
460+
461+
1. Enter one of the book IDs from the previous response in the **id** field, then click **Execute**.
462+
463+
1. The **Response body** section displays the JSON object for the specified book. For example, the result for the ID `61a6058e6c43f32854e51f52` is similar to the following:
464+
465+
```json
466+
{
467+
"Id": "61a6058e6c43f32854e51f52",
468+
"Name": "Clean Code",
469+
"Price": 43.15,
470+
"Category": "Computers",
471+
"Author": "Robert C. Martin"
472+
}
473+
```
474+
475+
1. To test creating a new book, expand the **POST /api/books** endpoint and click **Try it out**.
476+
477+
1. Replace the default request body with a new book object:
478+
479+
```json
480+
{
481+
"Name": "The Pragmatic Programmer",
482+
"Price": 49.99,
483+
"Category": "Computers",
484+
"Author": "Andy Hunt"
485+
}
486+
```
487+
488+
1. Click **Execute** to send the request.
489+
490+
1. The response should have a status code of 201 (Created) and include the newly created book with its assigned ID in the response body.
491+
492+
1. Lastly, to delete a book record, expand the **DELETE /api/books/{id}** endpoint, click **Try it out**, and enter one of the book IDs from the previous response in the **id** field. Click **Execute** to send the request.
493+
494+
1. The response should have a status code of 204 (No Content), indicating that the book was successfully deleted.
495+
---
496+
303497
## Configure JSON serialization options
304498

305499
There are two details to change about the JSON responses returned in the [Test the web API](#test-the-web-api) section:

Diff for: aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/BookStoreApi.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<ItemGroup>
1010
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.4" />
1111
<PackageReference Include="MongoDB.Driver" Version="3.3.0" />
12+
<PackageReference Include="NSwag.AspNetCore" Version="14.3.0" />
1213
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.0" />
1314
</ItemGroup>
1415

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@BookStoreApi_HostAddress = https://localhost:56874
2+
3+
GET {{BookStoreApi_HostAddress}}/api/books
4+
5+
###
6+
7+
@id=string
8+
GET {{BookStoreApi_HostAddress}}/api/Books/{{id}}
9+
10+
###
11+
12+
POST {{BookStoreApi_HostAddress}}/api/books
13+
Content-Type: application/json
14+
15+
{
16+
//Book
17+
}
18+
19+
###
20+
21+
DELETE {{BookStoreApi_HostAddress}}/api/Books/{{id}}
22+
23+
###

Diff for: aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Controllers/WeatherForecastController.cs

-32
This file was deleted.

Diff for: aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/Program.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525

2626
builder.Services.AddOpenApi();
2727

28+
// <snippet_UseSwagger>
2829
var app = builder.Build();
2930

30-
// Configure the HTTP request pipeline.
3131
if (app.Environment.IsDevelopment())
3232
{
3333
app.MapOpenApi();
@@ -36,6 +36,7 @@
3636
options.SwaggerEndpoint("/openapi/v1.json", "v1");
3737
});
3838
}
39+
// </snippet_UseSwagger>
3940

4041
app.UseHttpsRedirection();
4142

Diff for: aspnetcore/tutorials/first-mongo-app/samples/9.x/BookStoreApi/WeatherForecast.cs

-12
This file was deleted.

0 commit comments

Comments
 (0)