Laravel Eloquent: API 资源 - 它是如何工作的,以便我可以创建一个类似的 class?
Laravel Eloquent: API Resources - How does it work, so that I can create a similar class?
看这个例子:
use App\Http\Resources\UserResource;
use App\Models\User;
Route::get('/user/{id}', function ($id) {
return new UserResource(User::findOrFail($id));
});
这在内部是如何工作的?因为乍一看我们只是returnclassUserResource
的一个Object。但是 Laravel 神奇地调用了 toArray
函数并正确解析了它。
我希望我的推荐 class 也能发挥作用。
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
}
输出 array/json 应解析为:
return [
'title' => $title,
'description' => $description,
'courses' => (collection) $courses
];
您创建的任何资源都是 Illuminate\Contracts\Support\Responsable
接口的实例,
这意味着他们每个人 必须 实施 toResponse
方法。
如果我们查看 JsonResponse
的 toResponse
方法,我们会看到以下代码:
public function toResponse($request)
{
return (new ResourceResponse($this))->toResponse($request);
}
它在内部调用 Resource
的 resolve
方法。
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 会发生,当你 return ['collecion' => new SomeRecomendation()]
、Laravel 调用 json_encode
时(对 return 的响应为 json ),
因为 new SomeRecomendation()
是 JsonSerializable
的实例,它将调用 jsonSerialize
方法并从中编码一个数组 return。
当你return只return new SomeRecomendation();
来自控制器时,它会调用,因为它是Arrayable
的实例,Laravel神奇地调用toArray
方法。
希望这个回答对您有所帮助。
看这个例子:
use App\Http\Resources\UserResource;
use App\Models\User;
Route::get('/user/{id}', function ($id) {
return new UserResource(User::findOrFail($id));
});
这在内部是如何工作的?因为乍一看我们只是returnclassUserResource
的一个Object。但是 Laravel 神奇地调用了 toArray
函数并正确解析了它。
我希望我的推荐 class 也能发挥作用。
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
}
输出 array/json 应解析为:
return [
'title' => $title,
'description' => $description,
'courses' => (collection) $courses
];
您创建的任何资源都是 Illuminate\Contracts\Support\Responsable
接口的实例,
这意味着他们每个人 必须 实施 toResponse
方法。
如果我们查看 JsonResponse
的 toResponse
方法,我们会看到以下代码:
public function toResponse($request)
{
return (new ResourceResponse($this))->toResponse($request);
}
它在内部调用 Resource
的 resolve
方法。
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 会发生,当你 return ['collecion' => new SomeRecomendation()]
、Laravel 调用 json_encode
时(对 return 的响应为 json ),
因为 new SomeRecomendation()
是 JsonSerializable
的实例,它将调用 jsonSerialize
方法并从中编码一个数组 return。
当你return只return new SomeRecomendation();
来自控制器时,它会调用,因为它是Arrayable
的实例,Laravel神奇地调用toArray
方法。
希望这个回答对您有所帮助。