Building My First Web API

Building My First Web API

Sofia Reiter ยท November 03, 2025
ASP.NET CoreWeb APIBeginners
LearningTutorials

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 Mar 06, 2026 · 17:08

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

Greta Feb 17, 2026 · 20:08

Interesting thought, thanks for adding that.

Felix Mar 14, 2026 · 20:08

Good question, I'd like to know too.

Elena Mar 07, 2026 · 17:08

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


Leave a comment

Estimated Read Time
4 minutes

643 words

An unhandled error has occurred. Reload ๐Ÿ—™

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.