Kimi Laravel API eğitimleri Route::get('/users', ...) ile sona eriyor. Ancak bir API’yi üretime sunmak tamamen farklı bir süreçtir. Güçlü bir kimlik doğrulama mekanizmasına, istismar karşısında koruma sağlayan önlemlere ve her iterasyonda müşterilerinizi kötü etkilemeyecek bir versiyonlama stratejisine ihtiyacınız var. Bu kılavuz, bunların her birine gerçek kod örnekleriyle detaylı bir şekilde göz atıyor.
Laravel Sanctum ile Kimlik Doğrulama
Laravel Sanctum ile Kimlik Doğrulama
Pek çok API için — özellikle SPA’lar ve mobil uygulamalar — Laravel Sanctum en uygun araçtır. Passport’tan daha hafif ve gerçek dünya kullanım senaryolarının %90’ını kapsar.
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
Modelinize HasApiTokens trait’ini ekleyin:
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
}
Girişte Token Dağıtma
Girişte Token Dağıtma
// app/Http/Controllers/Api/AuthController.php
public function login(Request $request): JsonResponse
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
return response()->json(['message' => 'Geçersiz kimlik bilgileri'], 401);
}
// Gerekirse, bu cihaz için eski tokenları iptal edin
$user->tokens()->where('name', $request->device_name)->delete();
$token = $user->createToken($request->device_name, ['*'], now()->addDays(30));
return response()->json([
'token' => $token->plainTextToken,
'expires_at' => $token->accessToken->expires_at,
]);
}
Tokenın süresine dikkat edin — üretim ortamında sonsuz süreli token çıkarmayın. Ayrıca yeni bir token dağıtmadan önce bu cihazın var olan tokenlarını sildiğimize de dikkat edin. Bu, token birikimini önler.
Route’ları Koruma
Route’ları Koruma
// routes/api.php
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', [UserController::class, 'show']);
Route::post('/logout', [AuthController::class, 'logout']);
});
Token yetkilerini (scopes) denetlemek için controllerlarda kontrol edebilirsiniz:
if ($request->user()->tokenCan('orders:write')) {
// ...
}
Rate Limiting
Rate Limiting
Rate limiting olmadan, API’niz bir kötü niyetli bot yüzünden zor bir gün geçirebilir. Laravel’in RateLimiter facadesi size kesin kontrol sağlar.
Özel Limitörler Tanımlama
Özel Limitörler Tanımlama
App\Providers\RouteServiceProvider içinde (veya Laravel 11+ için ayrı bir AppServiceProvider içinde), limitörlerinizi boot metodunda tanımlayın:
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
public function boot(): void
{
// Genel endpointler — IP ile sınırlama
RateLimiter::for('public-api', function (Request $request) {
return Limit::perMinute(30)->by($request->ip());
});
// Kimlik doğrulanmış endpointler — kullanıcı ile sınırlama
RateLimiter::for('authenticated-api', function (Request $request) {
return $request->user()
? Limit::perMinute(120)->by($request->user()->id)
: Limit::perMinute(20)->by($request->ip());
});
// Yüksek maliyetli işlemler (örneğin, AI endpointleri)
RateLimiter::for('heavy-operations', function (Request $request) {
return [
Limit::perMinute(10)->by($request->user()?->id ?? $request->ip()),
Limit::perDay(500)->by($request->user()?->id ?? $request->ip()),
];
});
}
Bu limitörleri route’lara uygulayın:
Route::middleware(['auth:sanctum', 'throttle:authenticated-api'])->group(function () {
Route::get(, [ProductController::class, ]);
});
Route::middleware([, ])->group(function () {
Route::post(, [AiController::class, ]);
});
Kullanışlı Rate Limit Başlıkları Döndürme
Kullanışlı Rate Limit Başlıkları Döndürme
Laravel otomatik olarak X-RateLimit-Limit ve X-RateLimit-Remaining başlıklarını ekler. Limit aşıldığında 429 Too Many Requests ile birlikte Retry-After başlığı döner. API istemcilerinizin bunu düzgün bir şekilde ele aldığından emin olun.
Geri kalan limitleri proaktif bir şekilde açığa çıkarmak isterseniz, bunları bir middleware veya global yanıt makrosu ile manuel olarak ekleyebilirsiniz — ancak çoğu API için varsayılan ayarlar yeterlidir.
API Versiyonlama
API Versiyonlama
İşte burada ekipler sonsuza kadar tartışır. URI versiyonlama (/api/v1/) ile başlık versiyonlama (Accept: application/vnd.api+json;version=1) arasında. Çoğu takım için URI versiyonlama, pratikte kazanır — görünürdür, önbelleğe alınabilir ve bir tarayıcıda test etmek kolaydır.
Route Yapısı
Route Yapısı
routes/
api/
v1.php
v2.php
app/Http/Controllers/
Api/
V1/
UserController.php
ProductController.php
V2/
UserController.php
routes/api.php içinde:
Route::prefix()->name()->group(base_path());
Route::prefix()->name()->group(base_path());
Versiyonlar Arasında Mantık Paylaşma
Versiyonlar Arasında Mantık Paylaşma
İş mantığınızı kopyalamayın. Bunu servislerde veya aksiyonlarda toplayın ve versiyonlanmış controllerlardan aynı katmanı çağırın:
// app/Actions/GetUserProfileAction.php
class GetUserProfileAction
{
public function execute(User $user): array
{
return [
=> $user->id,
=> $user->name,
=> $user->email,
];
}
}
V1 ve V2 controllerları her ikisi de GetUserProfileAction kullanan mekanizmayı içe aktarır ve kullanır. V2 controllerı çıktıyı farklı şekillerde dönüştürebilir, ancak temel sorgu ve iş kuralları tek bir yerde yer alır.
Versiyonlu API Kaynakları
Versiyonlu API Kaynakları
Laravel’in API Kaynakları burada idealdir:
// app/Http/Resources/V1/UserResource.php
class UserResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
=> $this->id,
=> $this->name,
];
}
}
// app/Http/Resources/V2/UserResource.php
class UserResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
=> $this->id,
=> $this->name, // v2'de yeniden adlandırılmış alan
=> $this->avatar_url,
];
}
}
Bu, dönüşümlerinizi her versiyona özgü ve temiz bir şekilde izole eder.
Tutarlı Hata Yanıtları
Tutarlı Hata Yanıtları
API tüketicilerini en çok hayal kırıklığına uğratan şey tutarsız hata yapılarıdır. Laravel’in istisna işleyicisini kullanarak standart hale getirin:
// app/Exceptions/Handler.php (ya da L11'de bootstrap/app.php)
$exceptions->render(function (\Illuminate\Validation\ValidationException $e, Request $request) {
if ($request->expectsJson()) return response()->json([
,
=> $e->errors(),
], 422);
}
});
$exceptions->render(function (\Illuminate\Auth\AuthenticationException $e, Request $request) {
if ($request->expectsJson()) {
return response()->json([ ], 401);
}
});
Her hata, her seferde, aynı JSON yapısını döner. Müşteriler buna güvenebilir.
Gerçek Dünya API Projeleri Üzerine Bir Not
Gerçek Dünya API Projeleri Üzerine Bir Not
Yukarıda belirtilen desenler teorik değil — doğrudan üretim projelerinden alınmıştır. Bölgedeki müşteriler için API’ler oluştururken (birçok kiracılı SaaS ve e-ticaret platformları gibi), kimlik doğrulama için Sanctum, özel rate limiter’lar ve temiz URI versiyonlama kombinasyonları her zaman güvenilir ve sürdürülebilir olduğu kanıtlanmıştır. Bu desenlerin daha büyük Laravel mimarisi kararlarına nasıl uyduğunu merak ediyorsanız, web sitesini ziyaret edebilirsiniz ve bu yapıları HanzWeb’de nasıl ele aldığımızı görebilirsiniz.
Sonuç
Sonuç
Gerçekten üretim için hazır bir Laravel API’si oluşturmak, mutlu patikanın ötesini düşünmeyi gerektirir. Sanctum, OAuth’a ihtiyaç duyulmadığında kimlik doğrulamayı temiz bir şekilde yönetir. Özel rate limitörleri, farklı endpoint’leri farklı şekilde korumanızı sağlar — tek tip bir global throttle nadiren doğru cevaptır. URI versiyonlama, paylaşılan aksiyon sınıfları ve versiyonlu API Kaynakları ile desteklendiğinde, mevcut istemcileri kırmadan net bir yükseltme yolunu sağlar.
Kimlik doğrulama, rate limiting ve versiyonlama — bunlar opsiyonel eklemeler değil, zorunluluklardır. Bunları başarıyla uyguladıysanız, üzerinde her şeyin inşa edileceği sağlam bir temel oluşturduğunuz anlamına gelir.
Kaynak: Orijinal Makale


