› Backend

Laravel ile REST API: Sıfırdan Production'a Tam Rehber (2026)

25 March 2025 · 18 dk okuma · EMIXHAS Editör
Paylaş: WhatsApp X / Twitter LinkedIn Facebook

Modern web ve mobil uygulamaların kalbi REST API'lerdir. Frontend'i React, Vue veya Next.js ile yapsanız, mobil uygulamayı React Native veya Flutter'la geliştirseniz — backend'iniz neredeyse her zaman bir API olarak konumlanıyor. Laravel 11, API geliştirme için en güçlü PHP framework'lerinden biri. Eloquent ORM'in gücü, Sanctum'un sadeliği, queue sistemi, broadcasting, scheduling — kurumsal düzeyde API'lar için ihtiyacınız olan her şey hazır geliyor.

Bu kapsamlı rehberde sıfırdan production'a kadar tüm adımları detaylı şekilde işleyeceğiz: proje kurulumu, veritabanı tasarımı, authentication, rate limiting, validation, error handling, versiyonlama, test, dokümantasyon ve deploy. Junior'dan senior'a tüm seviyelerdeki PHP geliştiricileri için faydalı olacak.

1. Proje Kurulumu ve İlk Yapılandırma

Composer ile Laravel Yükleme

composer create-project laravel/laravel my-api
cd my-api
php artisan install:api

Laravel 11'de install:api komutu, Sanctum authentication ve API route'larını otomatik kurar. Bu komut routes/api.php dosyasını oluşturur ve gerekli middleware'leri yapılandırır.

Önemli Konfigürasyon Adımları

# .env dosyasını yapılandır
APP_NAME="MyAPI"
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost:8000

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=my_api
DB_USERNAME=root
DB_PASSWORD=

# Cache ve queue için Redis
CACHE_STORE=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379

Geliştirme Ortamı için Docker

Laravel Sail ile tek komutla Docker ortamı kurabilirsiniz:

php artisan sail:install
./vendor/bin/sail up -d

Sail; PHP 8.3, MySQL 8, Redis, Mailpit, MinIO ve daha fazlasını otomatik konteynerleştirir.

2. Veritabanı Tasarımı ve Migration'lar

Migration Yazma

php artisan make:model Product -mfsc

Bu komut model, migration, factory, seeder ve controller'ı bir arada üretir. Migration dosyasını düzenleyelim:

Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('sku')->unique();
    $table->string('name');
    $table->text('description')->nullable();
    $table->decimal('price', 10, 2);
    $table->integer('stock')->default(0);
    $table->foreignId('category_id')->constrained();
    $table->boolean('is_active')->default(true);
    $table->timestamps();
    $table->softDeletes();
    
    $table->index(['is_active', 'category_id']);
});

İlişkiler ve Eloquent Modeller

class Product extends Model
{
    use HasFactory, SoftDeletes;
    
    protected $fillable = ['sku', 'name', 'description', 'price', 'stock', 'category_id', 'is_active'];
    
    protected $casts = [
        'price' => 'decimal:2',
        'is_active' => 'boolean',
    ];
    
    public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }
    
    public function reviews(): HasMany
    {
        return $this->hasMany(Review::class);
    }
    
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }
}

3. API Resource'lar (Veri Dönüşümü)

Modeller doğrudan JSON'a dönüştürülmemeli. Resource sınıfları kullanın — bu sayede database alanlarını doğrudan dışa açmaz, response yapısını kontrol edersiniz.

php artisan make:resource ProductResource

class ProductResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'sku' => $this->sku,
            'name' => $this->name,
            'description' => $this->description,
            'price' => [
                'amount' => $this->price,
                'currency' => 'TRY',
                'formatted' => number_format($this->price, 2) . ' TL',
            ],
            'stock' => $this->stock,
            'is_in_stock' => $this->stock > 0,
            'category' => new CategoryResource($this->whenLoaded('category')),
            'created_at' => $this->created_at->toIso8601String(),
        ];
    }
}

Resource Collection'lar

