Controllers

  • Use Resource Controllers: Generate API-specific resource controllers to handle CRUD operations.
BASH
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.
BASH
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.
BASH
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:

JSON
{
    "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:

JSON
{
    "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 Entity response with a standard structure that includes a main message and a detailed list of errors for each field.

A standard Laravel validation error response:

JSON
{
    "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.php to 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 ok with a message There 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.