dandoetech/laravel-generic-api
Composer 安装命令:
composer require dandoetech/laravel-generic-api
包简介
Registry-driven CRUD proxy for Laravel. Validation, policies, filtering, and consistent JSON responses.
README 文档
README
Pre-release — Architecture by senior tech lead, implementation largely AI-assisted with human review. Not fully reviewed. Architecture may change before v1.0.0.
Registry-driven CRUD controller for Laravel. One controller handles all resources — validation, authorization, filtering, sorting, pagination, and computed fields are derived from the Resource Registry.
Installation
composer require dandoetech/laravel-generic-api
The service provider is auto-discovered. Publish the config:
php artisan vendor:publish --tag=ddt-api-config
Requires dandoetech/laravel-resource-registry.
Quick Start
Define a resource with HasEloquentModel (and optionally HasPolicy):
class ProductResource extends Resource implements HasEloquentModel, HasPolicy { public function model(): string { return \App\Models\Product::class; } public function policy(): string { return \App\Policies\ProductPolicy::class; } protected function define(ResourceBuilder $b): void { $b->key('product') ->label('Product') ->timestamps() ->field('name', FieldType::String, nullable: false, rules: ['required', 'max:120']) ->field('price', FieldType::Float, nullable: false, rules: ['required', 'numeric', 'min:0']) ->field('category_id', FieldType::Integer, nullable: false) ->belongsTo('category', foreignKey: 'category_id') ->computed('category_name', FieldType::String, via: 'category.name') ->computed('orders_count', FieldType::Integer, via: 'count:orders') ->filterable(['name', 'price', 'category_id', 'category_name']) ->sortable(['name', 'price', 'created_at', 'orders_count']) ->action('create') ->action('update') ->action('delete'); } }
Routes are registered automatically. The API is ready:
GET /api/v1/product → list (paginated)
GET /api/v1/product?filter[name]=Phone → filter
GET /api/v1/product?sort=-price,name → sort (- = desc)
GET /api/v1/product?page=2&perPage=50 → paginate
GET /api/v1/product/123 → show
POST /api/v1/product → create
PATCH /api/v1/product/123 → update
DELETE /api/v1/product/123 → delete
POST /api/v1/product/actions/bulk-delete → mass action
Routes
All routes are prefixed with config('ddt_api.prefix') (default: api/v1) and use the api middleware plus AuthorizeResource.
| Method | Route | Action |
|---|---|---|
| GET | {resource} |
List with pagination, filtering, sorting |
| POST | {resource} |
Create |
| GET | {resource}/{id} |
Show |
| PATCH | {resource}/{id} |
Update (partial) |
| DELETE | {resource}/{id} |
Delete |
| POST | {resource}/actions/{action} |
Execute mass action |
Responses
List:
{
"data": [
{ "id": 1, "name": "Phone", "price": 599.99, "category_name": "Electronics" }
],
"meta": { "page": 1, "perPage": 25, "total": 42, "lastPage": 2 }
}
Single item:
{
"data": { "id": 1, "name": "Phone", "price": 599.99, "category_name": "Electronics" }
}
Query Syntax
Only fields listed in filterable() and sortable() on the resource are accepted. Unknown fields return a 422 Unprocessable Entity. This includes computed fields — filtering and sorting on category_name or orders_count works out of the box.
Filtering
?filter[name]=Widget String fields: auto LIKE match
?filter[category_id]=3 Non-string fields: exact match
?filter[price][gte]=10&filter[price][lte]=100 Operator syntax
?filter[price][between]=10,100 Between shorthand (comma-separated)
Operators: eq, neq, gt, gte, lt, lte, like, between
Sorting
?sort=name Ascending
?sort=-price Descending (prefix with -)
?sort=-created_at,name Multiple fields (comma-separated)
Search
?search=widget OR LIKE across all searchable() fields
Search applies LIKE %term% for string fields and exact match for non-string fields.
Pagination
?page=2&perPage=50 Default: 25, max: 200 (configurable)
Query Profiles
Override filterable/sortable/searchable per context. Profiles can be defined on the Resource class:
$b->queryProfile('admin', filterable: ['name', 'price', 'category_id', 'created_at'], sortable: ['name', 'price', 'created_at', 'orders_count'], ); // With preFilter — automatically applied WHERE conditions: $b->queryProfile('active', filterable: ['name', 'price'], preFilter: ['status' => 'active'], );
Activate with ?profile=admin or ?profile=active.
Authorization
The AuthorizeResource middleware handles authorization automatically for resources that implement HasPolicy:
| Request | Gate ability | Subject |
|---|---|---|
| GET (list) | viewAny |
Model class |
| GET (single) | view |
Model instance |
| POST | create |
Model class |
| PATCH | update |
Model instance |
| DELETE | delete |
Model instance |
| Mass action | action |
Model class + action name |
Resources without HasPolicy skip authorization entirely.
Validation
Validation rules are derived from the resource definition:
- POST (create): Field rules applied directly. Non-nullable fields without explicit rules get
required. - PATCH (update): All rules wrapped with
sometimes(PATCH semantics — only validate provided fields).
Configuration
config/ddt_api.php:
return [ // Route prefix for all endpoints 'prefix' => env('GENERIC_API_PREFIX', 'api/v1'), // Pagination defaults 'pagination' => [ 'per_page' => 25, 'max_per_page' => 200, ], // Named query profiles per resource 'query_profiles' => [ // 'product' => [ // 'admin' => ['filterable' => [...], 'sortable' => [...]], // ], ], // Mass action handlers 'actions' => [ // 'product' => [ // 'bulk-delete' => App\Actions\ProductBulkDelete::class, // ], ], ];
Testing
composer install composer test # PHPUnit (Orchestra Testbench) composer qa # cs:check + phpstan + test
License
MIT
dandoetech/laravel-generic-api 适用场景与选型建议
dandoetech/laravel-generic-api 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 2, 最近一次更新时间为 2026 年 03 月 15 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「php」 「rest」 「api」 「crud」 「laravel」 「generic-controller」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 dandoetech/laravel-generic-api 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 dandoetech/laravel-generic-api 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 dandoetech/laravel-generic-api 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A PSR-7 compatible library for making CRUD API endpoints
Api bundle
Alfabank REST API integration
A Flickr wrapper to allow you to call the Flickr api with Guzzle as the backend.Goal is to have 100% Flickr api coverage rather than just upload/display photos (currently at 23%).
BlockCypher's PHP SDK for REST API
Helper classes for creating cookie headers
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 2
- 点击次数: 34
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-03-15