If you are working with ASP.NET Core Web API, you will frequently hear the term REST API. But what does REST actually mean, and how do you implement it properly in .NET? Let’s break it down step by step with practical examples.
What is REST?
REST stands for Representational State Transfer. It is an architectural style for building distributed systems, especially web services, that communicate over HTTP.
Key REST principles:
-
Resources, not actions → Think in nouns like
/api/books
instead of verbs like/api/getBooks
. -
HTTP methods define actions
-
GET
→ fetch data -
POST
→ create -
PUT
→ replace -
PATCH
→ partial update -
DELETE
→ remove
-
-
Stateless → Each request contains everything needed. The server does not store session data.
-
Multiple representations → Same resource can be returned in JSON, XML, etc.
-
Cacheable → Responses should support caching for performance.
In short: REST APIs are about clean URLs, proper HTTP methods, and stateless communication.
REST in .NET
In ASP.NET Core, REST APIs are built using:
-
Controllers or Minimal APIs
-
Attributes like
[HttpGet]
,[HttpPost]
,[HttpPut]
,[HttpDelete]
-
Model binding & validation
-
ActionResult / IActionResult for proper HTTP responses
Example: Building a REST API in ASP.NET Core
1. Define a Model (DTO)
public record BookDto
{
public int Id { get; init; }
public string Title { get; init; } = "";
public string Author { get; init; } = "";
}
2. In-memory Repository
public interface IBookRepository
{
Task<IEnumerable<BookDto>> GetAllAsync();
Task<BookDto?> GetByIdAsync(int id);
Task<BookDto> CreateAsync(BookDto book);
Task UpdateAsync(BookDto book);
Task DeleteAsync(int id);
}
public class InMemoryBookRepository : IBookRepository
{
private readonly List<BookDto> _books = new();
private int _nextId = 1;
public Task<IEnumerable<BookDto>> GetAllAsync() =>
Task.FromResult(_books.AsEnumerable());
public Task<BookDto?> GetByIdAsync(int id) =>
Task.FromResult(_books.FirstOrDefault(b => b.Id == id));
public Task<BookDto> CreateAsync(BookDto book)
{
var created = book with { Id = _nextId++ };
_books.Add(created);
return Task.FromResult(created);
}
public Task UpdateAsync(BookDto book)
{
var idx = _books.FindIndex(b => b.Id == book.Id);
if (idx >= 0) _books[idx] = book;
return Task.CompletedTask;
}
public Task DeleteAsync(int id)
{
var book = _books.FirstOrDefault(x => x.Id == id);
if (book != null) _books.Remove(book);
return Task.CompletedTask;
}
}
3. Create a REST Controller
[ApiController]
[Route("api/[controller]")]
public class BooksController : ControllerBase
{
private readonly IBookRepository _repo;
public BooksController(IBookRepository repo) => _repo = repo;
[HttpGet]
public async Task<ActionResult<IEnumerable<BookDto>>> GetAll()
{
var items = await _repo.GetAllAsync();
return Ok(items);
}
[HttpGet("{id}")]
public async Task<ActionResult<BookDto>> Get(int id)
{
var book = await _repo.GetByIdAsync(id);
return book is null ? NotFound() : Ok(book);
}
[HttpPost]
public async Task<ActionResult<BookDto>> Create(BookDto dto)
{
var created = await _repo.CreateAsync(dto);
return CreatedAtAction(nameof(Get), new { id = created.Id }, created);
}
[HttpPut("{id}")]
public async Task<IActionResult> Update(int id, BookDto dto)
{
if (id != dto.Id) return BadRequest();
var existing = await _repo.GetByIdAsync(id);
if (existing is null) return NotFound();
await _repo.UpdateAsync(dto);
return NoContent();
}
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(int id)
{
var existing = await _repo.GetByIdAsync(id);
if (existing is null) return NotFound();
await _repo.DeleteAsync(id);
return NoContent();
}
}
RESTful API Best Practices in .NET
✅ Use plural nouns for resources → /api/books
✅ Return correct status codes → 200
, 201
, 204
, 404
, 400
✅ Implement input validation and return problem details
✅ Add Swagger/OpenAPI for documentation
✅ Support paging, filtering, sorting with query parameters
✅ Use JWT authentication for secure APIs
✅ Apply versioning (e.g., /api/v1/books
)
When NOT to Use REST
-
Use gRPC for high-performance internal service-to-service communication.
-
Use GraphQL when clients need flexible queries and avoid multiple endpoints.
REST is best when:
-
You want simplicity
-
Standard HTTP semantics are enough
-
Clients benefit from caching
Conclusion
In .NET, REST APIs are built using ASP.NET Core’s Web API framework. By following REST principles—resources, HTTP verbs, statelessness, proper status codes—you can build clean, scalable, and maintainable APIs.
Start with a simple controller, use proper response codes, and then enhance with authentication, versioning, and documentation. That’s how you make a professional REST API in .NET.
No comments:
Post a Comment