Laravel
Quick Start
// routes/api.php Route::get('/health', fn () => ['status' => 'ok']);
Route::middleware('auth:sanctum')->group(function () { Route::apiResource('users', UserController::class); });
Features
Feature Description Guide
Models Eloquent ORM, relationships, scopes MODELS.md
Controllers Resource controllers, form requests CONTROLLERS.md
API Resources Response transformation RESOURCES.md
Auth Sanctum, policies, gates AUTH.md
Queues Jobs, events, listeners QUEUES.md
Testing Feature, unit tests TESTING.md
Common Patterns
Model with Relationships
class User extends Authenticatable { use HasApiTokens, HasFactory, SoftDeletes;
protected $fillable = ['name', 'email', 'password', 'role'];
protected $hidden = ['password', 'remember_token'];
protected $casts = ['email_verified_at' => 'datetime', 'password' => 'hashed'];
public function organizations(): BelongsToMany
{
return $this->belongsToMany(Organization::class, 'memberships')
->withPivot('role')
->withTimestamps();
}
public function scopeActive($query)
{
return $query->where('is_active', true);
}
public function scopeSearch($query, ?string $search)
{
return $search
? $query->where('name', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%")
: $query;
}
}
Controller with Service
class UserController extends Controller { public function __construct(private UserService $userService) {}
public function index(Request $request): PaginatedCollection
{
$users = $this->userService->list(
search: $request->input('search'),
perPage: $request->input('per_page', 20)
);
return new PaginatedCollection($users, UserResource::class);
}
public function store(CreateUserRequest $request): JsonResponse
{
$user = $this->userService->create($request->validated());
return (new UserResource($user))
->response()
->setStatusCode(201);
}
public function show(User $user): UserResource
{
return new UserResource($user->load('organizations'));
}
}
Form Request Validation
class CreateUserRequest extends FormRequest { public function authorize(): bool { return $this->user()->isAdmin(); }
public function rules(): array
{
return [
'name' => ['required', 'string', 'min:2', 'max:100'],
'email' => ['required', 'email', 'unique:users,email'],
'password' => ['required', 'confirmed', Password::min(8)->mixedCase()->numbers()],
'role' => ['sometimes', 'in:admin,user,guest'],
];
}
}
Workflows
API Development
-
Create model and migration
-
Create controller with php artisan make:controller --api
-
Add Form Request for validation
-
Create API Resource for responses
-
Write feature tests
Resource Response
class UserResource extends JsonResource { public function toArray(Request $request): array { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'organizations' => OrganizationResource::collection($this->whenLoaded('organizations')), 'created_at' => $this->created_at->toIso8601String(), ]; } }
Best Practices
Do Avoid
Use Form Requests for validation Validating in controllers
Use API Resources for responses Returning models directly
Use service classes for logic Fat controllers
Use eager loading N+1 queries
Use soft deletes Hard deletes for important data
Project Structure
app/ ├── Http/ │ ├── Controllers/Api/ │ ├── Requests/ │ ├── Resources/ │ └── Middleware/ ├── Models/ ├── Services/ ├── Policies/ ├── Jobs/ └── Events/ routes/ ├── api.php └── web.php tests/ ├── Feature/ └── Unit/
For detailed examples and patterns, see reference files above.