# Tutorial Two: My First CRUD App

# CRUD - Create Read Update Delete

In tutorial one , you built a simple API where you hard coded the results for HTTP methods.

For example: app.MapGet("/todo", () => new { Item = "Water plants", Complete = "false" }); has been hard coded to return the JSON results below.

{
"item": "Water plants",
"complete": "false"
}
1
2
3
4

In tutorial 3, we are going to step it up a notch and create something dynamic. Instead of returning a static item that is hardcoded to our route, we are going to be creating to-do list that we can update, create new items, mark an item as complete and delete an item.

Our to-do API will be a CRUD app, and will be able to to:

  • Create a new item.➕
  • Return a specific item on a list. ↩ī¸
  • Update an existing item. 🔄
  • Delete an item. ➖

Create a data model

Create a class that models the data we want to collect, also known as a data model. Place the code for your TodoItem underneath app.Run();

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

}
1
2
3
4
5
6
7

Now that we have defined that data we want to collect, we need to save it somewhere to be used in the future.

Store an item

To store items into our todo list, we need to install the Entity Frameworkcore InMemomry 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
1

Add using Microsoft.EntityFrameworkCore; to the top of your Program.cs file.

Now, that we have EntityFramework we can now wire up our code to the data we want save and query it. To do this we are going to create a TodoDb class. TodoDb class is going to do the following:

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

To setup 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> Todos { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseInMemoryDatabase("Todos");
    }
}
1
2
3
4
5
6
7
8
9
10

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

Snippet 2 : Before AddSwaggerGen services we configured in the first tutorial (opens new window) add the code snippet below.

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

Return a list of items

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

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

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

swagger-get-todos

# Create new items

Let's POST new tasks to the todos list. Below app.MapGet you create earlier.

app.MapPost("/todos", async (TodoDb db, TodoItem todo) =>
{
    await db.Todos.AddAsync(todo);
    await db.SaveChangesAsync();
    return Results.Created($"/todo/{todo.Id}", todo);
});
1
2
3
4
5
6

Go back to Swagger and now you should see POST/todos. To add new items to the todo list

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

swagger-post-todos

Read the 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.

[
  {
    "id": 1,
    "item": "Buy groceries",
    "isComplete": true
  },
  {
    "id": 2,
    "item": "Water plants",
    "isComplete": false
  }
]
1
2
3
4
5
6
7
8
9
10
11
12

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

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

1
2

To check this out you can either go to https://localhost:5001/todos/1 or use the Swagger UI. swagger-get-todos-item

# Update an item

To update an existing item add the code below GET /todos/{id} route we created above.

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

    await db.SaveChangesAsync();

    return Results.NoContent();
});
1
2
3
4
5
6
7
8
9
10
11
12
13
  • click on PUT/todos/{id}
  • Click on Try it out
  • In the id text box enter 2
  • Update Request body paste the JSON below and update isComplete to true.
 {
    "id": 2,
    "item": "Water plants",
    "isComplete": false
  }

1
2
3
4
5
6
  • Click Execute

To test this out scroll back to GET/todos/{id} and now Water Plants is marked as complete.

swagger-put-todos-item

# Delete an item.

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

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

    return Results.Ok();

});
1
2
3
4
5
6
7
8
9
10
11
12
13

Now, try deleting an item. swagger-delete-todos-item

# Learn checklist three ✔ī¸

  • Add model class and database context
  • CRUD methods
    • GET:read an item.
    • POST: create an item.
    • PUT: update an item.
    • DELETE: delete an item.
  • Configured routing and returned values