Laravel API 响应收敛:用 Resource 统一字段、用 Repository 隔离查询

test12026-09-222 次阅读

两个常见的乱源

写 Laravel 接口时,最容易乱掉的是两处:一是控制器里直接把 Eloquent 模型 toArray,前端要什么字段就在模型层改,结果模型被接口需求绑架;二是查询逻辑散落在各个控制器,同样的「活跃用户分页」在三个地方各写一遍,改条件要改三处。用 Resource 收敛响应、用 Repository 隔离查询,能把这两件事彻底解耦。

用 Resource 决定对外字段

ApiResource 把「模型长什么样」和「接口返回什么」分开。字段在这里裁剪,敏感字段还能按当前用户动态决定是否暴露。

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    public function toArray($request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->when($request->user()?->id === $this->id, $this->email),
            'created_at' => $this->created_at->toDateTimeString(),
        ];
    }
}

用 Repository 收拢查询

Repository 把数据来源封装成一组语义化方法,控制器只关心「要什么」,不关心「怎么查」。换数据源、加缓存、改排序都只动这一个类。

namespace App\Repositories;

use App\Models\User;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;

class UserRepository
{
    public function paginateActive(int $perPage = 20): LengthAwarePaginator
    {
        return User::query()
            ->where('is_active', true)
            ->orderByDesc('created_at')
            ->paginate($perPage);
    }

    public function find(int $id): ?User
    {
        return User::find($id);
    }
}

控制器只做编排

namespace App\Http\Controllers;

use App\Http\Resources\UserResource;
use App\Repositories\UserRepository;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;

class UserController extends Controller
{
    public function __construct(private UserRepository $users) {}

    public function index(): AnonymousResourceCollection
    {
        return UserResource::collection($this->users->paginateActive());
    }
}

收益与边界

  • 字段变更集中在 Resource,模型不被接口需求污染。
  • 查询逻辑集中在 Repository,避免同样的条件散落多处。
  • 小型项目或单表简单 CRUD 不必强行套 Repository,过度分层也是负担。
T

test1

文章作者

两个常见的乱源 写 Laravel 接口时,最容易乱掉的是两处:一是控制器里直接把 Eloquent 模型 toArr...

分类
技术
发布时间
2026-09-22
字数
约 1822 字
阅读
2 次