Çoklu kayıt döndürmek için resource collection kullanın. Pagination meta verisi otomatik eklenir:

public function index(Request $request): ResourceCollection
{
    $products = Product::active()
        ->with('category')
        ->paginate($request->per_page ?? 20);
    
    return ProductResource::collection($products);
}

4. Authentication: Sanctum vs JWT

Laravel Sanctum (Önerilen)

Token bazlı kimlik doğrulama için Sanctum yeterli. JWT karmaşıklığına ihtiyaç yok; özellikle SPA ve mobil uygulamalarınız için ideal.

// Login endpoint
public function login(Request $request)
{
    $request->validate([
        'email' => 'required|email',
        'password' => 'required',
    ]);
    
    $user = User::where('email', $request->email)->first();
    
    if (! $user || ! Hash::check($request->password, $user->password)) {
        throw ValidationException::withMessages([
            'email' => ['Geçersiz kimlik bilgileri.'],
        ]);
    }
    
    $token = $user->createToken('mobile-app', ['product:read', 'order:write'])->plainTextToken;
    
    return response()->json([
        'token' => $token,
        'user' => new UserResource($user),
    ]);
}

Token Yetenekleri (Abilities)

Sanctum, token bazında scope/yetenek tanımlamayı destekler:

Route::get('/products', function () {
    // Tüm authentication'lı kullanıcılar
})->middleware('auth:sanctum');

Route::post('/products', function () {
    // Sadece product:write yeteneğine sahip token'lar
})->middleware(['auth:sanctum', 'ability:product:write']);

JWT Alternatifi

Mikroservis mimarisinde veya stateless ihtiyacınız varsa JWT tercih edilebilir. php-open-source-saver/jwt-auth paketi ile Laravel'e JWT eklenebilir. Ama çoğu durumda Sanctum yeterli ve sade.

5. Validation ve Form Request'ler

Inline validation kötü bir pratik. Form Request sınıfları ile validation logic'ini ayır:

php artisan make:request StoreProductRequest

class StoreProductRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user()->can('create', Product::class);
    }
    
    public function rules(): array
    {
        return [
            'sku' => ['required', 'string', 'max:50', 'unique:products,sku'],
            'name' => ['required', 'string', 'max:255'],
            'price' => ['required', 'numeric', 'min:0'],
            'stock' => ['required', 'integer', 'min:0'],
            'category_id' => ['required', 'exists:categories,id'],
        ];
    }
    
    public function messages(): array
    {
        return [
            'sku.unique' => 'Bu SKU kodu zaten kullanılıyor.',
            'price.min' => 'Fiyat negatif olamaz.',
        ];
    }
}

6. Rate Limiting (DDoS Koruması)

API'nizi DDoS'tan ve abuse'dan koruyun. routes/api.php içinde:

Route::middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    // 60 istek / dakika - varsayılan
});

// Özel rate limit
RateLimiter::for('api', function (Request $request) {
    return $request->user()
        ? Limit::perMinute(60)->by($request->user()->id)
        : Limit::perMinute(20)->by($request->ip());
});

// Login için sıkı rate limit (brute force koruması)
RateLimiter::for('login', function (Request $request) {
    return Limit::perMinute(5)->by($request->ip())
        ->response(function () {
            return response()->json(['error' => 'Çok fazla deneme'], 429);
        });
});

7. API Versiyonlama

API'nizi /api/v1/, /api/v2/ gibi versiyonlayın. Eski client'lar bozulmadan yeni özellikler ekleyebilirsiniz.

// routes/api.php
Route::prefix('v1')->group(function () {
    Route::apiResource('products', \App\Http\Controllers\Api\V1\ProductController::class);
});

Route::prefix('v2')->group(function () {
    Route::apiResource('products', \App\Http\Controllers\Api\V2\ProductController::class);
});

Alternatif: Header-based versioningAccept: application/vnd.api+json;version=2

8. Error Handling ve Standart Response Format

Tutarlı bir hata yapısı için custom exception handler:

