Laravel Eloquent:API 资源 - 它是如何工作的,以便我可以创建一个类似的类?

时间:2021-07-09 07:17:28

标签: laravel laravel-eloquent-resource

看看这个例子:

use App\Http\Resources\UserResource;
use App\Models\User;

Route::get('/user/{id}', function ($id) {
    return new UserResource(User::findOrFail($id));
});

这在内部是如何工作的?因为乍一看我们只是返回一个 UserResource 类的对象。但是 Laravel 神奇地调用了 toArray 函数并正确解析了它。

我希望我的推荐课程也能发挥同样的作用。

use App\Http\Recommendations\RecentlyUpdatedRecommendation;
use ...

Route::get('/someurl', function () {
    return ['collections' => [
       new RecentlyUpdatedRecommendation(),
       new WatchlistRecommendation(),
       new LastWatchedRecommendation(),
       ...
    ]];
});

/**
 * All Recommendations use this as output
 */
abstract class Recommendation
{
    // No Idea what needs to be put here
}

输出数组/json 应该解析为:

    return [
        'title' => $title,
        'description' => $description,
        'courses' => (collection) $courses
    ];

1 个答案:

答案 0 :(得分:3)

您创建的任何资源都是 Illuminate\Contracts\Support\Responsable 接口的实例, 这意味着他们每个人必须都实现了 toResponse 方法。

如果我们查看 JsonResponsetoResponse 方法,我们会看到以下代码:

public function toResponse($request)
{
    return (new ResourceResponse($this))->toResponse($request);
}

在内部调用 Resourceresolve 方法。

resolve 方法是我们看到要调用的 toArray 方法

public function resolve($request = null)
{
    $data = $this->toArray(
        $request = $request ?: Container::getInstance()->make('request')
    );
}

通过创建新的响应,您只是用您的逻辑覆盖 toArray 方法。

在你的情况下,你不需要写太多来“神奇地”调用 toArray 方法

use Illuminate\Contracts\Support\Arrayable;
use JsonSerializable;

abstract class Recommendation implements Arrayable, JsonSerializable {
  
}
...
class SomeRecomendation extends Recommendation {

  public function jsonSerialize()
  {
    return $this->toArray();
  }

  public function toArray(){
    return [
      'title' => $title,
      'description' => $description,
      'courses' => (collection) $courses
    ];
  }
}

现在 watch 会发生,当你返回 ['collecion' => new SomeRecomendation()] 时,Laravel 会调用 json_encode(以 json 形式返回响应), 因为 new SomeRecomendation()JsonSerializable 的实例,它会调用 jsonSerialize 方法并对从它返回的数组进行编码。

当你只从控制器返回 return new SomeRecomendation(); 时,它会调用,因为它是 Arrayable 的实例,Laravel 神奇地调用了 toArray 方法。

希望这个回答对您有所帮助。