У меня странная (по крайней мере для моих усталых глаз) проблема, когда при использовании функции response()
для возврата ресурса API игнорируется метод with()
указанного ресурса, а также не добавляется перенос ключа 'data'.Как ни странно, последняя проблема касается только отдельных ресурсов, а не коллекций.
Я использую Laravel 5.7.
Метод, использующий функцию response()
, находится в моем контроллере API, который расширендругими моими контроллерами.
Интересно, что использование $data->response()
работает, но я бы тогда ответил, что метод ответа мог бы принимать только коллекции / модели / ресурсы, а не массив, например - на который я полагаюсьдругие методы, которые вызывают respond()
, как мой respondWithError()
метод.
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 '
];
}
}
ClubResource
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' => 'success'
];
}
}
Для пояснения, ни индекс, ни показ конечных точек не приводят к with()
метод вызывается.Что еще более важно, метод show()
также возвращает плоские данные, без ключа «data», обертывающего их.
api / v1 / clubs / 1 возвращает:
{
"id": 1,
"name": "Johns Ltd",
"primary_color": "18,140,142",
"secondary_colour": "13,148,5",
"tertiary_colour": "187,18,162",
"logo_url": "https://lorempixel.com/640/480/?58550",
"narrative": "Consequatur veniam consectetur sint blanditiis. Minima fugiat voluptatem aperiam corporis assumenda et consequuntur. Voluptate fugiat nulla eos ut. Itaque vero doloribus ea nihil consequuntur vel. Minus error quos occaecati dignissimos."
}
Ожидаемый доход:
{
"data": {
"id": 1,
"name": "Johns Ltd",
"primary_color": "18,140,142",
"secondary_colour": "13,148,5",
"tertiary_colour": "187,18,162",
"logo_url": "https://lorempixel.com/640/480/?58550",
"narrative": "Consequatur veniam consectetur sint blanditiis. Minima fugiat voluptatem aperiam corporis assumenda et consequuntur. Voluptate fugiat nulla eos ut. Itaque vero doloribus ea nihil consequuntur vel. Minus error quos occaecati dignissimos."
},
"status": "success"
}