Laravel Mastery: API Design & Documentation

10 minute read Laravel Mastery · Part 7

Build clean, versioned, and well-documented APIs in Laravel using resources, route groups, validation layers, and OpenAPI documentation tooling.

A well-structured API is easy to consume, version, and maintain. Laravel’s routing, resources, and validation features make it a strong foundation for robust RESTful API development.

API Structure & Versioning

Organise APIs with versioned route groups:

Route::prefix('v1')->group(function () {
    Route::apiResource('products', ProductController::class);
});

Use subfolders in controllers:

App\Http\Controllers\API\V1\ProductController

HTTP Standards Matter

Stick to standard methods:

  • GET /products
  • POST /products
  • GET /products/{id}
  • PUT /products/{id}
  • DELETE /products/{id}

Return correct status codes:

  • 200 OK
  • 201 Created
  • 204 No Content
  • 404 Not Found
  • 422 Validation Error

Resource Responses

Use JsonResource for consistent output:

return new ProductResource($product);

Define shape:

class ProductResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'price' => $this->formatted_price,
        ];
    }
}

Collection responses:

return ProductResource::collection(Product::all());

Input Validation

Use Form Requests:

php artisan make:request StoreProductRequest
public function rules()
{
    return [
        'name' => 'required|string|max:255',
        'price' => 'required|numeric|min:0',
    ];
}

In controller:

public function store(StoreProductRequest $request)
{
    $product = Product::create($request->validated());
    return new ProductResource($product);
}

Auth & Throttling

Use Sanctum or Passport for token auth:

composer require laravel/sanctum

Protect routes:

Route::middleware('auth:sanctum')->group(function () {
    Route::get('/user', function (Request $request) {
        return $request->user();
    });
});

Throttle requests:

Route::middleware('throttle:60,1')->group(...);

OpenAPI / Swagger Docs

Use Laravel Scribe or Swagger-PHP:

composer require knuckleswtf/scribe --dev
php artisan scribe:generate

Document routes with PHPDoc:

/**
 * List all products
 *
 * @response 200 array<Product>
 */
public function index()

Real-World Outcomes

For the jewellery commerce platform, the API allowed:

  • Mobile app integration
  • Internal tools with token auth
  • Auto-generated docs for third-party logistics

Best Practices

  • Version all public APIs
  • Use JsonResource for all output
  • Validate with Form Requests
  • Write Swagger docs inline
  • Avoid business logic in controllers