› 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....

Yapay Zekâ 11 dk · 02.07.2026

Web Sitenize Yapay Zekâ Eklemek 2026: Sohbet Botundan Kişiselleştirmeye Pratik Yol Haritası

Web sitenize yapay zekâ nasıl eklenir? 2026 itibarıyla gerçekçi seçenekler: yapay zekâ sohbet botu, akıllı arama, ürün önerisi, iç...

Yapay Zekâ 12 dk · 06.07.2026

Google AI Overviews ve AI Mode: Trafiğiniz Neden Düşüyor, 2026'da Nasıl Korunursunuz?

Google'ın yapay zekâ özetleri (AI Overviews) tıklama oranlarını ortalama % 34,5 düşürdü; aramaların % 58'i artık tıklamasız bitiyo...

Yapay Zekâ 11 dk · 09.07.2026

GEO (Generative Engine Optimization) Nedir? ChatGPT, Gemini ve Claude'da Kaynak Gösterilme Rehberi 2026

GEO nedir, SEO'dan farkı ne? ChatGPT haftada 900 milyon kullanıcıya ulaşırken markanızın yapay zekâ cevaplarında anılması yeni gör...

Yapay Zekâ 9 dk · 13.07.2026

llms.txt Nedir, Gerçekten İşe Yarar mı? 2026 Verileriyle Dürüst Bir Değerlendirme

llms.txt dosyası siteler için yeni robots.txt mi, yoksa abartılmış bir trend mi? Google'ın Mayıs 2026 rehberi "kendi yapay zekâ öz...

Yapay Zekâ 12 dk · 16.07.2026

Agentic Commerce: Yapay Zekâ Ajanları Alışverişi Devraldığında E-Ticaret Siteniz Hazır mı? (2026)

Yapay zekâ ajanları artık ürün arıyor, karşılaştırıyor ve satın alıyor. Shopify'da yapay zekâ kaynaklı siparişler yıllık ~13 kat a...

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

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