Welcome to dotnet.rest

Comprehensive guide to REST APIs in the .NET ecosystem with best practices, patterns, and implementation guidance

This comprehensive documentation serves as your complete guide to understanding, designing, implementing, and consuming REST APIs in the .NET ecosystem. Whether you’re building your first API or looking to refine your existing services, this resource provides practical guidance, best practices, and real-world examples.

About This Documentation

This documentation is regularly updated with the latest .NET REST practices and patterns as of May 2025.

Who Is This For?

This documentation is designed for:

  • Beginners: Those new to REST API concepts and implementation
  • Intermediate Developers: Those looking to deepen their understanding and refine their approach
  • Architects: Those making design decisions about API strategies

What You’ll Learn

The documentation is structured to provide a complete learning path from fundamental REST principles to advanced implementation techniques:

SectionWhat You’ll Find
What is REST?Core REST concepts, architectural constraints, and the historical evolution from SOAP to modern REST
Why REST?Strategic benefits, ideal use cases, limitations, and comparisons with alternative approaches
BasicsResource modeling, RESTful constraints, content negotiation, and essential HTTP concepts
Best PracticesAPI design patterns, status code usage, versioning strategies, and security implementation
LibrariesIn-depth analysis of .NET client libraries (HttpClient, Refit, RestSharp) and server frameworks
AlternativesComparative analysis of gRPC, GraphQL, SOAP, and event-driven architectures for specialized scenarios

Key Features

  • Real-world code examples in C# and ASP.NET Core
  • Interactive samples that you can run and modify
  • Decision guides to help you make the right architectural choices
  • Performance considerations to ensure your APIs scale efficiently
  • Security best practices to protect your services and data

Getting Started

New to REST APIs? We recommend starting with these foundational articles:

  1. What is REST? - Understand the core concepts
  2. Why REST? - Learn when REST is the right choice
  3. REST Constraints - Explore the architectural constraints
  4. Your First REST API - Build a simple API with ASP.NET Core

Examples and Code Samples

Throughout this documentation, you’ll find practical code samples that demonstrate REST concepts. Most examples use C# with ASP.NET Core for server implementations and various client libraries for consumption.

// Simple ASP.NET Core REST endpoint
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly IProductService _productService;
    
    public ProductsController(IProductService productService)
    {
        _productService = productService;
    }

    [HttpGet]
    [ProducesResponseType(typeof(IEnumerable<Product>), StatusCodes.Status200OK)]
    public ActionResult<IEnumerable<Product>> GetAll()
    {
        IEnumerable<Product> products = _productService.GetAllProducts();
        return Ok(products);
    }
    
    [HttpGet("{id}")]
    [ProducesResponseType(typeof(Product), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public ActionResult<Product> GetById(int id)
    {
        Product product = _productService.GetById(id);
        if (product == null)
            return NotFound();
        
        return Ok(product);
    }
    
    [HttpPost]
    [ProducesResponseType(typeof(Product), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public ActionResult<Product> Create(ProductCreateDto productDto)
    {
        Product newProduct = _productService.CreateProduct(productDto);
        return CreatedAtAction(
            nameof(GetById), 
            new { id = newProduct.Id }, 
            newProduct
        );
    }
}

Running examples are available in the samples directory of the repository.

Key REST API Design Principles

When designing REST APIs in the .NET ecosystem, adhering to these core principles will ensure your APIs are intuitive, maintainable, and aligned with industry standards:

1. Resource-Oriented Design

Structure your API around resources (nouns) rather than actions (verbs):

Good Resource Design:

  • GET /api/products - Retrieve all products
  • GET /api/products/123 - Retrieve product with ID 123
  • POST /api/products - Create a new product
  • PUT /api/products/123 - Update product with ID 123

Poor Resource Design:

  • GET /api/getProducts - Using verbs in URLs
  • POST /api/createProduct - Action-oriented instead of resource-oriented
  • GET /api/productData/123 - Inconsistent resource naming

2. Use HTTP Methods Appropriately

Each HTTP method carries specific semantics in a RESTful design:

MethodPurposeIdempotentSafe
GETRead resourcesYesYes
POSTCreate resourcesNoNo
PUTReplace resourcesYesNo
PATCHPartially update resourcesNo*No
DELETERemove resourcesYesNo

*PATCH can be idempotent depending on implementation

3. Implement Proper Status Codes

Communicate results clearly with appropriate HTTP status codes:

// Example of proper status code usage
[HttpPost]
public ActionResult<Order> CreateOrder(OrderCreateDto orderDto)
{
    if (!ModelState.IsValid)
        return BadRequest(ModelState);  // 400 Bad Request
        
    if (orderDto.CustomerId <= 0)
        return UnprocessableEntity(new { Error = "Invalid customer ID" });  // 422 Unprocessable Entity
        
    try 
    {
        Order newOrder = _orderService.CreateOrder(orderDto);
        return CreatedAtAction(nameof(GetOrder), new { id = newOrder.Id }, newOrder);  // 201 Created
    }
    catch (InsufficientInventoryException ex)
    {
        return Conflict(new { Error = ex.Message });  // 409 Conflict
    }
}

ASP.NET Core Implementation Patterns

Dependency Injection

Rely on ASP.NET Core’s built-in dependency injection container to decouple components:

// Service registration in Program.cs
builder.Services.AddScoped<IProductRepository, ProductRepository>();
builder.Services.AddScoped<IProductService, ProductService>();

Clean Controller Organization

Keep controllers focused on HTTP concerns while delegating business logic to services:

[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
    private readonly IOrderService _orderService;
    private readonly ILogger<OrdersController> _logger;
    
    public OrdersController(IOrderService orderService, ILogger<OrdersController> logger)
    {
        _orderService = orderService;
        _logger = logger;
    }
    
    [HttpGet("{id}")]
    public async Task<ActionResult<OrderDto>> GetOrder(int id)
    {
        _logger.LogInformation("Retrieving order {OrderId}", id);
        
        OrderDto order = await _orderService.GetOrderByIdAsync(id);
        
        if (order == null)
        {
            _logger.LogWarning("Order {OrderId} not found", id);
            return NotFound();
        }
        
        return Ok(order);
    }
}

Next Steps

Continue exploring the documentation to build your expertise in REST API development:


Understanding REST: Representational State Transfer

Fundamental introduction to REST architectural principles, constraints, and evolution

Why Choose REST for Your API?

Explore the benefits, use cases, and strategic advantages of REST API architecture