Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

API

A mobile app or a React front end needs data in JSON rather than HTML pages. Laravel returns JSON with almost no extra code: a model returned from a controller turns into it by itself.

API routes

In recent Laravel versions the API routes file is created with a command:

php artisan install:api

It adds the routes/api.php file. Every address in it starts with /api:

use App\Http\Controllers\Api\PostController;
use Illuminate\Support\Facades\Route;
 
Route::apiResource('posts', PostController::class);

apiResource registers five routes: list, view, create, update and delete.

The controller

php artisan make:controller Api/PostController --api

A model or a collection returned from a method automatically becomes JSON:

namespace App\Http\Controllers\Api;
 
use App\Http\Controllers\Controller;
use App\Models\Post;
 
class PostController extends Controller
{
    public function index()
    {
        return Post::latest()->paginate(20);
    }
 
    public function show(Post $post)
    {
        return $post;
    }
}

The Post $post parameter is route model binding: Laravel finds the record by the identifier in the address or returns 404.

Creating a record

public function store(Request $request)
{
    $data = $request->validate([
        'title' => 'required|max:255',
        'body' => 'required',
    ]);
 
    $post = Post::create($data);
 
    return response()->json($post, 201);
}

The 201 code means "created". If validation fails, the API client receives a 422 response with a list of errors in JSON — there is no redirect to a form.

API resources

Returning the whole model is inconvenient: every column, service ones included, ends up in the response. A resource describes exactly what the client sees:

php artisan make:resource PostResource
namespace App\Http\Resources;
 
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
 
class PostResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'published_at' => $this->created_at->toDateString(),
        ];
    }
}
return new PostResource($post);
return PostResource::collection(Post::paginate(20));

Deleting

public function destroy(Post $post)
{
    $post->delete();
 
    return response()->noContent();
}

noContent() sends the 204 code — "done, no response body".

Authentication

The install:api command installs the Sanctum package. The client sends a token in the Authorization header, and routes are protected with middleware:

Route::middleware('auth:sanctum')->group(function () {
    Route::apiResource('posts', PostController::class)->except(['index', 'show']);
});

Common mistake

The client must send the Accept: application/json header. Without it Laravel treats the request as a regular one and answers a validation failure with a redirect instead of JSON with the errors.

Thanks for reading!

Donate to the site — we work hard for you.