I have a strange (at least to my tired eyes) problem where using the response() function to return an API resource is ignoring the with() method of said resource, and also not adding the 'data' key wrapping. Strangely the latter issue is only on single resources, not on collections.
The method using the response() function is in my API controller, which is extended by my other controllers.
ApiController
class ApiController extends Controller
{
public function respond($data, int $status_code = 200)
{
try {
// this is where the issue is
// simply returning $data prevents the issue
return response($data)->setStatusCode($status_code);
} catch (Throwable $t) {
$this->logger->log('critical', $t->getMessage(), ['exception' => $t]);
return $this->respondWithError(500);
}
}
...
}
ClubController
use App\Http\Resources\Club as ClubResource;
use App\Http\Resources\ClubCollection;
...
class ClubController extends ApiController
{
/**
* Display a listing of the resource.
*
* @return ClubCollection
*/
public function index()
{
// returns with data key wrapping, but ignores the with() method on the resource
// collection
return $this->respond(new ClubCollection(Club::all()));
}
public function show($id)
{
// returns with no wrapping, and also doesn't implement resource with() method
return $this->respond(new ClubResource(Club::findOrFail($id)));
}
...
}
ClubCollection Resource
class ClubCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => $this->collection,
'links' => [
'self' => 'link-value'
],
'status' => 'success'
];
}
// doesn't get called
public function with($request)
{
return [
'test' => 'this will be ignored '
];
}
}
Club Resource
class Club extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'primary_color' => $this->primary_colour,
'secondary_colour' => $this->secondary_colour,
'tertiary_colour' => $this->tertiary_colour,
'logo_url' => $this->logo_url,
'narrative' => $this->narrative
];
}
// doesn't get called
public function with($request)
{
return [
'status' => 'this will be ignored'
];
}
}
To clarify, neither the index or show endpoints result in the with() method being called.
More importantly, the show method also returns the data flat, with no 'data' key wrapping it.