Getting start with Minimal APIs in .Net 6

What's Minimal APIs

Microsoft has released .NET 6 on 2021-11-08 and Minimal API is a part of this release. 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. Basically, with minimal API all you need is a csproj and a program.cs to get started.

Point of Minimal APIs:

Minimalism First
Rapidly move from idea to a functioning application. All the features of C# web applications without the ceremony.

Grows With You
As your web application grows, so do we! The C# ecosystem powers the most productive applications on the web.

Incredibly Fast
Proven to be one of the fastest web servers in the world, serving more than 4 million requests per second.

C# Ecosystem

Minimal APIs is built using C#. AN open-source, modern, object-oriented, and type-safe programming language. Build an API in C# with just 3 lines of code.

var app = WebApplication.Create(args);

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

app.Run();

CRUD and minimal APIs.

This part will show you how to build the backend to a Todo App using minimal APIs. By the end of this part, you will know-how:

  • Create a minimal API
  • Build interactive API documentation with Swagger UI
  • Build CRUD application
  • Store Todo items into a database.

Getting started

Before you can start building a minimal API, please install the following:

  • .NET 6 SDK
  • An editor of your choice, such as VS Code or Visual Studio.

Create new Minimal API project

dotnet cli

dotnet new web -o TodoApi

Run
Now, that you have created your minimal API you can now run it. To run your application navigate to the TodoApi folder and type the command below:

TodoApi> dotnet run

If you navigate or click on the localhost link provided to http://localhost:5048 in a browser, you'll see the text Hello World! as the browser makes a request to your app and display the output.

To shut down the application, go back to the terminal window and hit ctr + c.

Add a new route

Open your TodoApi app in an editor of your choice and open the Program.cs file.

Your Program.cs looks like this:

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

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

app.Run();

In Program.cs, create a new to-do route to our API that returns a list of items. Add a new MapGet after app.MapGet("", () => "Hello World");

// C# Tip: Item and Complete are referred to as anonymous types.
app.MapGet("/todo", () => new { Item = "New task", Complete = false });

This route will return one Todo item when you navigate to http://localhost:5048/todo.
You'll see the JSON response:

{
    "item": "New task",
    "complete": false
}
Interactive API docs

Add Swagger UI to your application
Install the Microsoft OpenAPI and Swagger packages.
Using .NET CLI

In a terminal window, type the following command:

TodoApi> dotnet add package Swashbuckle.AspNetCore --version 6.1.4

To set up swagger UI, add the following two code snippets:
Snippet 1: Under var builder = WebApplication.CreateBuilder(args); , add the following lines of code:

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c => {
    c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo {
        Title = "Todo API",
        Description = "Minimal APIs sample",
        Version = "v1"
    });
});

The AddSwaggerGen method adds information such as title, description, and version to your API.

Snippet 2: Above app.MapGet code block, add the following lines of code:

app.UseSwagger();
app.UseSwaggerUI(c => {
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "Todo API V1");
});

The preceding code snippet does the following:

  • app.UseSwagger enables middleware to server the generated OpenAPI description ad JSON content.
  • app.UseSwaggerUI enables middle to serve the Swagger UI elements.
  • SwaggerEndpoint specifies the OpenAPI description's endpoint.

Go back to your browser where your app is and navigate to this URL http://localhost:5048/swagger

Now that Swagger UI is set up, you can visualize and interact with your API.

Create Read Update Delete

Our to-do APIs is going to:

  • Create a new item.
  • Return a specific item on a list.
  • Update an existing item.
  • Delete and item.

Create the class that models the data we want to collect aka Data model. The code for your TodoItem will go after app.Run()

Create a data model

class TodoItem
{
    public int Id { get; set; }
    public string? Item { get; set; }
    public bool IsComplete { get; set; }
}

Now, that we have defined the data we want to collect we need to save it.

Store an Item
To store the item in the to-do list we are going need to install the Entity Framework core InMemory package below:

Entity Framework is a code library that enables the transfer of data stored in relational database tables(E.g SQLite and MySQL, SQL Server etc) into objects that are more commonly used in application code.

Using .Net CLI
In your terminal window
TodoApi> dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 5.0.7

Add using Microsoft.EntityFrameworkCore; to the top of your Program.cs file.
Now, that we have EntityFramework we can now write up our code to the data we want to save and query it. To do it we are going to create a TodoDb class. TodoDb class is going to do the following:

  • Expose our Todos property from our list TodoItem in the database.
  • UseInMemoryDatabase wires the in-memory database storage. This will store data as long as the app is running.

To set up your in-memory database add the following code snippets to our code.
Snippet 1: Below the TodoItem create a TodoDb class

class TodoDb: DbContext
{
    public TodoDb(DbContextOptions options) : base(options) {}

    public DbSet<TodoItem> Tasks { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseInMemoryDatabase("Todos");
    }
}

DbContext represents a connection/session which is used to query and save instances of entities in a database.

Snippet 2: Before AddSwaggerGen services add the code snippet below.

builder.Services.AddDbContext<TodoDb>(options => options.UseInMemoryDatabase("item"));

Return a list of items
To read from a list of items in the todo list replate the "/todo" route with "/todos" route below.

app.MapGet("/todos", async (TodoDb db) => await db.Tasks.ToListAsync());

Go back to your browser and navigate to http://localhost:5048/swagger click on the GET /todos button and you will see the list is empty under Response body.

Create new items
Let's POST new tasks to the to-do list. Below app.MapGet you create earlier.

app.MapPost("/todos", async (TodoDb db, TodoItem todo) => {
    await db.Tasks.AddAsync(todo);
    await db.SaveChangesAsync();
    return Results.Created($"/todo/{todo.Id}", todo);
});

Go back to swagger and now you can see the POST /todos. To add new items to the to-do list.

  • Click on the POST /todos
  • Click on Try it out
  • Update id, item, and isComplete
  • Click Execute

Post result:

Read the list items in the list
To read the items in the list

  • Click on GET /todos
  • Click on Try it out
  • Click Execute

The Response body will include the items just added.

To GET an item by id add the code below app.MapPost route create earlier

app.MapGet("/todos/{id}", async (TodoDb db, int id) => await db.Tasks.FindAsync(id));

To check this out you can either go to http://localhost:5048/todos/1 or use the Swagger UI

Update an item
To update an existing item add the code below GET /todos/{id}

app.MapPut("/todos", async (TodoDb db, TodoItem updateTodo, int id) => {
    var todo = await db.Tasks.FindAsync(id);
    if (todo is null) return Results.NotFound();

    todo.Item = updateTodo.Item;
    todo.IsComplete = updateTodo.IsComplete;

    await db.SaveChangesAsync();
    return Results.NoContent();
});
  • Click on the PUT /todos/{id}
  • Click on Try it out
  • In the id text vox enter 1
  • Update Request body past the JSON below and update isComplete to true
{
  "id": 1,
  "item": "Make minimal APIs CRUD sample",
  "isComplete": false
}
  • Click Execute

  • Access http://localhost:5048/todos/1 to result after update

Delete an item
To delete an existing item add the code below PUT /id/{id} we create above.

app.MapDelete("/todos/{id}", async (TodoDb db, int id) => {
    var todo = await db.Tasks.FindAsync(id);
    if (todo is null) return Results.NotFound();
    
    db.Tasks.Remove(todo);
    await db.SaveChangesAsync();

    return Results.Ok();
});

Now, try deleting an item.

Reference: