behindsolution / laravel-query-gate
Generic HTTP gateway for Laravel Eloquent queries.
Package info
github.com/behindSolution/laravel-query-gate
pkg:composer/behindsolution/laravel-query-gate
Requires
- php: ^8.2
- illuminate/database: ^10.0|^11.0|^12.0
- illuminate/http: ^10.0|^11.0|^12.0
- illuminate/pagination: ^10.0|^11.0|^12.0
- illuminate/pipeline: ^10.0|^11.0|^12.0
- illuminate/routing: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.5|^11.0
- dev-main
- v1.7.0
- v1.6.3
- v1.6.2
- v1.6.1
- v1.6.0
- v1.5.6
- v1.5.5
- v1.5.4
- v1.5.3
- v1.5.2
- v1.5.1
- v1.5.0
- v1.4.0
- v1.3.9
- v1.3.7
- v1.3.6
- v1.3.5
- v1.3.4
- v1.3.0
- v1.2.0
- v1.1.15
- v1.1.14
- v1.1.13
- v1.1.11
- v1.1.10
- v1.1.9
- v1.1.8
- v1.1.7
- v1.1.6
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.7
- v1.0.6
- v1.0.5
- v1.0.4
- dev-feature/lockable
- dev-feature/types
- dev-feature/detail
This package is auto-updated.
Last update: 2026-03-24 18:18:31 UTC
README
A declarative API layer for Laravel that turns Eloquent models into fully featured REST endpoints — with filtering, sorting, actions, versioning, OpenAPI docs, and a type-safe TypeScript SDK.
Features
- Declarative API definition — define filters, sorts, selects, and actions directly on your model
- CRUD actions — built-in create, update, delete, and detail with validation, policies, and custom handlers
- Custom actions — extend your API with reusable action classes
- API versioning — version your endpoints with automatic changelog generation
- OpenAPI documentation — auto-generated spec and UI out of the box
- TypeScript code generation — generate type-safe contracts with
php artisan qg:types - Frontend SDK — fully typed, framework-agnostic query builder for the frontend
- Caching & pagination — cursor and offset pagination, built-in cache support
Requirements
- PHP 8.2+
- Laravel 10, 11, or 12
Installation
composer require behindsolution/laravel-query-gate
Publish the config file:
php artisan vendor:publish --tag=query-gate-config
Quick Start
Add the trait to your model and define the query gate:
use BehindSolution\LaravelQueryGate\Traits\HasQueryGate; use BehindSolution\LaravelQueryGate\Support\QueryGate; class User extends Model { use HasQueryGate; public static function queryGate(): QueryGate { return QueryGate::make() ->alias('users') ->select(['id', 'name', 'email', 'created_at']) ->filters(['name' => 'string', 'email' => 'email']) ->allowedFilters(['name' => ['like', 'eq'], 'email' => ['eq']]) ->sorts(['name', 'created_at']); } }
Your API is ready:
GET /query/users?filter[name][like]=John&sort=-created_at
GET /query/users/1
Actions
Define mutations with a fluent builder:
QueryGate::make() ->alias('posts') ->actions(fn ($actions) => $actions ->create(fn ($action) => $action ->validations(['title' => 'required|string', 'body' => 'required|string']) ->policy('create') ) ->update(fn ($action) => $action ->validations(['title' => 'string', 'body' => 'string']) ->policy('update') ) ->delete(fn ($action) => $action->policy('delete')) ->detail() );
Custom actions:
->actions(fn ($actions) => $actions ->use(PublishPostAction::class) )
API Versioning
QueryGate::make() ->alias('users') ->version('2024-01-01', fn ($gate) => $gate ->select(['id', 'name', 'email']) ->filters(['name' => 'string']) ) ->version('2024-06-01', fn ($gate) => $gate ->select(['id', 'name', 'email', 'avatar']) ->filters(['name' => 'string', 'email' => 'email']) );
Clients select a version via the X-Query-Version header or ?version= query parameter. A changelog is auto-generated at GET /query/users/__changelog.
TypeScript Code Generation
Generate type-safe contracts from your API definitions:
php artisan qg:types --output=resources/ts/contracts
Output example:
export interface UserEntity { id: number; name: string; email: string; } export interface UserCreatePayload { name: string; email: string; } export interface UserResourceContract { get: UserEntity; create: { payload: UserCreatePayload; response: UserEntity }; // ... }
Frontend SDK
Install the companion SDK:
npm install laravel-query-gate-sdk
import { configureQueryGate, queryGate } from 'laravel-query-gate-sdk' configureQueryGate({ baseUrl: 'https://api.example.com/query' }) // List with filters and sorting const users = await queryGate<UserResourceContract>('users') .filter('name', 'like', 'John') .sort('created_at', 'desc') .get() // Create await queryGate<UserResourceContract>('users') .post({ name: 'Jane', email: 'jane@example.com' }) // Update await queryGate<UserResourceContract>('users').id(1) .patch({ name: 'Jane Doe' }) // Custom action await queryGate<PostResourceContract>('posts').id(1) .action('publish').post()
OpenAPI Documentation
Enable in config/query-gate.php:
'openAPI' => [ 'enabled' => true, ],
Access the generated docs at GET /query/docs (UI) or GET /query/docs.json (spec).
Ecosystem
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for details.
License
MIT