Look at this example:
use App\Http\Resources\UserResource;
use App\Models\User;
Route::get('/user/{id}', function ($id) {
return new UserResource(User::findOrFail($id));
});
How does this internally work? Because at first glance we just return an Object of the class UserResource
. But Laravel is magically calling the toArray
function and resolves it correctly.
I want the same for my Recommendation class to work.
use App\Http\Recommendations\RecentlyUpdatedRecommendation;
use ...
Route::get('/someurl', function () {
return ['collections' => [
new RecentlyUpdatedRecommendation(),
new WatchlistRecommendation(),
new LastWatchedRecommendation(),
...
]];
});
With
/**
* All Recommendations use this as output
*/
abstract class Recommendation
{
// No Idea what needs to be put here
}
The output array/json should resolve into this:
return [
'title' => $title,
'description' => $description,
'courses' => (collection) $courses
];
Any resource that you create is instance of Illuminate\Contracts\Support\Responsable
Interface,
This means that each of them must have toResponse
method implemented.
If we look at JsonResponse
's toResponse
method we see this code:
public function toResponse($request)
{
return (new ResourceResponse($this))->toResponse($request);
}
Internally it is calling Resource
's resolve
method.
resolve
method is where we see toArray
method to be called
public function resolve($request = null)
{
$data = $this->toArray(
$request = $request ?: Container::getInstance()->make('request')
);
}
By creating new response you are just overriding toArray
method with your logic.
In Your case, you don't need to write too much to get toArray
method "magically" called
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
];
}
}
Now watch will happen, When you return ['collecion' => new SomeRecomendation()]
, Laravel calls json_encode
on it ( to return response as json ),
Because new SomeRecomendation()
is instance of JsonSerializable
it will call jsonSerialize
method and encodes an array returned from it.
When you return only return new SomeRecomendation();
from controller, it will call, because it is instance of Arrayable
, Laravel calls toArray
method magically.
Hope this answer helps you.