API Versioning

  1. Rate Limiting
  2. JWT Authentication
  3. Idempotency
  4. API Keys
  5. API Versioning
  6. Pagination
  7. Consistent Error Format
Client
Server

Before

Route::get('/api/orders/{id}', [OrderController::class, 'show']);

class OrderController
{
    public function show(Order $order): JsonResponse
    {
        // changing this shape breaks every existing client at once
        return response()->json([
            'id' => $order->id,
            'total' => $order->total,
        ]);
    }
}

After

Route::get('/api/v1/orders/{id}', [OrderV1Controller::class, 'show']);
Route::get('/api/v2/orders/{id}', [OrderV2Controller::class, 'show']);

class OrderV2Controller
{
    public function show(Order $order): JsonResponse
    {
        // v1 keeps its old shape, untouched, in its own controller
        return response()->json([
            'id' => $order->id,
            'total' => ['amount' => $order->total, 'currency' => 'USD'],
        ]);
    }
}
{CC}