DEV Community

Cover image for 🐘 Building a To-do API in .NET with PostgreSQL (Beginner Friendly)
Asutosh Padhi
Asutosh Padhi

Posted on

🐘 Building a To-do API in .NET with PostgreSQL (Beginner Friendly)

So I’ve been picking up .NET lately, and one of the first real things I wanted to do was connect it to a database. An API with a frontend is nice, but let’s be honest — the fun starts when we can store stuff.

In this post, I’ll walk you through how I connected a minimal .NET API to PostgreSQL using Entity Framework Core (EF Core). Don’t worry, I’ll explain the new C#/.NET bits as we go along (coming from a JS/Node background myself, I needed that).

By the end, you’ll have:

  • A tiny Todo API in .NET
  • A PostgreSQL database behind it
  • The ability to add and fetch tasks

🎒 What you’ll need

  • .NET SDK installed
  • PostgreSQL installed and running locally
  • A blank database created (I called mine todo_db)
  • Postman (or curl) to test things

1. Install a couple of packages

From your backend folder:

dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
dotnet add package Microsoft.EntityFrameworkCore.Design
Enter fullscreen mode Exit fullscreen mode

👉 Translation:

  • The first one is the PostgreSQL driver for EF Core.
  • The second one is the “design-time tools” EF needs to run migrations.

2. Add a connection string

Inside appsettings.json:

{
  "ConnectionStrings": {
    "DefaultConnection": "Host=localhost;Database=todo_db;Username=postgres;Password=yourpassword"
  }
}
Enter fullscreen mode Exit fullscreen mode

This is basically your database “address book entry.”


3. Create a Todo model

Models/Todo.cs:

namespace backend.Models;

public class Todo
{
    public int Id { get; set; }          // primary key
    public string Title { get; set; } = string.Empty;
    public bool IsComplete { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Think of it like a schema in Mongo or a table in SQL. EF Core will map this to a database table.


4. Add a DbContext

Data/AppDbContext.cs:

using backend.Models;
using Microsoft.EntityFrameworkCore;

namespace backend.Data;

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

    public DbSet<Todo> Tasks { get; set; } = null!;
}
Enter fullscreen mode Exit fullscreen mode

This is EF Core’s way of saying: “Hey, here’s how I should talk to the database.”


5. Wire it up in Program.cs

using backend.Data;
using backend.Models;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// hook up PostgreSQL
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));

var app = builder.Build();

// GET all tasks
app.MapGet("/api/tasks", async (AppDbContext db) =>
    await db.Tasks.ToListAsync());

// POST a new task
app.MapPost("/api/tasks", async (AppDbContext db, Todo task) =>
{
    db.Tasks.Add(task);
    await db.SaveChangesAsync();
    return Results.Created($"/api/tasks/{task.Id}", task);
});

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

Notice how AppDbContext is just injected into the endpoint — no new-ing up objects yourself. .NET handles that for you.


6. Run migrations

This creates the actual database table:

dotnet ef migrations add InitialCreate
dotnet ef database update
Enter fullscreen mode Exit fullscreen mode

After this, PostgreSQL has a Tasks table ready for action.


7. Test it with Postman

POSThttp://localhost:5000/api/tasks

{
  "title": "Learn EF Core",
  "isComplete": false
}
Enter fullscreen mode Exit fullscreen mode

GEThttp://localhost:5000/api/tasks

And you’ll see your shiny new tasks, straight from PostgreSQL.


✅ Wrap up

And that’s it — we’ve got a .NET minimal API talking to PostgreSQL with EF Core in the middle doing all the heavy lifting.

Next up I’ll explore adding update and delete routes, so we’ll have the full CRUD cycle working.

Top comments (0)