wappo/laravel-schema-api
最新稳定版本:v1.0.0
Composer 安装命令:
composer require wappo/laravel-schema-api
包简介
This is a package that automatically exposes the DB schema in an api
README 文档
README
Automatically expose your Laravel Eloquent models through a RESTful HTTP API with zero configuration. Perfect for building mobile apps, SPAs, or syncing data between systems.
What Does This Package Do?
Laravel Schema API automatically creates API endpoints for all your Eloquent models, giving you:
- Instant REST API: GET, PUT, DELETE operations on all your models without writing controllers
- Real-Time Broadcasting: WebSocket notifications when data changes (via Laravel Echo)
- Streaming JSON Responses: Memory-efficient NDJSON streaming for large datasets
- Incremental Sync: Built-in
?sinceparameter to fetch only changed/deleted records - Automatic Relationships: Stream related models with the
#[ApiInclude]attribute - Cascade Deletes: Automatically delete/restore related models when parents change
- Schema-Based Validation: Auto-generates validation rules from your database schema
- Type-Safe Client Generation: Generate TypeScript types and Vue forms from your models
Installation
Install the package via composer:
composer require wappo/laravel-schema-api
Publish the config file (optional):
php artisan vendor:publish --tag="schema-api-config"
That's it! Your models are now accessible via /schema-api/{table-name}.
Quick Start
Once installed, you can immediately access your models:
# List all posts GET /schema-api/posts # Get a specific post GET /schema-api/posts/123 # Create, update, or delete records PUT /schema-api/sync
Example: Fetching Data
curl https://your-app.com/schema-api/posts
Response (NDJSON format - one JSON object per line):
{"id":"abc-123","type":"posts","attr":{"title":"Hello World","content":"..."}}
{"id":"def-456","type":"posts","attr":{"title":"Another Post","content":"..."}}
Example: Incremental Sync
Fetch only records modified since a specific timestamp:
# Get posts updated since 2025-01-01 GET /schema-api/posts?since=2025-01-01T00:00:00Z
This returns both updated records and deleted IDs (if using soft deletes).
Example: Creating/Updating Records
curl -X PUT https://your-app.com/schema-api/sync \ -H "Content-Type: application/json" \ -d '[ { "op": "create", "type": "posts", "id": "new-uuid", "attr": { "title": "New Post", "content": "Hello!" } }, { "op": "update", "type": "posts", "id": "existing-uuid", "attr": { "title": "Updated Title" } }, { "op": "delete", "type": "posts", "id": "old-uuid" } ]'
Advanced Usage
Including Relationships
Stream related models alongside parent records using the #[ApiInclude] attribute:
use Wappo\LaravelSchemaApi\Attributes\ApiInclude; class Order extends Model { #[ApiInclude] public function rows(): HasMany { return $this->hasMany(OrderRow::class); } #[ApiInclude] public function owner(): BelongsTo { return $this->belongsTo(User::class); } }
Now when you fetch orders, you'll also get the rows and owner streamed as separate root-level entities:
GET /schema-api/orders/123
Response:
{"id":"123","type":"orders","attr":{"number":1001}}
{"id":"row-1","type":"order_rows","attr":{"specification":"Item 1"}}
{"id":"row-2","type":"order_rows","attr":{"specification":"Item 2"}}
{"id":"user-1","type":"users","attr":{"name":"John Doe"}}
Cascade Delete & Restore
Automatically delete or restore related models when the parent changes:
use Wappo\LaravelSchemaApi\Attributes\ApiInclude; use Wappo\LaravelSchemaApi\Concerns\HasApiIncludeCascadeDelete; class Order extends Model { use HasApiIncludeCascadeDelete, SoftDeletes; // Related rows will be automatically deleted when order is deleted #[ApiInclude(cascadeDelete: true)] public function rows(): HasMany { return $this->hasMany(OrderRow::class); } // For models without SoftDeletes, you must explicitly allow hard deletion #[ApiInclude(cascadeDelete: true, forceDelete: true)] public function metadata(): HasOne { return $this->hasOne(OrderMetadata::class); } }
Safety Features:
- Models with
SoftDeletesare always safe to cascade delete - Models without
SoftDeletesrequireforceDelete: trueto prevent accidental data loss - When restoring a soft-deleted parent, only related records deleted at approximately the same time are restored (configurable tolerance)
Validation
Validation rules are automatically generated from your database schema:
// varchar(255) → string|max:255 // integer → integer // datetime → date // etc.
Or provide custom validation rules:
use Wappo\LaravelSchemaApi\Attributes\UseValidationRulesProvider; use Wappo\LaravelSchemaApi\Contracts\ValidationRulesProviderInterface; #[UseValidationRulesProvider(PostValidationRules::class)] class Post extends Model { // ... } class PostValidationRules implements ValidationRulesProviderInterface { public function getRules(): array { return [ 'title' => 'required|string|max:255', 'slug' => 'required|string|unique:posts', 'content' => 'required|string', ]; } }
Query Modifiers
Customize how models are queried using attributes:
use Wappo\LaravelSchemaApi\Attributes\ApplyQueryModifier; use Wappo\LaravelSchemaApi\QueryModifiers\LatestFirstModifier; use Wappo\LaravelSchemaApi\QueryModifiers\FilterQueryModifier; #[ApplyQueryModifier(LatestFirstModifier::class)] #[ApplyQueryModifier(FilterQueryModifier::class)] class Post extends Model { // Posts will be ordered by created_at DESC // and support filtering via query parameters }
Built-in modifiers:
LatestFirstModifier- Order bycreated_at DESCUpdatedFirstModifier- Order byupdated_at DESCSortQueryModifier- Custom sortingFilterQueryModifier- Filter by query parameters
Exclude Models from API
use Wappo\LaravelSchemaApi\Attributes\ApiIgnore; #[ApiIgnore] class AdminUser extends Model { // This model will NOT be exposed via the API }
If you want to exclude a model from the HTTP API but still broadcast its changes via WebSockets:
#[ApiIgnore(shouldBroadcast: true)] class InternalAuditLog extends Model { // Not exposed via HTTP, but changes are broadcast to authorized users }
Real-Time Broadcasting
Get instant notifications when data changes using Laravel's broadcasting system:
// config/schema-api.php 'broadcasting' => [ 'enabled' => true, 'mode' => 'model-events', // or 'sync' ],
Two Broadcasting Modes:
-
syncmode (default) - Only broadcasts changes from the/schema-api/syncendpoint- Most predictable and transaction-safe
- Best for apps that exclusively use the sync endpoint
-
model-eventsmode - Broadcasts all Eloquent model changes- Captures changes from sync endpoint, console commands, direct Eloquent operations, etc.
- Respects
#[ApiIgnore]- won't broadcast excluded models (unlessshouldBroadcast: true) - Best for apps with multiple entry points for data changes
Client-Side Setup:
Configure Laravel Echo to listen for real-time updates:
// Subscribe to your user's private channel Echo.private(`user.${userId}`) .listen('.model.operation', (operation) => { // operation = { id, type, op: 'C'|'U'|'D', attr: {...} } if (operation.op === 'C') { // Add new record to your UI } else if (operation.op === 'U') { // Update existing record } else if (operation.op === 'D') { // Remove deleted record } });
Authorization:
By default, the package checks Laravel Gates to determine which users can view a model:
// In your AuthServiceProvider Gate::define('view', function (User $user, Model $model) { // Return true if $user can view $model return $user->id === $model->user_id; });
For custom authorization logic, bind your own implementation:
use Wappo\LaravelSchemaApi\Contracts\ModelViewAuthorizerInterface; $this->app->singleton(ModelViewAuthorizerInterface::class, function () { return new YourCustomAuthorizer(); });
Important: Make sure you have Laravel Broadcasting configured with a driver like Pusher, Ably, or Redis.
Custom JSON Resources
Use your own JSON resource classes:
use Wappo\LaravelSchemaApi\Attributes\UseSchemaApiJsonResource; #[UseSchemaApiJsonResource(PostResource::class)] class Post extends Model { // ... }
API Endpoints
List Models
GET /schema-api/{table}
Query Parameters:
?since=2025-01-01T00:00:00Z- Incremental sync (returns modified and deleted records)?gzip- Enable gzip compression
Response Format: NDJSON (newline-delimited JSON)
Get Single Model
GET /schema-api/{table}/{id}
Response Format: NDJSON with the model and any #[ApiInclude] relationships
List All Available Models
GET /schema-api
Returns metadata about all exposed models.
Batch Sync
PUT /schema-api/sync
Request Body: Array of operations
[
{
"op": "create|update|delete",
"type": "table-name",
"id": "record-id",
"attr": { /* attributes */ }
}
]
Response: NDJSON with the result of each operation
Configuration
Publish and edit config/schema-api.php:
return [ 'date_format' => 'Y-m-d\TH:i:s.u\Z', // ISO 8601 format 'http' => [ 'base_path' => '/schema-api', 'middleware' => ['api'], 'gzip_level' => 6, // 0-9, compression level 'relationship_batch_size' => 200, // Batch size for loading relationships ], 'broadcasting' => [ 'enabled' => false, // Enable WebSocket broadcasting 'mode' => 'sync', // 'sync' or 'model-events' ], 'restore_soft_delete_tolerance_in_seconds' => 1, // Tolerance for cascade restore 'model_resolver' => [ 'driver' => 'namespace', // 'namespace' or 'morph-map' ], 'resource_resolver' => [ 'driver' => 'namespace', // How to find JSON resource classes ], ];
Performance
The package is optimized for large datasets:
- Streaming Responses: Uses cursor pagination and NDJSON to handle millions of records without memory issues
- Efficient Relationship Loading: Batches parent records and uses
whereIn()to avoid N+1 queries - Optional Compression: Enable gzip compression with
?gzipparameter - No Model Hydration: Uses raw queries (
toBase()) for better performance
Example: Streaming 1 million records uses constant memory (~50MB) instead of loading everything into RAM.
Client Code Generation
Generate TypeScript types and Vue forms from your models:
php artisan app:generate-client-resources
This reads your model schemas and generates type-safe client code for your frontend.
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.
统计信息
- 总下载量: 35
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-10-13