# Building RESTful APIs the Right Way in ASP.NET Core

APIs are the backbone of most modern web and mobile apps, and ASP.NET Core makes building them a breeze. But doing it *right* means thinking beyond just returning data.

In this post, we’ll walk through building clean, RESTful APIs with ASP.NET Core that follow best practices and avoid common pitfalls.

---

## 🛠️ Project Setup

If you don’t already have a project:

```bash
dotnet new webapi -n MyApiApp
cd MyApiApp
```

---

## 🧭 Creating Your Controller

```csharp
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private static List<Product> _products = new();

    [HttpGet]
    public IActionResult GetAll() => Ok(_products);

    [HttpGet("{id}")]
    public IActionResult GetById(int id)
    {
        var product = _products.FirstOrDefault(p => p.Id == id);
        if (product is null) return NotFound();
        return Ok(product);
    }

    [HttpPost]
    public IActionResult Create(Product product)
    {
        product.Id = _products.Count + 1;
        _products.Add(product);
        return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
    }
}
```

---

## 📦 The Model

```csharp
public class Product
{
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    public decimal Price { get; set; }
}
```

✅ ASP.NET Core automatically validates model properties like `[Required]`.

---

## 🛡️ Model Validation

If your model is invalid, `ApiController` will return a `400 Bad Request` with details — no extra code needed.

You can check explicitly like this:

```csharp
if (!ModelState.IsValid)
    return BadRequest(ModelState);
```

But often it’s not even necessary.

---

## 🔁 Returning the Right HTTP Status Codes

- `200 OK` – when data is successfully returned
- `201 Created` – when you create a resource
- `204 No Content` – when you successfully delete or update without returning content
- `400 Bad Request` – when validation fails
- `404 Not Found` – when a resource doesn't exist

Let your API speak clearly and predictably.

---

## 🧪 Swagger for Free

ASP.NET Core comes with Swagger UI out of the box.

- Add this to `Program.cs` (if not already there):

```csharp
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

app.UseSwagger();
app.UseSwaggerUI();
```

Now hit `https://localhost:5001/swagger` to test your API visually!

---

## 🧼 Bonus: Use DTOs for Clean APIs

Avoid returning full database models. Use DTOs (Data Transfer Objects):

```csharp
public class ProductDto
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}
```

It helps keep internal logic decoupled from API responses.

---

## ✅ Up Next

Now that you can build clean APIs, let’s talk about data persistence with **Entity Framework Core** — code-first, migrations, relationships, and more.

➡️ [Entity Framework Core Deep Dive →](./efcore-database-access)

Let’s move from “working” to *wow* 🚀

