Tüm Laravel geliştiricileri bu düzene aşinadır: bir model oluştur, bir controller yaz, route tanımla, validasyon ekle, filtreleme, paginasyon, sıralama implement et… her bir varlık için bunu tekrar et.
Daha iyi bir yol olduğunu söylesem?
Ben Laravel Query Gate üzerinde çalışıyorum. Bu paket API’leri nasıl oluşturduğunuzu dönüştürüyor. Tekrar eden boilerplate kod yazmak yerine, istediğinizi tanımlıyorsunuz — ve Query Gate geri kalanını hallediyor.
Size Gönderi, Yorum, Kategori, Etiket, Kimlik Doğrulama, Özel Eylemler ve API Sürümleme içeren tam bir blog API’si oluşturmak için nasıl bir yol izlediğimi göstereceğim — tek bir controller yazmadan.
Hepimizin Karşılaştığı Sorun
Hepimizin Karşılaştığı Sorun
Tipik bir Laravel API kurulumu şöyle görünür:
// PostController.php - Yazacağınız birçok controller'dan sadece BİRİ
class PostController extends Controller
{
public function index(Request $request)
{
$query = Post::query();
if ($request->has('status')) {
$query->where('status', $request->status);
}
if ($request->has('category_id')) {
$query->where('category_id', $request->category_id);
}
if ($request->has('author')) {
$query->whereHas('author', fn($q) => $q->where('name', 'like', "%{$request->author}%"));
}
// ... 20 daha fazla filtre
if ($request->has('sort')) {
// ayrıştırma mantığı...
}
return $query->paginate($request->per_page ?? 15);
}
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'content' => 'required|string',
// ... daha fazla kural
]);
return Post::create($validated);
}
// update(), destroy(), show()... fikri anladınız
}
Şimdi bunu uygulamanızdaki her model için çarpın. Bu çok yorucu.
Query Gate Yöntemi
Query Gate Yöntemi
Aynı işlevselliği Laravel Query Gate ile şöyle yapabilirsiniz:
// app/Models/Post.php
class Post extends Model
{
use HasQueryGate;
public static function queryGate(): QueryGate
{
return QueryGate::make()
->alias('posts')
->middleware(['auth:sanctum'])
->filters([
'status' => ['string', 'in:draft,published,archived'],
'category_id' => 'integer',
'author.name' => ['string', 'max:100'],
'created_at' => 'date',
])
->allowedFilters([
'status' => ['eq', 'in', 'neq'],
'category_id' => ['eq', 'in'],
'author.name' => ['like'],
'created_at' => ['gte', 'lte', 'between'],
])
->select(['id', 'title', 'slug', 'status', 'created_at', 'author.name'])
->sorts(['created_at', 'title'])
->actions(fn ($actions) => $actions
->create(fn ($action) => $action
->validations([
'title' => ['required', 'string', 'max:255'],
'content' => ['required', 'string'],
])
)
->update()
->delete()
);
}
}
Hepsi bu kadar. Hiçbir controller yok. Hiçbir route yok. Tekrar eden kod yok.
Query Gate size otomatik olarak şu işlevleri sunar:
GET /query/posts → Filtrelerle, sıralama, paginasyon ile listele
GET /query/posts/{id} → Tekil gönderiyi göster
POST /query/posts → Gönderi oluştur
PATCH /query/posts/{id} → Gönderiyi güncelle
DELETE /query/posts/{id} → Gönderiyi sil
Gerçek Dünya Örneği: Tam Bir Blog API’si
Gerçek Dünya Örneği: Tam Bir Blog API’si
Query Gate’in neler yapabileceğini göstermek için tam bir örnek proje oluşturdum. İşte içindekiler:
1. Gelişmiş Filtreleme
1. Gelişmiş Filtreleme
Herhangi bir alanla filtreleyin ve eq, neq, like, in, between, gt, gte, lt, lte gibi operatörler kullanın:
# 2024'te yayımlanan gönderiler
GET /query/posts?filter[published_at][between]=2024-01-01,2024-12-31
# Belirli etiketlere sahip gönderiler
GET /query/posts?filter[tag_slugs][in]=laravel,php
# 1000+ görüntülenmeye sahip, popülerlik sırasına göre sıralı gönderiler
GET /query/posts?filter[views_count][gte]=1000&sort=views_count:desc
2. İlişki Filtreleme
2. İlişki Filtreleme
Nokta notasyonu kullanarak ilişkileri sorgulama:
# Yazar adına göre gönderiler
GET /query/posts?filter[author.name][like]=John
# Yayımlanan gönderiler üzerindeki yorumlar
GET /query/comments?filter[post.status][eq]=published
3. Özel Eylemler
3. Özel Eylemler
CRUD’dan fazlasına mı ihtiyacınız var? Özel eylemler tanımlayın:
// app/Actions/QueryGate/Posts/PublishPost.php
class PublishPost extends AbstractQueryGateAction
{
public function action(): string
{
return 'publish';
}
public function handle($request, $model, array $payload)
{
$model->update([
'status' => 'published',
'published_at' => now(),
]);
return ['message' => 'Gönderi yayımlandı!', 'post' => $model];
}
public function authorize($request, $model): ?bool
{
return $request->user()->can('update', $model);
}
}
Artık şunlara sahipsiniz:
POST /query/posts/1/publish
Ö example’da şunlar için eylemler var: Yayımla, Yayından Kaldır, Arşivle, Öne Çıkar, Öne Çıkarmayı Kaldır, Gönderileri Kopyala ve Onayla, Reddet, Spam Olarak İşaretle yorumlar.
4. API Sürümleme (Evet, Yerleşik!)
4. API Sürümleme (Evet, Yerleşik!)
Mevcut istemcileri bozmadan API’nizi geliştirin:
QueryGate::make()
->version('2024-01-01', function (QueryGate $gate) {
$gate->filters([=> , => ])
->select([, , ]);
})
->version(, function (QueryGate $gate) {
$gate->filters([
=> ,
=> ,
=> , // 2025'te yenidir!
, // 2025'te yenidir!
])
->select([, , , ,
});
İstemciler sürümlerini seçebilir:
GET /query/posts -H "X-Query-Version: 2024-01-01"
Ve bir değişiklik günlüğü uç noktası da var:
GET /query/posts/__changelog
5. Otomatik OpenAPI Dokümantasyonu
5. Otomatik OpenAPI Dokümantasyonu
Query Gate, OpenAPI/Swagger dokümanlarını otomatik olarak oluşturur:
GET /query/docs → Etkileşimli dokümantasyon arayüzü
GET /query/docs.json → OpenAPI JSON spesifikasyonu
Manuel bir dokümantasyon yok. Her zaman kodunuzla senkronizedir.
Hızlı Başlangıç
Hızlı Başlangıç
Denemek mi istiyorsunuz? İşte nasıl başlayacağınız:
Paketi Yükleyin
Paketi Yükleyin
composer require behindsolution/laravel-query-gate
Modelinize Trait Ekleyin
Modelinize Trait Ekleyin
use BehindSolution\LaravelQueryGate\Traits\HasQueryGate;
use BehindSolution\LaravelQueryGate\Support\QueryGate;
class Post extends Model
{
use HasQueryGate;
public static function queryGate(): QueryGate
{
return QueryGate::make()
->alias()
->filters([=> , => ])
->allowedFilters([=> [], => []])
->actions(fn ($a) => $a->create()->update()->delete());
}
}
Konfigüre Kaydedin
Konfigüre Kaydedin
// config/query-gate.php
=> [
App\Models\Post::class,
],
Tamam. Artık tamamen işlevsel bir REST API’niz var.
Örnek Projeyi Deneyin
Örnek Projeyi Deneyin
Her şeyin çalıştığını görmek için tam örneği klonlayın:
git clone [email protected]:behindSolution/LQG-example.git
cd LQG-example
composer install
cp .env.example .env
php artisan key:generate
php artisan migrate --seed
php artisan serve
Dahil edilen Postman koleksiyonunu içe aktarın ve keşfetmeye başlayın.
Bunu Neden Yaptım
Bunu Neden Yaptım
Her proje için aynı kodu tekrar tekrar yazmaktan yoruldum. Her proje şunları gerektiriyordu:
- Filtreleme mantığı
- Sıralama mantığı
- Paginasyon
- Validasyon
- Yetkilendirme kontrolleri
- API sürümleme (şansınız varsa)
- Dokümantasyon (zaman varsa)
Query Gate, tüm bunları açıklayıcı bir şekilde yönetiyor. Siz iş mantığınıza odaklanıyorsunuz, boilerplate’a değil.
Sonra Ne Olacak?
Sonra Ne Olacak?
Herhangi bir sorunuz veya geri bildiriminiz mi var? Aşağıya bir yorum bırakın ya da GitHub’da bir sorun açın. Projelerinizde Query Gate’i nasıl kullandığınızı duymak isterim!
Eğer bu size zaman kazandırdıysa, repo’ya bir yıldız vermeyi düşünün. Bu, daha fazla geliştiricinin projeyi keşfetmesine yardımcı olur.
Kaynak: Orijinal Makale


