Building a RESTful Minimal API with .NET Core 7

Xing Wang - Oct 9 '23 - - Dev Community

.NET Core and ASP.NET Core are popular frameworks for creating powerful RESTful APIs. In this tutorial, we will use it to develop a simple Minimal API that simulates a credit score rating. Minimal APIs provide a streamlined approach to creating high-performing HTTP APIs using ASP.NET Core. They allow you to construct complete REST endpoints with minimal setup and code easily. Instead of relying on conventional scaffolding and controllers, you can fluently define API routes and actions to simplify the development process.

We will create an endpoint allowing a user to retrieve a credit score rating by sending a request to the API. We can also save and retrieve credit scores using POST and GET methods. However, it is essential to note that we will not be linking up to any existing backend systems to pull a credit score; instead, we will use a random number generator to generate the score and return it to the user. Although this API is relatively simple, it will demonstrate the basics of REST API development using .NET Core and ASP.NET. This tutorial will provide a hands-on introduction to building RESTful APIs with .NET Core 7 and the Minimal API approach.

Prerequisites

Before we start, we must ensure that we have completed several prerequisites. To follow along and run this tutorial, you will need the following:

  • A working .NET Core installation
  • An IDE or text editor of your choice
  • Postman to test our endpoint

Creating the Initial Project

We'll be using the .NET cli tool to create our initial project. The .NET command line interface provides the ability to develop, build, run, and publish .NET applications.

The .NET cli new command provides many templates to create your project. You can also add the search command to find community-developed templates from NuGet or use dotnet new list to see available templates provided by Microsoft.

Image description

We'll be creating a Minimal API and starting from as clean a slate as possible. We'll be using the empty ASP.NET Core template. In the directory of your choosing; enter the following in the terminal:

dotnet new web
Enter fullscreen mode Exit fullscreen mode

You'll notice that the directory structure will look something like this:

Image description

We'll be doing all of our work in the Program.cs file. Its starting code should look similar to the following:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();
Enter fullscreen mode Exit fullscreen mode

We can see how concise and readable our starter code is. Let's break down the code provided by the template line by line:

  1. The WebApplication.CreateBuilder(args) method creates a new instance of the WebApplicationBuilder class, which is used to configure and build the WebApplication instance. The args parameter is an optional array of command-line arguments that can be passed to the application at runtime.
  2. The builder.Build() method is called to create a new instance of the WebApplication class, which represents the running application. This instance configures the application, defines routes, and handles requests.
  3. The third line defines a route for the root path ("/") of the application using the app.MapGet() method. This means that when the root path is requested, the application will respond with the string "Hello World!".
  4. We start the application by calling the app.Run() method.

Using the builder pattern, we can configure and customize the WebApplication instance. This allows us to define the application's behavior, including middleware, routes, and other settings, in a structured and extensible way. For example, the WebApplication instance created by the builder can be thought of as the "entry point" of the application, which handles requests and generates responses.

Overall, this code block creates a simple Minimal API in .NET 7 that responds with a "Hello World!" message when the application's root path is requested.

Next, we'll customize our API to mimic retrieving a credit score rating.

Adding in the Code

In Program.cs, we will house our endpoints and business logic. We'll define our creditscore endpoint to provide GET and POST operations. We'll implement a list to store any credit score we would like. We'll also define an endpoint to retrieve the list of saved credit scores. We'll be utilizing a CreditScore record, a new reference type in C# 10 similar to structs. A record is a lightweight and immutable data object optimized for comparison and equality checking.

Populate Program.cs with the following code:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

var userAddedCreditScores = new List<CreditScore>();

app.MapGet("/creditscore", () =>
{
    var score = new CreditScore
    (
        Random.Shared.Next(300, 850)
    );
    return score;
});

app.MapPost("/creditscore", (CreditScore score) => {
    userAddedCreditScores.Add(score);
    return score;
});

app.MapGet("/userAddedCreditScores", () => userAddedCreditScores);

app.Run();

record CreditScore(int Score)
{
    public string? CreditRating
    {
        get => Score switch
        {
            >= 800 => "Excellent",
            >= 700 => "Good",
            >= 600 => "Fair",
            >= 500 => "Poor",
            _ => "Bad"
        };
    }
}
Enter fullscreen mode Exit fullscreen mode

As mentioned, our code first creates a builder object for the web application and then uses it to build an application instance. It also defines a record type called CreditScore with a single property called Score and a read-only property called CreditRating. This may look a little strange as we define our record after using it. However, this is due to namespaces, and the record must be defined outside of the WebApplication namespace.

The application exposes multiple endpoints using app.MapGet() and app.MapPost() methods. The first endpoint, /creditscore is a GET method that generates a new random CreditScore object with a score between 300 and 850. We'll define a POST method for the same endpoint that accepts a CreditScore object in the request body, adds it to a list called userAddedCreditScores, and returns the same CreditScore object to the caller. The other endpoint /userAddedCreditScores is a GET method that returns a list of all the CreditScore objects that have been added to userAddedCreditScores.

Finally, the application starts running using app.Run().

Running and Testing the API

With our code written, run the following command to compile and run our project:

dotnet run
Enter fullscreen mode Exit fullscreen mode

The API is now operational and ready for testing. After running the previous command, you will see which port has been used to host your API in the console. You can define which port you would like to use by editing the Properties > launchSettings.json file or by adding editing the app.Run() command in Program.cs like so, replacing 3000 with your desired port number:

app.Run("http://localhost:3000");
Enter fullscreen mode Exit fullscreen mode

You can use a tool like Postman to send an HTTP request to the API. For me, the endpoint to get a credit score is localhost:5242/creditscore. When you send a request to this endpoint, you should receive a 200 OK status code, a credit score generated by the random number generator, and a credit rating.

Image description

We can save a credit score by sending a POST request to the creditscore endpoint. We form the request's body with a CreditScore object.

Image description

Finally, we can retrieve all added scores by sending a GET request to the /userAddedCreditScores endpoint.

Image description

Wrapping Up

In summary, we have developed a basic RESTful Minimal API using .NET Core 7 and ASP.NET. This code can be a foundation for creating more complex APIs for your application. As you continue to develop the API, you may want to consider implementing security measures such as an API key, integrating with an API gateway, monitoring the usage of the API, or generating revenue through API monetization.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .