Laravel pro začátečníky: první aplikace s modelem, migrací a API
Založte projekt v Laravelu, vytvořte model s migrací, kontroler s validací a JSON API. Vysvětlení struktury, Eloquentu a příkazů Artisan.
Laravel je nejpopulárnější PHP framework a pro nový webový projekt v PHP bývá rozumnou výchozí volbou. Má hotové řešení pro routing, databázi, validaci, fronty i autentizaci. V tomto návodu postavíme malé API pro správu článků a projdeme klíčové pojmy.
Instalace
Laravel 12 vyžaduje PHP 8.2 nebo novější a Composer. Nový projekt založíte takto:
composer create-project laravel/laravel blog-api
cd blog-api
php artisan serve
Aplikace poběží na http://127.0.0.1:8000. Alternativně můžete použít instalátor laravel new blog-api, který se nainstaluje přes composer global require laravel/installer.
Výchozí databáze je od Laravelu 11 SQLite (soubor database/database.sqlite), takže nemusíte nic nastavovat. Pro MySQL nebo PostgreSQL upravte .env:
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=blog
DB_USERNAME=blog
DB_PASSWORD=tajne-heslo
Soubor .env nikdy necommitujte – je v .gitignore a jako šablona slouží .env.example.
Kde co je
| Adresář | Obsah |
|---|---|
app/Models |
Eloquent modely |
app/Http/Controllers |
kontrolery |
routes/web.php |
webové routy |
routes/api.php |
API routy (vzniká až příkazem install:api) |
database/migrations |
migrace schématu |
config/ |
konfigurace (čte hodnoty z .env) |
storage/logs/laravel.log |
log aplikace |
API routy
Od Laravelu 11 je routes/api.php volitelný. Přidáte ho příkazem:
php artisan install:api
Ten zároveň nainstaluje Laravel Sanctum pro tokenovou autentizaci. Routy v tomto souboru mají automaticky prefix /api.
Model a migrace
Jedním příkazem vytvoříte model, migraci, kontroler a form request:
php artisan make:model Article -mcR --api
Přepínače: -m migrace, -c kontroler, -R form requesty pro validaci, --api kontroler bez metod create a edit (ty slouží jen pro HTML formuláře).
Upravte migraci v database/migrations/xxxx_create_articles_table.php:
public function up(): void
{
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('slug')->unique();
$table->text('body');
$table->timestamp('published_at')->nullable();
$table->timestamps();
});
}
A spusťte ji:
php artisan migrate
V modelu app/Models/Article.php povolte hromadné přiřazení vybraných polí:
class Article extends Model
{
protected $fillable = ['title', 'slug', 'body', 'published_at'];
protected function casts(): array
{
return ['published_at' => 'datetime'];
}
}
$fillable chrání před tím, aby si někdo poslal v požadavku třeba is_admin a model ho uložil.
Validace
app/Http/Requests/StoreArticleRequest.php:
public function authorize(): bool
{
return true; // tady by měla být kontrola oprávnění
}
public function rules(): array
{
return [
'title' => ['required', 'string', 'max:200'],
'slug' => ['required', 'alpha_dash', 'unique:articles,slug'],
'body' => ['required', 'string'],
'published_at' => ['nullable', 'date'],
];
}
Pokud validace selže, Laravel u požadavku s hlavičkou Accept: application/json automaticky vrátí 422 s chybami podle polí.
Kontroler
app/Http/Controllers/ArticleController.php:
class ArticleController extends Controller
{
public function index()
{
return Article::whereNotNull('published_at')
->latest('published_at')
->paginate(20);
}
public function store(StoreArticleRequest $request)
{
$article = Article::create($request->validated());
return response()->json($article, 201);
}
public function show(Article $article)
{
return $article;
}
public function update(UpdateArticleRequest $request, Article $article)
{
$article->update($request->validated());
return $article;
}
public function destroy(Article $article)
{
$article->delete();
return response()->noContent();
}
}
Article $article v parametru je route model binding – Laravel podle ID z URL načte model, a pokud neexistuje, vrátí 404. paginate(20) vrátí data i metadata stránkování.
Do routes/api.php přidejte jeden řádek:
use App\Http\Controllers\ArticleController;
Route::apiResource('articles', ArticleController::class);
Výpis všech rout zobrazí php artisan route:list.
Vyzkoušení
curl -X POST http://127.0.0.1:8000/api/articles \
-H "Accept: application/json" -H "Content-Type: application/json" \
-d '{"title":"Ahoj Laravel","slug":"ahoj-laravel","body":"Text","published_at":"2026-10-12"}'
curl http://127.0.0.1:8000/api/articles
Bez hlavičky Accept: application/json by vás Laravel při chybě validace přesměroval zpět, jako u HTML formuláře.
Tinker na rychlé pokusy
php artisan tinker
Article::count();
Article::where('slug', 'ahoj-laravel')->first()->title;
Časté začátečnické chyby
- N+1 dotazy – v cyklu přistupujete k relaci (
$article->author->name) a pro každý řádek vznikne dotaz. Řešení:Article::with('author')->get(). Při vývoji pomůžeModel::preventLazyLoading()vAppServiceProvider. APP_DEBUG=truena produkci – zobrazí stack trace i hodnoty z prostředí.- Chybějící
APP_KEY– vygenerujtephp artisan key:generate. - Práva – webový server musí mít zápis do
storage/abootstrap/cache/.
Před nasazením
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan optimize
optimize nacachuje konfiguraci, routy, události i šablony. Po každé změně .env je nutné cache obnovit znovu.
Pro práci na existujícím Laravel projektu se hodí nahrát ho do ColdHost AI jako projekt (ZIP nebo GitHub) – AI pak vidí modely i migrace pohromadě a navrhované úpravy jsou konzistentní s vaším kódem.