为什么或何时使用Laravel资源/集合

问题描述 投票:1回答:1

我不明白为什么或何时使用Laravel https://laravel.com/docs/7.x/eloquent-resources中的资源。

请参阅此控制器:

public function show(School $school)
{
    // return response()->json($school, 200);
    return new SchoolResource($school);
}

两个返回解决方案都返回了这种响应:

    {
    "data": {
        "id": "4f390a7b-3c3f-4c23-9e6a-dd4429cf835d",
        "name": "school name",
.......,

数据是自动注入查询的结果(在这里:$ school)。

以及关于资源收集的相同问题。想象一下这个控制器:

public function index(Request $request)
{
    try {
        $schools = $this->schoolRepository->all($request->all());
    } catch (\Exception $e) {
        return response()->json(['message' => 'Bad request'], 400);
    }

    return SchoolResource::collection($schools);
    // return response()->json($schools, 200);
}

如果需要添加一些字段,可以在模型或存储库中进行。

我经常读到,这个资源概念对于理解和使用很重要。但是目前我还没有看到什么时候或为什么要使用它。我当然一定不明白!

laravel
1个回答
5
投票

有两个主要的原因来使用资源来管理您的返回值,即使您的资源除了今天不做任何事情之外,您将来可能希望它做一些不同的事情。

资源真正有用的原因的一小部分

1。特定于客户端的数据操作(即,使用您的api的js应用程序)

如果您开始使用增变器(getters / setters)来处理模型中的数据。您的内部应用程序现在必须使用这些约束。很多时候,它更容易在内部处理原始数据,然后只允许您的资源为客户端处理数据。

2。符合API规范,例如JSON API v1.0

尽管您可能需要在应用程序中使用逻辑来处理此类架构,但是模型和控制器不应该如此。该资源在这里起着至关重要的作用,以合规的方式为您的消费者应用程序组织数据。

3。古老的口头禅,关注点分离

这与第1点紧密相关,将数据映射到您希望用户应用程序接收的内容不是模型或控制器的责任。

以您的示例为基础

您当前在资源控制器的show路由中具有以下内容。

public function show(School $school)
{
    // return response()->json($school, 200);
    return new SchoolResource($school);
}

即使您的API规范做了更改,也不必更改(原因1和3)。

添加字段,是的,您需要将它们添加到模型中,但是使用它可以对资源进行有意义的处理。

我们已经为新的JSON字段ratings创建了迁移。评分具有这样的数据结构:

[
    {
        name: string,
        value: integer,
    }
]

出于诸如媒体审查之类的原因,我们从不希望将所有评级数据公开给我们的公开前端消费者应用程序。相反,我们希望提供所有评分的平均分数。

现在我们可以在模型中执行此操作,但这是模型的责任吗?并非如此,该模型仅应处理和处理原始/谨慎修改的数据。那么控制者的责任呢?不,控制器协调应执行的操作,并且对特定的细节或数据不感兴趣。

那么我们在哪里做?输入您已经方便设置的资源。

class School extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'rating' => $this->getRating(),
        ];
    }

    /**
     * @return integer
     */
    protected function getRating() {
        return (array_reduce($this->ratings, function($acc, $curr) {
            $acc += $curr['value'];
            return $acc;
        }, 0)) / count($this->ratings);
    }
}

该资源是我们专门为响应而处理数据的地方,而我们的内部数据建模则保持不变且干净无污染,不会因使用的应用程序的细微差别而受到污染。

更重要的是,如果您刚从控制器返回return response()->json($school, 200);,则您的数据结构将不匹配,并且您会将一些敏感数据暴露给前端应用程序。

© www.soinside.com 2019 - 2024. All rights reserved.