Php 如何将自定义请求传递给Api资源
我有自定义请求类:Php 如何将自定义请求传递给Api资源,php,laravel,api,Php,Laravel,Api,我有自定义请求类: 类ApiRequest扩展了FormRequest { ... 公共函数locale() { $lang=$this->header('Accept-Language'); 返回$lang?$lang:'uz'; } } 和API追索权: class SomeResource扩展了JsonResource { 公共功能待命($request) { 返回[ 'id'=>this->id, ... ]; } } 但是我不能在SomeResource中使用apirest的方法l
类ApiRequest扩展了FormRequest
{
...
公共函数locale()
{
$lang=$this->header('Accept-Language');
返回$lang?$lang:'uz';
}
}
和API追索权:
class SomeResource扩展了JsonResource
{
公共功能待命($request)
{
返回[
'id'=>this->id,
...
];
}
}
但是我不能在SomeResource中使用apirest的方法locale()
。因为toArray()
只接受\illumb\Http\Request
有没有想过我会通过我的课程进入这个领域?或者您提供更好的解决方案。应该接收模型实例,而不是模型本身。这是一个例子:
apirest.php
ApiRequest extends Request {
public function authorize() { /** your logic */ }
public function rules() { /** your logic */ }
}
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);
}
}
mycolcontroller.php
ApiRequest extends Request {
public function authorize() { /** your logic */ }
public function rules() { /** your logic */ }
}
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);
}
}
MyCoolController扩展控制器{
公共函数myFunction(APIRESQUEST$request)
{
$lang=$request->header('Accept-Language')??“uz”;
\App::setLocale($lang);//get('id');
返回新的SomeResource($model);
}
}
我创建了一个基本资源类,所有其他资源类都使用我的自定义方法对其进行扩展:
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,
];
}
}
创建响应时,容器中绑定的请求实例被注入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);
}
}
class SomeResource extends JsonResource
{
public function toArray($request)
{
// $request is now instanceof ApiRequest
return [
'id' => $this->id,
'locale' => $request->locale()
];
}
}
JSON资源
class ApiMiddleware
{
...
public function handle($request, $next)
{
$request = app()->instance('request', ApiRequest::createFrom($request));
return $next($request);
}
}
class SomeResource extends JsonResource
{
public function toArray($request)
{
// $request is now instanceof ApiRequest
return [
'id' => $this->id,
'locale' => $request->locale()
];
}
}
您如何通过API资源传递请求?用这些代码更新你的答案。我在控制器中使用它:返回新的SomeResource(User::find(2)),laravel自动获取它。我不想每次在控制器中获取请求头,所以我想用某种方式对其进行泛化。你可以将该逻辑放在中间件中,这只是一个示例。我的观点是,您不应该在API资源中使用请求。请记住,该类将应用于每个模型实例(如果您使用静态选项传递对象集合:
SomeResource::collection($models);
),因此在我看来效率不是很高。请参阅我的解决方案below@SomeDev见我上面的评论:v。再说一次,这只是一个建议,请牢记在心。