如何将自定义请求传递给Api资源

时间:2019-02-19 13:58:14

标签: php laravel api

我有自定义的Request类:

class ApiRequest extends FormRequest
{
    ...
    public function locale()
    {
        $lang = $this->header('Accept-Language');
        return $lang ? $lang : 'uz';
    }
}

和API资源:

class SomeResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            ...
        ];
    }
}

但是我不能在SomeResource中使用ApiRequest的方法locale()。因为toArray()仅接受\Illuminate\Http\Request

有什么想法可以让我的课程通过吗?或者是您的更好解决方案。

3 个答案:

答案 0 :(得分:1)

创建响应时,绑定在容器中的请求实例将注入JSON资源类中。

一种实现所需目标的方法是,创建扩展标准请求类的自定义请求,然后将其绑定到容器中,作为用于其余请求的请求实例。这可以在专门分配给API组的中间件中完成,也可以在特定的控制器中完成。

然后,当构建响应并可以使用您的自定义方法时,它将注入到JSON资源类的toArray()方法中。

自定义请求类别

class ApiRequest extends Request
{
    ...
    public function locale()
    {
        $lang = $this->header('Accept-Language');
        return $lang ? $lang : 'uz';
    }
}

API中间件

class ApiMiddleware
{
    ...
    public function handle($request, $next)
    {
        $request = app()->instance('request', ApiRequest::createFrom($request));
        
        return $next($request);
    }
}

JSON资源

class SomeResource extends JsonResource
{
    public function toArray($request)
    {
        // $request is now instanceof ApiRequest

        return [
            'id' => $this->id,
            'locale' => $request->locale()
        ];
    }
}

答案 1 :(得分:0)

API Resources应该接收模型实例,而不是Requests本身。这是一个示例:

ApiRequest.php

ApiRequest extends Request {

    public function authorize() { /** your logic */ }

    public function rules() { /** your logic */ }

}

MyCoolController.php

MyCoolController extends Controller {

    public function myFunction(ApiRequest $request)
    {
        $lang = $request->header('Accept-Language') ?? 'uz';
        \App::setLocale($lang); // <--

        $model = MyModel::find($request->get('id'));

        return new SomeResource($model);
    }
}

答案 2 :(得分:0)

我创建了一个基本的Resource类,所有其他资源类都使用自定义方法对其进行了扩展:

class BaseResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return parent::toArray($request);
    }

    protected function locale($request)
    {
        $lang = $request->header('Accept-Language');
        return $lang ? $lang : 'uz';
    }
}

我在子类中使用它:

class SomeResource extends BaseResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        $lang = $this->locale($request);

        return [
            'id' => $this->id,
            'hash' => $this->hash,
            'name'  => $this->translation('name', $this->locale($request)),
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
        ];
    }
}