// bootstrap/app.php (Laravel 11)
->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (NotFoundHttpException $e, Request $request) {
        if ($request->is('api/*')) {
            return response()->json([
                'message' => 'Kayıt bulunamadı',
                'code' => 'NOT_FOUND',
            ], 404);
        }
    });
    
    $exceptions->render(function (ValidationException $e, Request $request) {
        return response()->json([
            'message' => 'Validation failed',
            'errors' => $e->errors(),
            'code' => 'VALIDATION_ERROR',
        ], 422);
    });
})

9. API Dokümantasyonu

Scribe ile Otomatik Dokümantasyon

composer require --dev knuckleswtf/scribe
php artisan scribe:install
php artisan scribe:generate

Scribe controller'larınızdaki PHPDoc yorumlarını okuyup güzel HTML/Postman/OpenAPI dokümantasyonu üretir.

L5-Swagger Alternatifi

OpenAPI standardına uygun dokümantasyon için darkaonline/l5-swagger kullanılabilir. Daha standart, daha çok client kütüphanesiyle uyumlu.

10. Test Yazma (PHPUnit)

Feature Test Örnekleri

class ProductApiTest extends TestCase
{
    use RefreshDatabase;
    
    public function test_kullanici_urun_listeleyebilir(): void
    {
        Product::factory()->count(15)->create();
        $user = User::factory()->create();
        
        $response = $this->actingAs($user, 'sanctum')
            ->getJson('/api/v1/products');
        
        $response->assertOk()
            ->assertJsonStructure([
                'data' => ['*' => ['id', 'sku', 'name', 'price']],
                'meta' => ['current_page', 'total'],
            ]);
    }
    
    public function test_yetkisiz_kullanici_urun_olusturamaz(): void
    {
        $response = $this->postJson('/api/v1/products', [
            'sku' => 'TEST-001',
            'name' => 'Test Product',
            'price' => 100,
            'stock' => 10,
        ]);
        
        $response->assertUnauthorized();
    }
}

Test Coverage Hedefi

Profesyonel projelerde minimum % 80 test coverage hedeflenir. Kritik iş mantığı için % 100 hedeflenir.

11. Performans Optimizasyonu

N+1 Query Problemi

Eloquent'in en sık karşılaşılan tuzağı. Çözüm: eager loading.

// Kötü - N+1
$products = Product::all();
foreach ($products as $product) {
    echo $product->category->name; // Her ürün için ayrı query
}

// İyi - Eager loading
$products = Product::with('category')->get();

Caching Stratejisi

$products = Cache::remember('products.list', 3600, function () {
    return Product::active()->with('category')->get();
});

Database İndeksleme

Sıkça filtrelenen alanlara index ekleyin. EXPLAIN sorgu analiziyle yavaş query'leri tespit edin.

12. Production Deploy

Environment Yapılandırması

# .env.production
APP_ENV=production
APP_DEBUG=false
LOG_LEVEL=warning

# Cache hepsini production'da
php artisan config:cache
php artisan route:cache
php artisan view:cache

Queue Worker'lar

Mail, notification, heavy task'lar queue'ya alınmalı:

# Supervisor ile queue worker
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/api/artisan queue:work --queue=default --sleep=3 --tries=3
autostart=true
autorestart=true
numprocs=4

Nginx Konfigürasyonu

