Make MVC RESTful API
MVC for RESTful APIs keeps HTTP request handling, domain behavior, persistence, and JSON response shaping separate. The controller owns routing, binding, authorization checks, status codes, and response mapping. Models and services own business behavior. Repositories or data-access adapters own persistence. JSON response DTOs or resources form the API contract.
- Model: Owns domain data, invariants, value objects, persisted entities, and business rules.
- Controller: Receives HTTP input, validates/binds request data, calls services or use-case handlers, and returns JSON with explicit status codes.
- Resource or Response DTO: Presents data as the public JSON contract. It should not expose internal persistence objects by accident.
- Service: Coordinates use cases, transactions, policies, repositories, and external integrations.
- Repository: Encapsulates persistence queries and mappings when persistence details should stay out of controllers and services.
Core Practices
- Design Endpoints Around Resources: Use clear resource names, HTTP verbs, route parameters, query parameters, and status codes.
- Keep Controllers Thin: Controllers should bind input, call application behavior, and map results to JSON responses.
- Use Request and Response DTOs: Treat request bodies and JSON responses as contracts. Do not expose ORM entities directly.
- Validate at Boundaries: Validate route params, query params, headers, and JSON bodies before calling services.
- Return Consistent Errors: Map validation, not-found, conflict, authorization, rate-limit, and unexpected failures to predictable JSON error shapes.
- Use Services for Workflows: Put multi-step use cases, transactions, authorization policy decisions, and side effects outside controllers.
- Use Repositories Deliberately: Isolate persistence details when queries, mappings, or storage choices would otherwise leak into controllers.
- Support Pagination and Filtering Intentionally: Make collection endpoints explicit about sorting, filtering, pagination, limits, and defaults.
- Secure by Default: Add authentication, authorization, input validation, safe database access, secret management, CORS rules, and rate limiting where appropriate.
- Test the Contract: Cover routing, validation, status codes, response bodies, authorization paths, repository behavior, and critical end-to-end flows.
- Externalize Configuration: Keep environment-specific settings and secrets outside the codebase.
- Document the API Shape: Document endpoints, DTOs, status codes, error shapes, auth requirements, environment variables, and deployment assumptions.
API Fit Criteria
- RESTful JSON APIs: Best fit for services exposing HTTP resources consumed by web, mobile, CLI, or integration clients.
- MVC-Organized Backends: Best fit when the project uses controllers, models, services, repositories, DTOs, and framework routing.
- CRUD and Workflow APIs: Good for both simple resource operations and use-case endpoints that still benefit from clear request/response contracts.
- Public or Team-Consumed APIs: Useful when stable JSON contracts, documentation, validation, and error consistency matter.
- Applications Expected to Grow: Keeps controllers from accumulating persistence logic, business rules, and ad hoc response mapping.
Reference Guides
- Controller Guidelines
- API Response Guidelines
- Model Binding Guidelines
- Service Layer Guidelines
- Repository Pattern Guidelines
- Database Guidelines
- Testing Guidelines
- API Security Guidelines
- Environment Variables Guidelines
- Docker Guidelines