Fáze požadavku: 4. Routing & Matchování tras
Modul 8 · Lekce 2

Healthcheck endpoint /up, JSON API odpovědi a CORS v praxi

💡 Shrnutí lekce

Moderní monitorovací endpoint /up v Laravelu 12, návrh lehkých JSON API endpointů přes Closure routy a správa Cross-Origin Resource Sharing (CORS).

Monitoring a API rozhraní v moderním Laravelu 12

V éře kontejnerů a mikroslužeb musí každá aplikace poskytovat mechanismus, kterým Docker, Kubernetes nebo reverzní proxy Caddy ověřuje, zda je aplikace "živá" a schopná odbavovat požadavky (Healthcheck & Liveness Probe).

Laravel 12 přináší revoluci ve způsobu konfigurace aplikace: ruší starý Http/Kernel.php a vše centralizuje do souboru bootstrap/app.php.

Nativní Healthcheck endpoint /up

V bootstrap/app.php naší aplikace najdete tento zápis:

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware): void {
        $middleware->web(append: [
            EnsureStudentProfile::class,
        ]);
    })
    ->withExceptions(function (Exceptions $exceptions): void {
        //
    })->create();

Parametr health: '/up' automaticky zaregistruje interní trasu /up. Tento endpoint:

  1. Reaguje okamžitě s HTTP kódem 200 OK.
  2. Má minimální režii, protože neprochází plnou sadou session ani autentizačních middlewarů.
  3. Spouští interní diagnostický event Illuminate\Foundation\Events\DiagnosingHealth, na který mohou Service Provideři napojit kontrolu spojení s PostgreSQL databází nebo Redis cache.
  4. Je ideálním cílem pro Docker direktivu HEALTHCHECK CMD curl -f http://localhost:80/up || exit 1.

Stavba lehkých JSON API endpointů v routes/web.php

Kromě standardních Blade pohledů naše aplikace vystavuje také monitorovací JSON endpoint /api/status:

Route::get('/api/status', function (): JsonResponse {
    return response()->json([
        'app' => config('app.name'),
        'php_version' => PHP_VERSION,
        'laravel_version' => app()->version(),
        'modules_count' => CourseModule::count(),
        'lessons_count' => CourseLesson::count(),
        'status' => 'ok',
    ]);
})->name('api.status');

Všimněte si:

  • Explicitní návratový typ JsonResponse zajišťuje striktní typovou kontrolu v PHP 8.4.
  • Pomocník response()->json(...) automaticky nastaví správnou hlavičku Content-Type: application/json a zformátuje pole pomocí json_encode() s ošetřením UTF-8 znaků.
  • Data dynamicky zjišťují stav aplikace (počet modulů a lekcí v PostgreSQL).

Cross-Origin Resource Sharing (CORS)

Pokud by náš JSON endpoint chtěl konzumovat frontend z jiné domény (např. mobilní aplikace nebo externí dashboard), prohlížeč by vyslal předběžný požadavek OPTIONS (tzv. preflight request).

V Laravelu 12 lze CORS pravidla konfigurovat jednoduše přímo v bootstrap/app.php nebo v config/cors.php:

  • allowed_origins: Seznam povolených domén (např. ['https://heatsharing.cz']).
  • allowed_methods: Povolené HTTP slovesa (['GET', 'POST', 'OPTIONS']).
  • allowed_headers: Povolené hlavičky (např. ['Content-Type', 'X-Requested-With']).
💻 Klíčová konstrukce z praxe
// bootstrap/app.php:10-16
return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    // ...

// routes/web.php:20-29
Route::get('/api/status', function (): JsonResponse {
    return response()->json([
        'app' => config('app.name'),
        'php_version' => PHP_VERSION,
        'laravel_version' => app()->version(),
        'modules_count' => CourseModule::count(),
        'lessons_count' => CourseLesson::count(),
        'status' => 'ok',
    ]);
})->name('api.status');

🎯 Ověření znalostí z lekce

Kvíz otestuje pochopení architektury a reálného kódu probíraného v této lekci.

Otázka 1 z 3

K čemu slouží konfigurace health: '/up' v souboru bootstrap/app.php v Laravelu 12?

Otázka 2 z 3

Jaká hlavička je automaticky nastavena v HTTP odpovědi při použití pomocníka response()->json(...) v Laravelu?

Otázka 3 z 3

Jaký HTTP požadavek (metodu) posílá webový prohlížeč jako tzv. "preflight" dotaz před odesláním cross-origin požadavku s vlastními hlavičkami?

Zodpovězeno: 0 / 3
🔬 Živá anatomie v této aplikaci
2 soubory
Na co se v kódu zaměřit: V souboru bootstrap/app.php si všimni řádku 14 (health: '/up') — toto je nativní mechanismus Laravelu 12 pro Docker a load balancery. V routes/web.php si prohlédni endpoint /api/status vracející JsonResponse s verzemi PHP, Laravelu a počty modulů.
cesta: bootstrap/app.php
23 řádků · 0.7 KB
Nové jádro Laravel 12 pro registraci webových i konzolových rout, middleware pipeline a zachytávání výjimek bez Http Kernelu.
1 <?php
2
3 declare(strict_types=1);
4
5 use App\Http\Middleware\EnsureStudentProfile;
6 use Illuminate\Foundation\Application;
7 use Illuminate\Foundation\Configuration\Exceptions;
8 use Illuminate\Foundation\Configuration\Middleware;
9
10 return Application::configure(basePath: dirname(__DIR__))
11 ->withRouting(
12 web: __DIR__.'/../routes/web.php',
13 commands: __DIR__.'/../routes/console.php',
14 health: '/up',
15 )
16 ->withMiddleware(function (Middleware $middleware): void {
17 $middleware->web(append: [
18 EnsureStudentProfile::class,
19 ]);
20 })
21 ->withExceptions(function (Exceptions $exceptions): void {
22 //
23 })->create();
24
cesta: routes/web.php
29 řádků · 1.1 KB
Definice webových tras, Route Model Binding pro moduly a lekce, mapování na Controllery a API status endpoint.
1 <?php
2
3 declare(strict_types=1);
4
5 use App\Http\Controllers\AnatomyController;
6 use App\Http\Controllers\CourseController;
7 use App\Models\CourseLesson;
8 use App\Models\CourseModule;
9 use Illuminate\Http\JsonResponse;
10 use Illuminate\Support\Facades\Route;
11
12 Route::get('/', [CourseController::class, 'index'])->name('course.index');
13 Route::get('/anatomie', [AnatomyController::class, 'index'])->name('anatomy.index');
14
15 Route::post('/profil/prenosovy-kod', [CourseController::class, 'switchProfile'])->name('course.switch-profile');
16
17 Route::get('/moduly/{module:slug}', [CourseController::class, 'module'])->name('course.module');
18 Route::get('/moduly/{module:slug}/lekce/{lesson:slug}', [CourseController::class, 'lesson'])->name('course.lesson');
19
20 Route::get('/api/status', function (): JsonResponse {
21 return response()->json([
22 'app' => config('app.name'),
23 'php_version' => PHP_VERSION,
24 'laravel_version' => app()->version(),
25 'modules_count' => CourseModule::count(),
26 'lessons_count' => CourseLesson::count(),
27 'status' => 'ok',
28 ]);
29 })->name('api.status');
30
Zdroj: skutečné soubory této aplikace Plný průzkumník anatomie →