Response()不遵守API资源结构

时间:2018-10-05 12:41:58

标签: php laravel rest

我有一个奇怪的问题(至少在我疲倦的眼神中),在该问题中,使用response()函数返回API资源会忽略该资源的with()方法,并且也不会添加'data '换行。奇怪的是,后一个问题仅在单一资源上,而不在集合上。

我正在使用Laravel 5.7。

使用response()函数的方法在我的API控制器中,该方法由我的其他控制器扩展。

有趣的是,使用$data->response()可以工作,但是我希望response方法只能接受集合/模型/资源,而不能接受数组,例如,我依赖于其他调用{{ 1}},就像我的respond()方法一样。

ApiController

respondWithError()

ClubController

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);
        }
    }
...
}

ClubCollection资源

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)));
    }
...
}

ClubResource

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 '
        ];
    }
}

为澄清起见,索引或显示端点均不会导致调用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()方法还返回平面数据,没有'data'键将其包装。

api / v1 / clubs / 1返回:

show()

预期回报:

{
"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."
}

2 个答案:

答案 0 :(得分:0)

根据需要发送响应

return response()->json(["data" => $data, 'status'=>$status], $code);

$code是响应代码,可以根据您的要求为404,500,200

答案 1 :(得分:0)

资源有自己的通过response()方法返回响应的方式。

注意:通过response()方法,我引用的是Resource类中的->response(),而不是助手全局函数response()

例如:(new ClubCollection(Club::all()))->response()->setStatusCode(200);

您可以在响应方法的顶部添加退出语句

public function respond($data, int $status_code = 200)
{

    if ($data instanceof JsonResource) {
        return $data->response()->setStatusCode($status_code);
    }
    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);
    }
}