A resourceful API maps HTTP verbs and URLs onto a predictable set of actions, so anyone consuming it can guess the shape without reading your docs. Laravel gives you this for free with apiResource:
// routes/api.php
Route::apiResource('projects', ProjectController::class);
That single line registers five routes:
GET /api/projects index
POST /api/projects store
GET /api/projects/{project} show
PUT /api/projects/{project} update
DELETE /api/projects/{project} destroy
Notice there's no create or edit route — those exist in the web resource controller to return HTML forms, but an API has no forms to render, so apiResource skips them. Generate the matching controller with the --api flag so Laravel stubs out exactly these five methods instead of all seven:
php artisan make:controller Api/ProjectController --api --model=Project
Route model binding works identically to web routes — type-hint the model in the method signature and Laravel resolves {project} to an actual Project instance, returning a 404 automatically if it doesn't exist:
public function show(Project $project)
{
return $project;
}
Returning a model directly, like above, works because Eloquent models implement Arrayable and Jsonable — Laravel serializes them to JSON automatically. That's fine for a quick prototype, but it means every public column and loaded relationship goes straight into the response, including things like timestamps or foreign keys you might not want exposed. That's the exact problem the next lesson solves.