18 KiB
title | author | description | ms.author | ms.date | monikerRange | uid |
---|---|---|---|---|---|---|
Tutorial: Create a minimal web API with ASP.NET Core | rick-anderson | Learn how to build a minimal web API with ASP.NET Core. | riande | 05/28/2022 | >= aspnetcore-6.0 | tutorials/min-web-api |
Tutorial: Create a minimal web API with ASP.NET Core
Minimal APIs are architected to create HTTP APIs with minimal dependencies. They are ideal for microservices and apps that want to include only the minimum files, features, and dependencies in ASP.NET Core.
This tutorial teaches the basics of building a minimal web API with ASP.NET Core. For a tutorial on creating a web API project based on controllers that contains more features, see Create a web API.
Overview
This tutorial creates the following API:
API | Description | Request body | Response body |
---|---|---|---|
GET / |
Browser test, "Hello World" | None | Hello World! |
GET /todoitems |
Get all to-do items | None | Array of to-do items |
GET /todoitems/complete |
Get completed to-do items | None | Array of to-do items |
GET /todoitems/{id} |
Get an item by ID | None | To-do item |
POST /todoitems |
Add a new item | To-do item | To-do item |
PUT /todoitems/{id} |
Update an existing item | To-do item | None |
DELETE /todoitems/{id} |
Delete an item | None | None |
Prerequisites
Visual Studio
Visual Studio Code
Visual Studio for Mac
Create a Web API project
Visual Studio
-
Start Visual Studio 2022 and select Create a new project.
-
In the Create a new project dialog:
-
Name the project TodoApi and select Next.
-
In the Additional information dialog:
- Select .NET 6.0 (Long-term support)
- Remove Use controllers (uncheck to use minimal APIs)
- Select Create
Visual Studio Code
-
Open the integrated terminal.
-
Change directories (
cd
) to the folder that will contain the project folder. -
Run the following commands:
dotnet new webapi -minimal -o TodoApi cd TodoApi code -r ../TodoApi
-
When a dialog box asks if you want to trust the authors, select Yes.
-
When a dialog box asks if you want to add required assets to the project, select Yes.
The preceding command creates a new web minimal API project and opens it in Visual Studio Code.
Visual Studio for Mac
- Select File > New Project....
- In Visual Studio for Mac 2022, select Web and Console > App > API > Next.
In the Configure your new API dialog, make the following selections:
- Target framework: .NET 6.x (or more recent).
- Configure for HTTPS: Check
- Use Controllers (uncheck to use minimal APIs): Uncheck
- Enable OpenAPI Support: Check
Select Next.
- In the Configure our new API window, enter the following:
- Project name: TodoApi
- Solution name: TodoApi
Select Create.
Examine the code
The Program.cs
file contains the following code:
The project template creates a WeatherForecast
API with support for Swagger. Swagger is used to generate useful documentation and help pages for web APIs.
The following highlighted code adds support for Swagger:
Run the app
Visual Studio
Press Ctrl+F5 to run without the debugger.
Visual Studio launches the Kestrel web server.
Visual Studio Code
Press Ctrl+F5 to run the app. A browser window is opened. Append /swagger
to the URL in the browser, for example https://localhost:7122/swagger
.
Visual Studio for Mac
Select Debug > Start Debugging to launch the app. Visual Studio for Mac launches a browser and navigates to https://localhost:<port>
, where <port>
is a randomly chosen port number.
The Swagger page /swagger/index.html
is displayed. Select GET > Try it out> Execute
. The page displays:
- The Curl command to test the WeatherForecast API.
- The URL to test the WeatherForecast API.
- The response code, body, and headers.
- A drop down list box with media types and the example value and schema.
Copy and paste the Request URL in the browser: https://localhost:<port>/WeatherForecast
. JSON similar to the following is returned:
[
{
"date": "2021-10-19T14:12:50.3079024-10:00",
"temperatureC": 13,
"summary": "Bracing",
"temperatureF": 55
},
{
"date": "2021-10-20T14:12:50.3080559-10:00",
"temperatureC": -8,
"summary": "Bracing",
"temperatureF": 18
},
{
"date": "2021-10-21T14:12:50.3080601-10:00",
"temperatureC": 12,
"summary": "Hot",
"temperatureF": 53
},
{
"date": "2021-10-22T14:12:50.3080603-10:00",
"temperatureC": 10,
"summary": "Sweltering",
"temperatureF": 49
},
{
"date": "2021-10-23T14:12:50.3080604-10:00",
"temperatureC": 36,
"summary": "Warm",
"temperatureF": 96
}
]
Update the generated code
This tutorial focuses on creating a web API, so we'll delete the Swagger code and the WeatherForecast
code. Replace the contents of the Program.cs
file with the following:
The following highlighted code creates a xref:Microsoft.AspNetCore.Builder.WebApplicationBuilder and a xref:Microsoft.AspNetCore.Builder.WebApplication with preconfigured defaults:
The following code creates an HTTP GET endpoint /
which returns Hello World!
:
app.MapGet("/", () => "Hello World!");
app.Run();
runs the app.
Remove the two "launchUrl": "swagger",
lines from the Properties/launchSettings.json
file. When the launchUrl
isn't specified, the web browser requests the /
endpoint.
Run the app. Hello World!
is displayed. The updated Program.cs
file contains a minimal but complete app.
Add NuGet packages
NuGet packages must be added to support the database and diagnostics used in this tutorial.
Visual Studio
- From the Tools menu, select NuGet Package Manager > Manage NuGet Packages for Solution.
- Enter Microsoft.EntityFrameworkCore.InMemory in the search box, and then select
Microsoft.EntityFrameworkCore.InMemory
. - Select the Project checkbox in the right pane and then select Install.
- Follow the preceding instructions to add the
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
package.
Visual Studio Code
-
Run the following commands:
dotnet add package Microsoft.EntityFrameworkCore.InMemory dotnet add package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Visual Studio for Mac
- In the Visual Studio for Mac 2022 toolbar, select Project > Manage NuGet Packages...
- In the searchbox, enter Microsoft.EntityFrameworkCore.InMemory
- In the results window, check
Microsoft.EntityFrameworkCore.InMemory
. - Select Add Package
- In the Select Projects window, select Ok
- In the License Agreement window, select Agree
Add the API code
Replace the contents of the Program.cs
file with the following code:
The model and database context classes
The sample app contains the following model:
A model is a class that represents data that the app manages. The model for this app is the Todo
class.
The sample app also contains the following database context class:
The database context is the main class that coordinates Entity Framework functionality for a data model. This class is created by deriving from the xref:Microsoft.EntityFrameworkCore.DbContext?displayProperty=fullName class.
The following highlighted code adds the database context to the dependency injection (DI) container and enables displaying database-related exceptions:
The DI container provides access to the database context and other services.
The following code creates an HTTP POST endpoint /todoitems
to add data to the in-memory database:
Install Postman to test the app
This tutorial uses Postman to test the API.
- Install Postman
- Start the web app.
- Start Postman.
- Disable SSL certificate verification
- From File > Settings (General tab), disable SSL certificate verification.
[!WARNING] Re-enable SSL certificate verification after testing the controller.
- From File > Settings (General tab), disable SSL certificate verification.
Test posting data
The following instructions post data to the app:
-
Create a new request.
-
Set the HTTP method to
POST
. -
Set the URI to
https://localhost:<port>/todoitems
. For example:https://localhost:5001/todoitems
-
Select the Body tab.
-
Select raw.
-
Set the type to JSON.
-
In the request body enter JSON for a to-do item:
{ "name":"walk dog", "isComplete":true }
Examine the GET endpoints
The sample app implements several GET endpoints using calls to MapGet
:
API | Description | Request body | Response body |
---|---|---|---|
GET / |
Browser test, "Hello World" | None | Hello World! |
GET /todoitems |
Get all to-do items | None | Array of to-do items |
GET /todoitems/complete |
Get all completed to-do items | None | Array of to-do items |
GET /todoitems/{id} |
Get an item by ID | None | To-do item |
Test the GET endpoints
Test the app by calling the two endpoints from a browser or Postman. For example:
GET https://localhost:5001/todoitems
GET https://localhost:5001/todoitems/1
The call to GET /todoitems
produces a response similar to the following:
[
{
"id": 1,
"name": "Item1",
"isComplete": false
}
]
Test the GET endpoints with Postman
- Create a new request.
- Set the HTTP method to GET.
- Set the request URI to
https://localhost:<port>/todoitems
. For example,https://localhost:5001/todoitems
. - Select Send.
This app uses an in-memory database. If the app is restarted, the GET request doesn't return any data. If no data is returned, first POST data to the app.
Return values
ASP.NET Core automatically serializes the object to JSON and writes the JSON into the body of the response message. The response code for this return type is 200 OK, assuming there are no unhandled exceptions. Unhandled exceptions are translated into 5xx errors.
The return types can represent a wide range of HTTP status codes. For example, GET /todoitems/{id}
can return two different status values:
- If no item matches the requested ID, the method returns a 404 status xref:Microsoft.AspNetCore.Mvc.ControllerBase.NotFound%2A error code.
- Otherwise, the method returns 200 with a JSON response body. Returning
item
results in an HTTP 200 response.
Examine the PUT endpoint
The sample app implements a single PUT endpoint using MapPut
:
This method is similar to the MapPost
method, except it uses HTTP PUT. A successful response returns 204 (No Content). According to the HTTP specification, a PUT request requires the client to send the entire updated entity, not just the changes. To support partial updates, use HTTP PATCH.
Test the PUT endpoint
This sample uses an in-memory database that must be initialized each time the app is started. There must be an item in the database before you make a PUT call. Call GET to ensure there's an item in the database before making a PUT call.
Update the to-do item that has Id = 1 and set its name to "feed fish"
:
{
"id": 1,
"name": "feed fish",
"isComplete": false
}
Examine the DELETE endpoint
The sample app implements a single DELETE endpoint using MapDelete
:
Use Postman to delete a to-do item:
- Set the method to
DELETE
. - Set the URI of the object to delete (for example
https://localhost:5001/todoitems/1
). - Select Send.
Prevent over-posting
Currently the sample app exposes the entire Todo
object. Production apps typically limit the data that's input and returned using a subset of the model. There are multiple reasons behind this and security is a major one. The subset of a model is usually referred to as a Data Transfer Object (DTO), input model, or view model. DTO is used in this article.
A DTO may be used to:
- Prevent over-posting.
- Hide properties that clients are not supposed to view.
- Omit some properties in order to reduce payload size.
- Flatten object graphs that contain nested objects. Flattened object graphs can be more convenient for clients.
To demonstrate the DTO approach, update the Todo
class to include a secret field:
The secret field needs to be hidden from this app, but an administrative app could choose to expose it.
Verify you can post and get the secret field.
Create a DTO model:
Update the code to use TodoItemDTO
:
Verify you can't post or get the secret field.
Differences between minimal APIs and APIs with controllers
- No support for filters: For example, no support for xref:Microsoft.AspNetCore.Mvc.Filters.IAsyncAuthorizationFilter, xref:Microsoft.AspNetCore.Mvc.Filters.IAsyncActionFilter, xref:Microsoft.AspNetCore.Mvc.Filters.IAsyncExceptionFilter, xref:Microsoft.AspNetCore.Mvc.Filters.IAsyncResultFilter, and xref:Microsoft.AspNetCore.Mvc.Filters.IAsyncResourceFilter.
- No support for model binding, i.e. xref:Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinderProvider, xref:Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder. Support can be added with a custom binding shim.
- No support for binding from forms. This includes binding xref:Microsoft.AspNetCore.Http.IFormFile. We plan to add support for
IFormFile
in the future.
- No support for binding from forms. This includes binding xref:Microsoft.AspNetCore.Http.IFormFile. We plan to add support for
- No built-in support for validation, i.e. xref:Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IModelValidator
- No support for application parts or the application model. There's no way to apply or build your own conventions.
- No built-in view rendering support. We recommend using Razor Pages for rendering views.
- No support for JsonPatch
- No support for OData
- No support for ApiVersioning. See this issue for more details.
Use JsonOptions
The following code uses xref:Microsoft.AspNetCore.Http.Json.JsonOptions:
The following code uses xref:System.Text.Json.JsonSerializerOptions:
The preceding code uses web defaults, which converts property names to camel case.
Test minimal API
For an example of testing a minimal API app, see this GitHub sample.
Publish to Azure
For information on deploying to Azure, see Quickstart: Deploy an ASP.NET web app.