Working with APIs
ASP.NET Core builds REST APIs with minimal APIs or controllers, model binding, validation, OpenAPI/Swagger, and ProblemDetails error responses.
Introduction
ASP.NET Core builds REST APIs with minimal APIs or controllers, model binding, validation, OpenAPI/Swagger, and ProblemDetails error responses. HttpClient (via IHttpClientFactory) consumes external APIs.
Interviewers ask REST principles, status codes, idempotency, versioning, and middleware pipeline order.
The story
A fintech startup exposes a POST /api/payments endpoint that validates the amount, charges the customer through a gateway abstraction, and returns HTTP 201 Created with a location header pointing to the new payment record. Invalid amounts return 400 with structured validation errors — the same ProblemDetails format front-end apps expect.
Understanding the topic
Key concepts
- Minimal APIs MapGet/MapPost with lambda or delegate.
- Controller [ApiController] with automatic 400 on validation.
- Model binding from route, query, body.
- IHttpClientFactory typed clients with resilience.
- ProblemDetails RFC 7807 standard errors.
- OpenAPI document generation Swashbuckle/NSwag.
flowchart LRClient --> KestrelKestrel --> Middleware[Middleware Pipeline]Middleware --> RoutingRouting --> Controller[Minimal API / Controller]Controller --> Response[JSON Response]
Step-by-step explanation
- Request hits middleware → routing → endpoint.
- Binding populates parameters; validation runs.
- Handler returns IResult or IActionResult.
- JSON serializer writes response.
- Exception handler middleware maps to 500 ProblemDetails.
- Typed HttpClient registers base address and policies.
Practical code example
Minimal API with validation filter and typed HttpClient consumer:
namespace TechLearningPro.Apis;public record CreatePaymentRequest(decimal Amount, string Currency);public record PaymentResponse(Guid Id, string Status);public static class PaymentEndpoints{public static void MapPaymentApi(this WebApplication app){app.MapPost("/api/payments", async (CreatePaymentRequest req,IPaymentGateway gateway,CancellationToken ct) =>{if (req.Amount <= 0)return Results.ValidationProblem(new Dictionary<string, string[]>{["amount"] = ["Must be positive."]});var result = await gateway.ChargeAsync(req.Amount, req.Currency, ct);return Results.Created(quot;/api/payments/{result.Id}", result);});}}public interface IPaymentGateway{Task<PaymentResponse> ChargeAsync(decimal amount, string currency, CancellationToken ct);}
Line-by-line code explanation
record CreatePaymentRequest(decimal Amount, string Currency)is the JSON request body shape.record PaymentResponse(Guid Id, string Status)is the success response DTO.MapPaymentApi(this WebApplication app)is an extension method organizing endpoint registration.app.MapPost("/api/payments", async (...))registers a POST handler on the route.if (req.Amount <= 0) return Results.ValidationProblem(...)returns 400 with field-level errors.await gateway.ChargeAsync(req.Amount, req.Currency, ct)delegates payment to the injected gateway.Results.Created($"/api/payments/{result.Id}", result)returns 201 with Location header and body.IPaymentGatewayabstraction allows swapping Stripe, Adyen, or a test fake in DI.
Key takeaway: Results.ValidationProblem returns 400 ProblemDetails. Created returns 201 with Location. Gateway injected via DI for testability.
Real-world use
Where you'll use this in production
- Mobile backend BFF aggregating microservices.
- Payment webhook receivers.
- Internal admin APIs with OpenAPI docs.
- Third-party SaaS integration via HttpClient.
Best practices
- Use correct HTTP verbs and status codes.
- Validate input; never trust client.
- IHttpClientFactory not new HttpClient().
- Version APIs /api/v1/ or header.
- Enable HTTPS, rate limiting, authentication.
Common mistakes
- GET with side effects.
- Returning 200 with error in body only.
- Leaking exception details in production 500.
- Missing CancellationToken on I/O endpoints.
Advanced interview questions
Q1BeginnerREST idempotent methods?
Q2Beginner201 vs 200?
Q3IntermediateIHttpClientFactory why?
Q4IntermediateMinimal API vs controllers?
Q5AdvancedDesign idempotent POST payment endpoint.
Summary
ASP.NET Core exposes REST via minimal APIs or controllers. Model binding, validation, and ProblemDetails standardize APIs. IHttpClientFactory integrates external HTTP services. Correct status codes and idempotency matter in production. Next: Entity Framework Core.