Controllers
- Use Resource Controllers: Generate API-specific resource controllers to handle CRUD operations.
php artisan make:controller PhotoController --api
- Keep Controllers Thin: Avoid placing business logic directly in your controllers. Instead, abstract complex logic into service classes or action classes.
- Dependency Injection: Inject dependencies into your controllers to promote decoupling and improve testability.
Request Validation
Validate all incoming data to ensure its integrity and prevent security vulnerabilities.
- Use Form Requests: For complex validation, create dedicated form request classes. This keeps your controllers clean and your validation logic reusable.
php artisan make:request StorePhotoRequest
- Automatic JSON Responses: Laravel automatically returns validation errors as a JSON response when an API request fails validation.
API Resources (Data Transformation)
Standardize your API responses by using a transformation layer between your Eloquent models and the JSON output.
- Create Resource Classes: Generate resource classes to control the data and structure of your JSON responses.
php artisan make:resource PhotoResource
- Consistent Responses: API resources help in transforming models into consistent JSON responses. This allows you to hide sensitive information and format data as needed.
- Resource Collections: Use resource collections to transform and paginate lists of models.
Standard Payload Structures
Using a consistent payload structure across all endpoints makes your API predictable and easier for clients to consume.Specifications like JSON:API can provide a good starting point. The simplest approach is to use a consistent "envelope" for your data.
- Successful Responses Always wrap successful responses in a data key. This prevents ambiguity and provides a consistent location for the primary data of the response.
A typical successful response should look like this:
{
"data": {
"id": 1,
"title": "My First Post",
"content": "..."
}
}
- Error Responses For general errors (e.g., Not Found, Server Error), return a JSON object with a top-level error key. This key should contain a descriptive message.
A generic error response should look like this:
{
"error": {
"message": "The requested resource was not found."
}
}
- Validation Error Responses:
Laravel has a sensible default for validation errors. When a Form Request fails, it automatically returns a
422 Unprocessable Entityresponse with a standard structure that includes a main message and a detailed list of errors for each field.
A standard Laravel validation error response:
{
"message": "The given data was invalid.",
"errors": {
"title": [
"The title field is required."
],
"body": [
"The body must be at least 10 characters."
]
}
}
Packages we Recommend
Some packages we recommend to use to make your responses and structure better and dynamic.
Error Handling
Properly handle exceptions and return meaningful error responses.
- Custom Exception Handler: Customize the global exception handler in
app/Exceptions/Handler.phpto format API error responses consistently, adhering to the payload structure defined above. - Use Appropriate HTTP Status Codes: Return correct status codes to indicate the outcome of a request. Do not return
200 okwith a messageThere was an error with.... 200 OK: Successful request.201 Created: Resource successfully created.204 No Content: Resource successfully deleted.400 Bad Request: Malformed request.401 Unauthorized: Authentication is required.403 Forbidden: Authenticated user is not allowed to access the resource.404 Not Found: The requested resource does not exist.500 Internal Server Error: A server-side error occurred.
