如何基于Laravel JSON:API实现用户权限计算值的端点?
解决方案
1. 定义权限数据模型(DTO)
先创建一个普通类作为数据传输对象,用来封装计算后的用户产品权限信息,无需继承Eloquent:
// app/Models/Access.php namespace App\Models; class Access { public function __construct( public array $products // 存储每个产品的权限详情:product_id、product_name、has_access、expires_at ) {} }
2. 创建Access资源类
为上述DTO创建JSON:API资源,定义返回字段的映射规则:
// app/JsonApi/Resources/AccessResource.php namespace App\JsonApi\Resources; use Illuminate\Http\Request; use LaravelJsonApi\Core\Resources\JsonApiResource; class AccessResource extends JsonApiResource { public function attributes($request): array { return [ 'products' => collect($this->products)->map(function ($product) { return [ 'product_id' => $product['product_id'], 'product_name' => $product['product_name'], 'has_access' => $product['has_access'], 'expires_at' => $product['expires_at']?->toIso8601String(), ]; })->toArray(), ]; } public function type(): string { return 'user-accesses'; // 定义资源类型,无需单独创建独立端点路由 } }
3. 配置嵌套关联路由
在JSON:API v1路由配置中,为users资源添加hasOne关联的access端点:
// routes/api-v1.php use LaravelJsonApi\Core\Facades\JsonApi; JsonApi::register('v1')->routes(function ($api) { $api->resource('users') ->hasOne('access'); // 绑定用户与权限的关联关系 });
4. 实现关系逻辑与权限计算
4.1 定义用户资源的关联关系
修改UserResource,添加access关系的定义:
// app/JsonApi/Resources/UserResource.php namespace App\JsonApi\Resources; use LaravelJsonApi\Core\Resources\JsonApiResource; class UserResource extends JsonApiResource { // ... 现有代码 public function relationships(): array { return [ // ... 其他已定义的关系 $this->relation('access')->resource(AccessResource::class), ]; } }
4.2 实现权限计算与端点逻辑
在UserController中添加showAccess方法,负责查询用户购买记录并计算权限:
// app/JsonApi/Controllers/UserController.php namespace App\JsonApi\Controllers; use App\Models\Access; use App\Models\User; use LaravelJsonApi\Laravel\Http\Controllers\JsonApiController; class UserController extends JsonApiController { // ... 现有代码 public function showAccess(User $user) { // 从数据库查询用户购买记录,计算每个产品的权限状态与过期时间 $productPermissions = $user->purchases->map(function ($purchase) { return [ 'product_id' => $purchase->product_id, 'product_name' => $purchase->product->name, 'has_access' => $purchase->expires_at > now(), 'expires_at' => $purchase->expires_at, ]; })->toArray(); // 组装成Access DTO实例 $access = new Access($productPermissions); return new AccessResource($access); } }
关键说明
- 采用非Eloquent DTO完全适配你的需求:权限是计算生成的,无需独立数据库表或单独端点。
- 通过
hasOne关联绑定到用户资源,完美匹配/api/v1/users/{id}/access的嵌套端点结构。 - 权限计算逻辑完全可控,只需在
showAccess中根据用户购买记录调整计算规则即可。
内容的提问来源于stack exchange,提问作者adear11
相关产品推荐
相关产品推荐

