Building My First Web API cover image

Building My First Web API

By Sofia Reiter · Monday, November 3, 2025 · ~4 min read

After spending a couple of months getting comfortable with C# fundamentals, I decided it was time to build something real. I chose to create a simple REST API for managing a book collection using ASP.NET Core. Here's what I learned along the way.

The Project Idea

I wanted something simple but practical: a Book API where you can create, read, update, and delete books. Nothing fancy, but enough to learn the core concepts of building a web API.

Scaffolding the Project

Creating the project was a single command:

dotnet new webapi -n BookApi

This generated a project with a sample WeatherForecast controller. I spent some time studying its structure before replacing it with my own.

Defining the Model

First, I created a simple Book model:

public class Book
{
    public int Id { get; set; }
    public required string Title { get; set; }
    public required string Author { get; set; }
    public int Year { get; set; }
    public string? Genre { get; set; }
    public bool IsRead { get; set; }
}

I used the required keyword for properties that must always have a value. This was a nice C# 11 feature I picked up from the documentation.

Building the Controller

The controller was where things got interesting. I learned about attribute routing, HTTP verbs, and how ASP.NET Core maps incoming requests to methods:

[ApiController]
[Route("api/[controller]")]
public class BooksController : ControllerBase
{
    private static readonly List<Book> _books = new();
    private static int _nextId = 1;

    [HttpGet]
    public ActionResult<IEnumerable<Book>> GetAll()
    {
        return Ok(_books);
    }

    [HttpGet("{id}")]
    public ActionResult<Book> GetById(int id)
    {
        var book = _books.FirstOrDefault(b => b.Id == id);
        if (book is null) return NotFound();
        return Ok(book);
    }

    [HttpPost]
    public ActionResult<Book> Create(Book book)
    {
        book.Id = _nextId++;
        _books.Add(book);
        return CreatedAtAction(nameof(GetById), new { id = book.Id }, book);
    }
}

Mistakes I Made

Forgetting About Content Types

My first POST request failed because I forgot to set the Content-Type: application/json header. The API returned a 415 Unsupported Media Type, and I spent twenty minutes debugging before I realized the issue. Lesson learned: always check your request headers.

Returning the Wrong Status Codes

Initially, I returned Ok() for everything, including creation. A quick read through REST conventions taught me that 201 Created is the proper response for resource creation, which is what CreatedAtAction provides.

Static Data Is Not Persistence

Using a static list was fine for learning, but I quickly realized that the data disappeared every time I restarted the application. This motivated me to look into Entity Framework Core, which I plan to explore next.

Testing with Swagger

One thing I absolutely loved was the built-in Swagger UI. Opening https://localhost:5001/swagger gave me a fully interactive page to test all my endpoints without needing Postman or curl. I could send requests, see responses, and even inspect the schema of my models.

What Clicked for Me

The request pipeline concept finally made sense. A request comes in, gets routed to a controller, the controller processes it and returns a result, and the framework serializes it to JSON. It sounds obvious in hindsight, but seeing it work end-to-end was an important moment for me.

I also appreciated how much ASP.NET Core does automatically: model binding from JSON, input validation, content negotiation, and consistent error responses. Coming from manually parsing request bodies in other frameworks, this felt like a significant upgrade.

Next Steps

I want to add a proper database with Entity Framework Core, learn about data validation with data annotations, and understand how middleware works. I've also been hearing a lot about dependency injection, which seems to be fundamental to how ASP.NET Core is structured. That will probably be my next deep dive.

Building this small API gave me a lot of confidence. It's one thing to read about RESTful services, but actually building one and seeing the pieces fit together is a completely different experience.


Comments (2)

David Friday, March 6, 2026 5:08 PM

Could you elaborate on this topic in a follow-up post?

Greta Tuesday, February 17, 2026 8:08 PM

Interesting thought, thanks for adding that.

Felix Saturday, March 14, 2026 8:08 PM

Good question, I'd like to know too.

Elena Saturday, March 7, 2026 5:08 PM

This is exactly what I was looking for, thank you!

Leave a Comment

4

min read