server {
    listen 443 ssl http2;
    server_name api.example.com;
    
    root /var/www/api/public;
    index index.php;
    
    ssl_certificate /etc/ssl/cert.pem;
    ssl_certificate_key /etc/ssl/key.pem;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Hosting Seçenekleri

  • Laravel Forge: DigitalOcean/AWS/Hetzner üzerinde tek tıkla deploy. Aylık 19$.
  • Laravel Vapor: AWS Lambda üzerinde serverless deploy. Yüksek ölçek için ideal.
  • Kendi VPS: Daha ucuz ama ekstra DevOps işi. Ubuntu + Nginx + PHP-FPM + MySQL/PostgreSQL.
  • Türkiye sunucu: Hosting.com.tr, Veriteknik gibi yerli sağlayıcılarla yasal uyumluluk avantajı.

13. Monitoring ve Logging

Production'da göz açık olun:

  • Sentry: Hata takibi, alert'leri
  • Laravel Telescope: Local debugging için
  • New Relic / Datadog: APM (Application Performance Monitoring)
  • ELK Stack: Log aggregation
  • Grafana + Prometheus: Metric görselleştirme

Sonuç: Laravel ile API Geliştirme Eğlencelidir

Laravel ile REST API geliştirmek hızlı, güvenli ve eğlenceli. Bu rehberdeki adımları takip ederek production-ready bir API geliştirebilirsiniz. Profesyonel API ihtiyacınız mı var? EMIXHAS Yazılım ile iletişime geçin. Özel yazılım hizmetlerimiz kapsamında Laravel REST API geliştirme, mevcut API'larınızın audit'i ve performans optimizasyonu yapıyoruz.

› Etiketler: Laravel REST API PHP Sanctum JWT Docker Production

› Bu yazı ilginizi çektiyse

Profesyonel yazılım, web tasarım, SEO veya dijital pazarlama ihtiyaçlarınız için ücretsiz keşif görüşmesi planlayalım.

İlgili Hizmet ve Şehir Cluster'larına Geçin

Bu rehberden hizmet detaylarına, sektörel sayfalara ve yerel niyetli şehir landing page'lerine geçerek ticari yolculuğu güçlendirin.

İlgili Yazılar

Backend kategorisinden ve EMIXHAS blog merkezinden seçilmiş 6 ilgili yazı:

Backend 14 dk · 08.02.2025

PHP 8.3 ile Gelen Yenilikler: 2026 Backend Geliştirici Rehberi

PHP 8.3'ün getirdiği readonly classes, json_validate, typed class constants, override attribute ve JIT performans iyileştirmeleri....

KOBİ Çözümleri 11 dk · 17.06.2026

Çiçekçi & Online Çiçek Siparişi Web Sitesi 2026: Aynı Gün Teslimat, Özel Gün Yoğunluğu ve Sipariş Yönetimi

Çiçekçiler için online sipariş ve web sitesi nasıl kurulur? Aynı gün ve zaman aralıklı teslimat, Sevgililer/Anneler Günü kapasite ...

KOBİ Çözümleri 11 dk · 17.06.2026

Kuyumcu & Mücevher Mağaza Yazılımı 2026: Gram/Has Bazlı Stok, Güncel Altın Fiyatı ve Hurda Alımı

Kuyumcu ve mücevher mağazaları için yazılım nasıl seçilir? Gram/ayar/has bazlı stok, güncel altın/döviz fiyatına göre satış, hurda...

KOBİ Çözümleri 11 dk · 17.06.2026

Düğün Salonu & Organizasyon Rezervasyon Yazılımı 2026: Takvim, Kapora ve Online Tarih Sorgulama

Düğün salonu, kır düğünü ve organizasyon işletmeleri için rezervasyon yazılımı nasıl seçilir? Çift rezervasyonu önleyen takvim, ka...

KOBİ Çözümleri 12 dk · 17.06.2026

Kargo, Nakliye & Lojistik Takip Yazılımı 2026: Gönderi Takibi, Teslim Kanıtı ve Filo Yönetimi

Nakliye, kurye ve dağıtım firmaları için lojistik takip yazılımı nasıl seçilir? Gönderi/sevkiyat takibi, müşteri takip linki, tesl...

KOBİ Çözümleri 11 dk · 17.06.2026

Optik & Gözlükçü Otomasyon Yazılımı 2026: Müşteri/Reçete Kaydı, Stok ve Yenileme Hatırlatması

Optik mağazası ve gözlükçü için yazılım nasıl seçilir? SGK/optik provizyon gibi regüle tarafla mağaza yazılımının farkını, müşteri...

Tüm Blog Yazılarını Gör →

🎁ÜCRETSİZ DEMO HAZIRLATINSitenizi görün, beğenirseniz ödeyin