Laravel 资源 VS ViewModel

问题描述 投票:0回答:3

我开始使用 Laravel 开发 API 服务。现在,我正在使用 DDD 方法(并同时学习它)。

目前我的结构如下:

我的应用程序

  • 应用程序
    • (laravel 应用程序的东西)
  • 源代码
    • 域名
      • 类别
        • 行动
        • 数据传输对象
        • 型号
        • 资源

如您所见,我目前正在使用

Resources
。例如,在我的类别控制器中,我有:

public function index(): AnonymousResourceCollection
    {
        $categories = Category::all();
        return CategoriesResource::collection($categories);
    }

我的资源文件如下所示:

<?php

namespace Domain\Category\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class CategoriesResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  Request  $request
     * @return array
     */
    public function toArray($request): array
    {
        return [
            'id' => (string)$this->id,
            'type' => 'categories',
            'attributes' => [
                'name' => $this->name,
                'parent' => $this->parent,
                'description' => $this->description,
                'image' => $this->image,
                'created_at' => $this->created_at,
                'updated_at' => $this->updated_at,
            ]
        ];
    }
}

返回前端最终期望的 JSON 响应。

现在,我一直在阅读有关

ModelView
的内容,但仍然不理解这个概念,或者它如何代替(或与)
Resources
一起工作。到目前为止,我看到的大多数示例实际上并没有从
ModelView
.

返回完整的 JSON 响应

谢谢

php laravel domain-driven-design laravel-9 model-view
3个回答
1
投票

它们是两个不同的东西。 Laravel

Resources
专为 API 响应而设计,可使用您可能需要的任何类型的逻辑将您的 Eloquent 模型转换为 JSON 响应。就这么简单(就像您在代码中所做的那样)。


TL;博士:

Resource
:将属性、加载关系转换、添加或删除为“模型的 JSON 表示形式(或模型的
collection
)”。
ModelView
:它只是一个包含一堆方法的文件,可以在视图中使用,而不是在控制器的每个方法中单独传递每个变量。


长解释:

现在,在您发布的有关

ModelView
的链接中,他们给出了以下示例作为将数据传递到视图的普通方式:

public function create()
{
    // Here we are just passing the $categories
    return view('blog.form', [
        'categories' => Category::allowedForUser(
           current_user()
        )->get()
    ]);
}

public function edit(Post $post)
{
    // Here we are passing $post, and the $categories are
    // the same like in the "create" method
    return view('blog.form', [
        'post' => $post,
        'categories' => Category::allowedForUser(
           current_user()
        )->get()
    ]);
}

这个“ViewModel”只是将控制器中的所有逻辑和方法封装到单个文件中的一种方法,该文件最后包含传递给视图的所有信息(甚至是您可能不需要的数据) .

class PostFormViewModel
{
    public function __construct(User $user, Post $post = null) 
    {
        $this->user = $user;
        $this->post = $post;
    }
    
    public function post(): Post
    {
        return $this->post ?? new Post();
    }
    
    public function categories(): Collection
    {
        // The same query as in the "ordinary" example
        return Category::allowedForUser($this->user)->get();
    }
}
class PostsController
{
    public function create()
    {
        $viewModel = new PostFormViewModel(
            current_user()
        );
        
        return view('blog.form', compact('viewModel'));
    }
    
    public function edit(Post $post)
    {
        $viewModel = new PostFormViewModel(
            current_user(), 
            $post
        );
    
        return view('blog.form', compact('viewModel'));
    }
}

这就是在视图中应该如何使用:

<input value="{{ $viewModel->post()->title }}" />
<input value="{{ $viewModel->post()->body }}" />

<select>
    @foreach ($viewModel->categories() as $category)
        <option value="{{ $category->id }}">
            {{ $category->name }}
        </option>
    @endforeach
</select>

这种方法有一些我不喜欢的地方(在这个特定的例子中):

  • 每次调用
    $viewModel->categories()
    时,您都会对数据库进行查询(而不是传递 $categories 并在视图中根据需要多次调用它,而不进行新查询)
  • 您仍然将
    current_user()
    $post
    传递给
    ViewModel
    然后将所有这些传递给视图。
  • 最后:当您需要使用 JSON 进行响应(如 API 响应)时,您不会使用这个
    ModelView
    ,而是使用一个简单的
    Resource

0
投票

模型用于查询数据库中表中的数据和从表中查询数据。 构建 API 时需要资源类,您可能需要一个位于 Eloquent 模型和实际返回给应用程序用户的 JSON 响应之间的转换层。

示例:

$users = User:all();
return UserResource::collection($users);

0
投票

我还有一篇关于资源路由的文章,以防有人需要Laravel 资源路由

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