When dealing with Web applications in ASP.NET Core, we may often want to build lightweight services, that is, services without templates or controller classes.
Lightweight services can reduce resource consumption and improve performance. We can create these lightweight services or API s in Startup or Program classes.
1. Create ASP.NET Core project with VS2022
We created an ASP.NET Core project in Visual Studio 2022. Follow these steps to create a new ASP.NET Core Web API 6 project in Visual Studio 2022.
1) Start the Visual Studio 2022 IDE.
2) Click Create new project.
3) In the Create new project window, select ASP.NET Core Web API from the list of templates displayed.
4) Click next.
5) In the Configure your new project window, specify the name and location of the new project.
6) According to your preference, you can select the "Place solution and project in the same directory" check box.
7) Click next.
8) In the Additional Information window that appears next, select. NET 6.0 as the target framework from the drop-down list at the top. Leave Authentication Type as None (default).
9) Make sure the "Enable Docker", "Configure for HTTPS" and "Enable Open API Support" check boxes are not selected because we will not use any of these features here. You can also choose to uncheck the Use controllers check box because we will create our own controllers.
10) Click create.
This will create a new ASP.NET Core 6 Web API project in Visual Studio 2022. We will use this project in subsequent parts of this article to illustrate how to use lightweight services.
2. Enable a lightweight service in ASP.NET Core
Since we will build a lightweight service that does not require a controller, we should delete the Controllers solution folder and any model classes created by default.
Next, open the launchSettings.json file in the Properties solution folder, delete or comment out the launchUrl key value pair, as shown in the code given below.
Where launchurl refers to the host of the application. When the application starts, the URL specified in the launchurl is used to start the application.
If the URL is wrong or does not exist, the application will throw an error at startup. By deleting or commenting out the launchUrl, we can ensure that the application does not start the application with the default launchUrl, thus avoiding any errors. Once the launchUrl is deleted, the application will return to port 5000.
"profiles": { "Light_Weight_Services": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, //"launchUrl": "", "applicationUrl": "http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, //"launchUrl": "", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }
3. Use IEndpointConventionBuilder extension method in ASP.NET Core
We can use some extension methods of the IEndpointConventionBuilder interface to map requests.
The following is a list of these extension methods:
- MapGet
- MapPost
- MapDelete
- MapPut
- MapRazorPages
- MapControllers
- MapHub
- MapGrpcServices
The MapGet, MapPost, MapDelete, and MapPut methods are used to delegate requests to the routing system. MapRazorPages is used for RazorPages, MapControllers is used for Controllers, MapHub is used for SignalR, and MapGrpcService is used for gRPC.
The following code explains how to create an HTTP Get endpoint using MapGet.
endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello World!"); });
We create a C# file named Author, which contains the following code:
public class Author { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } }
Create a read-only list of authors and fill in some data, as shown below:
private readonly List<Author> _authors; public Startup(IConfiguration configuration) { _authors = new List<Author> { new Author { Id = 1, FirstName = "Joydip", LastName = "Kanjilal" }, new Author { Id = 2, FirstName = "Steve", LastName = "Smith" }, new Author { Id = 3, FirstName = "Julie", LastName = "Lerman" } }; Configuration = configuration; }
We can use the following code to create another endpoint and return the author list in JSON format.
endpoints.MapGet("/authors", async context => { var authors = _authors == null ? new List<Author>() : _authors; var response = JsonSerializer.Serialize(authors); await context.Response.WriteAsync(response); });
4. Retrieve records using lightweight services in ASP.NET Core
To retrieve a specific record by Id, we can write the following code:
endpoints.MapGet("/authors/{id:int}", async context => { var id = int.Parse((string)context.Request.RouteValues["id"]); var author = _authors.Find(x=> x.Id == id); var response = JsonSerializer.Serialize(author); await context.Response.WriteAsync(response); });
5. Create records using lightweight services in ASP.NET Core
To add data using HTTP Post, we can use the MapPost extension method, as shown below:
endpoints.MapPost("/", async context => { var author = await context.Request.ReadFromJsonAsync<Author>(); _authors.Add(author); var response = JsonSerializer.Serialize(author); await context.Response.WriteAsync(response); });
6. Delete records using lightweight services in ASP.NET Core
To delete data, we can use the MapDelete extension method, as shown below:
endpoints.MapDelete("/authors/{id:int}", async context => { var id = int.Parse((string)context.Request.RouteValues["id"]); var author = _authors.Find(x => x.Id == id); _authors.Remove(author); var response = JsonSerializer.Serialize(_authors); await context.Response.WriteAsync(response); });
7. Configuration method of lightweight services in asp.net core
The following is the complete source code of the Configure method of the Startup class:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello World!"); }); endpoints.MapGet("/authors", async context => { var authors = _authors == null ? new List<Author>() : _authors; var response = JsonSerializer.Serialize(authors); await context.Response.WriteAsync(response); }); endpoints.MapGet("/authors/{id:int}", async context => { var id = int.Parse((string)context.Request.RouteValues["id"]); var author = _authors.Find(x=> x.Id == id); var response = JsonSerializer.Serialize(author); await context.Response.WriteAsync(response); }); endpoints.MapPost("/", async context => { var author = await context.Request.ReadFromJsonAsync<Author>(); _authors.Add(author); var response = JsonSerializer.Serialize(author); await context.Response.WriteAsync(response); }); endpoints.MapDelete("/authors/{id:int}", async context => { var id = int.Parse((string)context.Request.RouteValues["id"]); var author = _authors.Find(x => x.Id == id); _authors.Remove(author); var response = JsonSerializer.Serialize(_authors); await context.Response.WriteAsync(response); }); }); }
8. Create lightweight services in the Program class of ASP.NET Core
There is another way to create lightweight services in ASP.NET 6. When we create a new ASP.NET Core 6 empty project, the Startup.cs file is not created by default. Therefore, we can write code in the Program.cs file to create lightweight services.
The following example shows how to do this:
app.MapGet("/", () => "Hello World!"); app.MapDelete("/{id}", (Func<int, bool>)((id) => { // Delete record code return true; })); app.MapPost("/", (Func<Author, bool>)((author) => { // Add record code return true; })); app.Run();
Lightweight services or API s have no templates and do not require controller classes to create them.
We can create such services in the Startup or Program class.
If we want to implement authorization in lightweight services, we can use the RequireAuthorization extension method of the iendpoint conventionbuilder interface.
reference material: