mustafafares/laravel-selective-response
Composer 安装命令:
composer require mustafafares/laravel-selective-response
包简介
Automatic API resource filtering based on model select() queries with optional Scramble documentation support
README 文档
README
Automatic API resource filtering based on model select() queries with optional Scramble documentation support.
Features
- Automatic Filtering: Automatically filters API resource responses based on
select()queries - Zero Breaking Changes: Just change your resource parent class - no code changes needed
- Scramble Integration: Optional extension that updates API documentation to show only selected fields
- Flexible Configuration: Enable/disable globally or per-resource
- Always-Include Fields: Support for fields that should always be included
- Relationship Support: Works seamlessly with
whenLoaded()pattern
Installation
composer require mustafafares/laravel-selective-response
Publish the configuration file:
php artisan vendor:publish --tag=selective-response-config
Quick Start
1. Update Your Resources
Change your resources to extend BaseApiResource instead of JsonResource:
<?php namespace App\Http\Resources; use MustafaFares\SelectiveResponse\Http\Resources\BaseApiResource; class UserResource extends BaseApiResource { public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'phone' => $this->phone, 'address' => $this->address, ]; } }
2. Use in Controllers
<?php namespace App\Http\Controllers\Api; use App\Http\Resources\UserResource; use App\Models\User; class UserController extends Controller { // Full response - returns all fields public function show($id) { $user = User::findOrFail($id); return new UserResource($user); } // Selective response - returns only selected fields public function summary($id) { $user = User::select('id', 'name', 'email')->findOrFail($id); return new UserResource($user); // Returns: {id, name, email} ✨ } }
That's it! The filtering happens automatically.
Usage Examples
Basic Usage
// Resource (no changes needed!) class UserResource extends BaseApiResource { public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'phone' => $this->phone, ]; } } // Controller - Full response $user = User::find($id); return new UserResource($user); // Returns: {id, name, email, phone} // Controller - Selective response $user = User::select('id', 'name')->find($id); return new UserResource($user); // Returns: {id, name} ✨ Automatic!
Always Include Fields
class UserResource extends BaseApiResource { protected $alwaysInclude = ['id']; public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, ]; } } // Even with select('name'), 'id' is always included User::select('name')->find($id); // Returns: {id, name}
Disable Filtering
// Option 1: In resource class class AdminResource extends BaseApiResource { protected $useSelectiveResponse = false; } // Option 2: In controller return (new UserResource($user))->withoutSelectiveFiltering();
With Relationships
class UserResource extends BaseApiResource { public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'posts' => PostResource::collection($this->whenLoaded('posts')), ]; } } // Load relationship User::select('id', 'name')->with('posts')->find($id); // Returns: {id, name, posts: [...]}
Dynamic Always-Include
public function summary($id) { $user = User::select('name')->findOrFail($id); return (new UserResource($user)) ->alwaysInclude(['id', 'created_at']); }
Scramble Extension
The package includes an optional extension for Scramble that automatically detects select() calls in your controllers and updates the API documentation to show only selected fields.
Setup
- Install Scramble (if not already installed):
composer require dedoc/scramble
- Install PHP Parser (required for the extension):
composer require nikic/php-parser
- Publish Scramble config (if not already done):
php artisan vendor:publish --tag=scramble-config
- Register the extension in
config/scramble.php:
<?php return [ // ... other config ... 'extensions' => [ \MustafaFares\SelectiveResponse\Extensions\SelectiveResponseExtension::class, ], ];
How It Works
The extension uses PHP Parser to analyze your controller methods and find select() calls. It then filters the OpenAPI schema to show only the selected fields in the documentation.
Before Extension:
// Controller $user = User::select('id', 'name', 'email')->findOrFail($id); return new UserResource($user); // Scramble docs show: {id, name, email, phone, address, ...} ❌
After Extension:
// Same controller code $user = User::select('id', 'name', 'email')->findOrFail($id); return new UserResource($user); // Scramble docs show: {id, name, email} ✅
Disable Scramble Extension
You can disable the Scramble extension in the config:
// config/selective-response.php 'scramble' => [ 'enabled' => false, ],
Configuration
Publish the configuration file:
php artisan vendor:publish --tag=selective-response-config
Available Options
<?php return [ // Enable/disable selective filtering globally 'enabled' => env('SELECTIVE_RESPONSE_ENABLED', true), // Fields that should always be included globally 'always_include' => [ // 'id', ], // Scramble extension configuration 'scramble' => [ 'enabled' => env('SELECTIVE_RESPONSE_SCRAMBLE_ENABLED', true), 'always_include_in_docs' => [ // 'id', ], ], ];
Common Patterns
List Endpoint (Efficient)
public function index() { $users = User::select('id', 'name', 'email') ->paginate(20); return UserResource::collection($users); }
Detail Endpoint (Full Data)
public function show($id) { $user = User::with('posts', 'role')->findOrFail($id); return new UserResource($user); }
Search with Dynamic Fields
public function search(Request $request) { $fields = explode(',', $request->input('fields', 'id,name,email')); $users = User::select($fields) ->where('name', 'like', "%{$request->q}%") ->get(); return UserResource::collection($users); }
Force Full Response
public function adminView($id) { $user = User::select('id')->findOrFail($id); return (new UserResource($user))->withoutSelectiveFiltering(); }
Advanced Features
Custom Always-Include Logic
class UserResource extends BaseApiResource { protected function shouldIncludeKey(string $key, $value): bool { // Always include timestamps if (in_array($key, ['created_at', 'updated_at'])) { return true; } return parent::shouldIncludeKey($key, $value); } }
Conditional Computed Fields
public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'full_name' => $this->whenAttributeLoaded('name', $this->first_name . ' ' . $this->last_name ), ]; }
Testing
use MustafaFares\SelectiveResponse\Http\Resources\BaseApiResource; use Tests\TestCase; use App\Models\User; class SelectiveResponseTest extends TestCase { public function test_selective_response() { $user = User::factory()->create(); $selected = User::select('id', 'name')->find($user->id); $resource = new UserResource($selected); $data = $resource->toArray(request()); $this->assertArrayHasKey('id', $data); $this->assertArrayHasKey('name', $data); $this->assertArrayNotHasKey('email', $data); } }
Troubleshooting
Issue: All fields still returned
Solution: Verify you're extending BaseApiResource, not JsonResource
Issue: Relationships not working
Solution: Use $this->whenLoaded() for relationships
Issue: Computed fields missing
Solution: Use $this->whenAttributeLoaded() for computed fields
Issue: Need specific field always
Solution: Add to protected $alwaysInclude = ['field']; in your resource
Issue: Scramble extension not working
Solutions:
- Clear config cache:
php artisan config:clear - Verify extension is in
config/scramble.php - Check PHP Parser is installed:
composer show nikic/php-parser - Ensure Scramble is installed:
composer show dedoc/scramble
Performance Benefits
| Endpoint | Without Select | With Select | Improvement |
|---|---|---|---|
| User list | 50 KB | 10 KB | 80% smaller |
| Search | 100 KB | 20 KB | 80% smaller |
| Summary | 2 KB | 0.5 KB | 75% smaller |
Result: Faster APIs, lower bandwidth costs, better UX!
Migration Guide
From JsonResource to BaseApiResource
- Change the parent class:
// Before class UserResource extends JsonResource // After class UserResource extends BaseApiResource
- Add the import:
use MustafaFares\SelectiveResponse\Http\Resources\BaseApiResource;
- That's it! Your
toArray()method works exactly the same.
Requirements
- PHP 8.1+
- Laravel 10.0+, 11.0+, or 12.0+
- (Optional) Scramble 1.0+ for documentation extension
- (Optional) PHP Parser 5.0+ for Scramble extension
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
For issues and questions, please open an issue on GitHub.
mustafafares/laravel-selective-response 适用场景与选型建议
mustafafares/laravel-selective-response 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 14 次下载、GitHub Stars 达 1, 最近一次更新时间为 2025 年 12 月 30 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「api」 「laravel」 「resource」 「filtering」 「selective」 「scramble」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 mustafafares/laravel-selective-response 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 mustafafares/laravel-selective-response 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 mustafafares/laravel-selective-response 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Generates URLs for public Puli resources.
Add the resource system to symfony application
A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.
Adds support for singular resource routes to the Laravel router.
A PSR-7 compatible library for making CRUD API endpoints
Retrieve a WebResourceInterface instance over HTTP
统计信息
- 总下载量: 14
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 22
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-12-30