ASP.NET Core 6 introduces a simplified hosting model that can be used to implement lightweight APIs with minimal dependencies. These minimal APIs reduce the boilerplate code you need to write to get your ASP.NET Core 6 applications up and running.

We discussed how to get started with minimal APIs in an earlier article. In this article we’ll explore more advanced aspects of minimal APIs including implementing logging, reading from the configuration system, and using dependency injection.

To work with the code examples provided in this article, you should have Visual Studio 2022 installed in your system. If you don’t already have a copy, you can download Visual Studio 2022 here.

Create an ASP.NET Core minimal web API project in Visual Studio 2022

First off, let’s create an ASP.NET Core project in Visual Studio 2022. Following these steps will create a new ASP.NET Core Web API 6 project in Visual Studio 2022:

  1. Launch the Visual Studio 2022 IDE.
  2. Click on “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 for the new project.
  6. Optionally check the “Place solution and project in the same directory” check box, depending on your preferences.
  7. Click Next.
  8. In the “Additional Information” window shown next, uncheck the check box that says “Use controllers…” since we’ll be using minimal APIs in this example. Leave the “Authentication Type” as “None” (default).
  9. Ensure that the check boxes “Enable Docker,” “Configure for HTTPS,” and “Enable Open API Support” are unchecked as we won’t be using any of those features here.
  10. Click Create.

This will create a new ASP.NET Core 6 Web API project in Visual Studio 2022. We’ll use this project to work with a minimal API in the subsequent sections of this article.

Run a minimal web API

You can get your minimal API working with just a few lines of code:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("https://www.infoworld.com/", () => "This is an example of a minimal API");
app.Run();

Configure multiple ports for a minimal web API

The following code snippet illustrates how you can configure your minimal API to run on one specific port.

var app = WebApplication.Create(args);
app.MapGet("https://www.infoworld.com/", () => "Hello World!");
app.Run("http://localhost:5178");

When you run the application and browse to this URL, you should see the “Hello World!” message displayed in your web browser.

You can use multiple ports by adding the URLs as shown in the following code snippet.

app.Urls.Add("http://localhost:5178");
app.Urls.Add("http://localhost:5179");

In this case, if you browse to any of these endpoints, the same “Hello World!” message will be displayed.

You can even read the port from the environment as shown in the code snippet given below.

var app = WebApplication.Create(args);
var port = Environment.GetEnvironmentVariable("PORT") ?? "5155";
app.MapGet("https://www.infoworld.com/", () => "Hello World!");
app.Run($"http://localhost:{port}");

Use logging in a minimal web API

You can also use logging in your minimal APIs. Here is how you can log data to the console using Serilog:

var logger = new LoggerConfiguration()
    .WriteTo.Console()
    .CreateLogger();

You can use Serilog for creating logs that persist application restarts as well. Serilog supports logging to a database, file, cloud storage, and other targets. The following code snippet illustrates how you can use Serilog in minimal APIs.

var builder = WebApplication.CreateBuilder(args);
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .WriteTo.File("logs.txt", rollingInterval: RollingInterval.Day)
    .CreateLogger();

The following code snippet shows how you can use logging in your minimal API.

app.MapGet("https://www.infoworld.com/", (ILoggerFactory loggerFactory) => {
    var logger = loggerFactory.CreateLogger("Start");
    logger.LogInformation("Starting...");
    return "Logging at work!";
});

Read from the configuration system in a minimal API

You can also read from the configuration system in your minimal API. The following code snippet shows how this can be achieved.

var app = WebApplication.Create(args);
var message = app.Configuration["TextMessage"] ?? "This is a default message.";
app.MapGet("https://www.infoworld.com/", () => message);
app.Run();

Use dependency injection in a minimal web API

If you would like to use a HttpClient instance to connect to a remote resource, you can use dependency injection as shown in the code snippet given below.

app.MapGet("https://www.infoworld.com/", (IHttpClientFactory httpClientFactory) => "Inside HttpGet method");

Remember to add HttpClient to the container using the following code.

builder.Services.AddHttpClient();

You can also take advantage of dependency injection in a HttpPost method. The code snippet below shows how you can pass an instance of IHttpClientFactory as a parameter to your HttpPost method.

app.MapPost("https://www.infoworld.com/", (IHttpClientFactory httpClientFactory) =>
{
    var client = httpClientFactory.CreateClient();
    return Results.Ok();
});

Inject a custom class in a minimal web API

You can also inject an instance of a custom class in your minimal API. To illustrate this, let’s implement two types: the IAuthorRepository interface and the AuthorRepository class. We’ll use these types to implement dependency injection in our minimal API.

Create a new file named IAuthorRepository.cs and insert the following code:

    public interface IAuthorRepository
    {
        public List<Author> GetAuthors();
        public Author GetAuthor(int id);
    }

The AuthorRepository class implements the IAuthorRepository interface as shown below.

 public class AuthorRepository: IAuthorRepository
    {
        private readonly List<Author> _authors;
        public AuthorRepository()
        {
            _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"
                },
                new Author
                {
                    Id = 4,
                    FirstName = "Simon",
                    LastName = "Bisson"
                }
            };
        }
        public List<Author> GetAuthors()
        {
            return _authors;
        }
        public Author GetAuthor(int id)
        {
            return _authors.Find(x=> x.Id == id);
        }
    }

Inject a custom interface in a minimal web API

The following code snippet illustrates how you can inject an instance of the IAuthorRepository interface.

app.MapGet("api/author/{id:int}", async (IAuthorRepository authorRepository, HttpContext httpContext) =>
{
    var id = int.Parse((string)httpContext.Request.RouteValues["id"]);
    var author = authorRepository.GetAuthor(id);
    if (author == null)
    {
        return Results.NotFound();
    }
    return Results.Ok(author);
});

Finally, .NET 6 includes a great new feature, global using directives. To leverage global uses, create a new file named Usings.cs and move all of your using statements there. You can use this feature with your ASP.NET Core 6 or minimal APIs.

I’ll have more to say about minimal APIs (such as working with security and middleware) in a future post here.

Copyright © 2022 IDG Communications, Inc.

Source link

Leave a Reply

Your email address will not be published.