我正在开发一个Laravel 4应用程序,它将通过JSON REST API和Web UI对我的数据集进行相同的CRUD操作 . 似乎是为了防止破坏DRY原则,我的UI应该使用我自己的API,将所有请求从UI路由回API . 我不确定这项工作的最佳方法 . 据推测,我会有单独的UI和API控制器,并以某种方式路由请求 . 或者我应该完全看一个不同的方法?
谢谢 .
如果您正在使用自己的API,请使用 app()->handle() 而不是 Route::dispatch() ,正如Derek MacDonald建议的那样 .
app()->handle()
Route::dispatch()
app()->handle() 创建一个新请求,而 Route::dispatch() 在堆栈中运行路由,实际上忽略了作为您发送的请求的一部分的参数 .
Edit :只是单挑 . 泰勒奥特威尔advises against using sub-requests to make internal API calls, as they mess the current route . 您可以使用像 Guzzle 这样的HTTP API客户端来进行API调用 .
Guzzle
NOTE: As vcardillo pointed out below, route filters are not called with these methods.
我目前正在做同样的事情,杰森的回答让我朝着一个伟大的方向前进 . 查看Symfony\Component\HttpFoundation\Request文档,我想出了如何POST以及我使用表单的其他所有内容,以下是一些可以帮助您的代码:
得到:
$request = Request::create('/api/users/1', 'GET'); $response = Route::dispatch($request);
POST:
$request = Request::create('/api/users/1', 'POST', Input::get()); $response = Route::dispatch($request);
POST w / cookies
$request = Request::create('/api/users/1', 'POST', Input::get(), Cookie::get('name')); $response = Route::dispatch($request);
POST带文件
$request = Request::create('/api/users/1', 'POST', Input::get(), null, Input::file('file')); $response = Route::dispatch($request);
我希望这有助于其他人 . 如果您没有使用表单,或者您没有使用Laravel的输入/ Cookie外观,请将输入/ Cookie外观替换为您自己的内容 .
你可以使用Optimus API consumer,API干净简单,例如发出内部请求:
$response = app()->make('apiconsumer')->post('/oauth/token', $data);
在它的核心,它使用 Illuminate\Routing\Router 和 Illuminate\Http\Request 进行调用
Illuminate\Routing\Router
Illuminate\Http\Request
// create the request $this->request->create($uri, $method, $data, [], [], $server, $content); // get the response $response = $this->router->prepareResponse($request, $this->app->handle($request));
Taylor Otwell suggested使用 app()->handle() 而不是 Route::dispatch() 来实现干净的请求 .
对于 Route::dispatch($request) ,我注意到您的非GET请求的 endpoints (HTTP请求主体上的参数)是否使用了依赖注入 \Illuminate\Http\Request 或 \Illuminate\Foundation\Http\FormRequest 扩展实例,参数状态,cookie,文件等来自原始HTTP请求 . 即,对于您的应用程序的控制器操作方法 .
Route::dispatch($request)
\Illuminate\Http\Request
\Illuminate\Foundation\Http\FormRequest
如果您的app控制器和API控制器的参数名称和post方法类型相同,则您赢得了't notice the difference since the original parameter values are passed on. But when you' re手动组装 Request::create() 的第3个参数, Route::dispatch() 将导致它被忽略 .
Request::create()
app()->handle() 修复了Laravel请求生命周期中的上下文问题 .
Caveat: app()->handle() 影响 Illuminate\Support\Facades\Request ,使用此新请求实例刷新它 . 作为连锁效应,在 app()->handle() 之后调用 Request::isXmlHttpRequest() 或 redirect()->back() 之类的调用将导致不可预测的行为 . 我建议您跟踪原始请求的上下文,而是使用 redirect()->to(route('...')) ,以便严格控制应用的流量和状态 .
Illuminate\Support\Facades\Request
Request::isXmlHttpRequest()
redirect()->back()
redirect()->to(route('...'))
考虑到所有这些极端情况,最好只使用Guzzle HTTP client进行手动卷曲 .
如果您正在寻找内部使用护照登录api,那么您需要将参数添加到原始请求:
protected function manualLogin(Request $request) { $email = $request->input('email'); $password = $request->input('password'); $request->request->add([ 'username' => $email, 'password' => $password, 'grant_type' => 'password', 'client_id' => $clientID, 'client_secret' => $clientSecret, 'scope' => '*']); $newRequest = Request::create('/oauth/token', 'post'); return Route::dispatch($newRequest)->getContent(); }
我实际上是在修补同样的想法,它非常整洁 . 使用Laravel,您确实能够发出内部请求(有些人可能会将其称为HMVC,但我不会这样做) . 这是内部请求的基础知识 .
$response 现在将包含API的返回响应 . 通常,这将返回一个JSON编码的字符串,这对客户端很有用,但对于内部API请求来说并不是那么好 . 你必须在这里扩展一些东西,但基本上我们的想法是返回内部调用的实际对象,并且外部请求返回格式化的JSON响应 . 你可以在这里使用像_438714这样的东西 .
$response
您应该看到的是构建某种内部 Dispatcher ,它允许您分派API请求并返回原始对象 . 调度程序还应处理格式错误的请求或错误的响应,并抛出异常以匹配 .
Dispatcher
这个想法本身很扎实 . 但规划API是一项艰苦的工作 . 我建议你写一个包含所有预期 endpoints 的好列表,然后选择几个API版本,然后选择最好的 endpoints .
7 回答
如果您正在使用自己的API,请使用
app()->handle()
而不是Route::dispatch()
,正如Derek MacDonald建议的那样 .app()->handle()
创建一个新请求,而Route::dispatch()
在堆栈中运行路由,实际上忽略了作为您发送的请求的一部分的参数 .Edit :只是单挑 . 泰勒奥特威尔advises against using sub-requests to make internal API calls, as they mess the current route . 您可以使用像
Guzzle
这样的HTTP API客户端来进行API调用 .NOTE: As vcardillo pointed out below, route filters are not called with these methods.
我目前正在做同样的事情,杰森的回答让我朝着一个伟大的方向前进 . 查看Symfony\Component\HttpFoundation\Request文档,我想出了如何POST以及我使用表单的其他所有内容,以下是一些可以帮助您的代码:
得到:
POST:
POST w / cookies
POST带文件
我希望这有助于其他人 . 如果您没有使用表单,或者您没有使用Laravel的输入/ Cookie外观,请将输入/ Cookie外观替换为您自己的内容 .
你可以使用Optimus API consumer,API干净简单,例如发出内部请求:
在它的核心,它使用
Illuminate\Routing\Router
和Illuminate\Http\Request
进行调用Taylor Otwell suggested使用
app()->handle()
而不是Route::dispatch()
来实现干净的请求 .对于
Route::dispatch($request)
,我注意到您的非GET请求的 endpoints (HTTP请求主体上的参数)是否使用了依赖注入\Illuminate\Http\Request
或\Illuminate\Foundation\Http\FormRequest
扩展实例,参数状态,cookie,文件等来自原始HTTP请求 . 即,对于您的应用程序的控制器操作方法 .如果您的app控制器和API控制器的参数名称和post方法类型相同,则您赢得了't notice the difference since the original parameter values are passed on. But when you' re手动组装
Request::create()
的第3个参数,Route::dispatch()
将导致它被忽略 .app()->handle()
修复了Laravel请求生命周期中的上下文问题 .Caveat:
app()->handle()
影响Illuminate\Support\Facades\Request
,使用此新请求实例刷新它 . 作为连锁效应,在app()->handle()
之后调用Request::isXmlHttpRequest()
或redirect()->back()
之类的调用将导致不可预测的行为 . 我建议您跟踪原始请求的上下文,而是使用redirect()->to(route('...'))
,以便严格控制应用的流量和状态 .考虑到所有这些极端情况,最好只使用Guzzle HTTP client进行手动卷曲 .
如果您正在寻找内部使用护照登录api,那么您需要将参数添加到原始请求:
如果您正在寻找内部使用护照登录api,那么您需要将参数添加到原始请求:
我实际上是在修补同样的想法,它非常整洁 . 使用Laravel,您确实能够发出内部请求(有些人可能会将其称为HMVC,但我不会这样做) . 这是内部请求的基础知识 .
$response
现在将包含API的返回响应 . 通常,这将返回一个JSON编码的字符串,这对客户端很有用,但对于内部API请求来说并不是那么好 . 你必须在这里扩展一些东西,但基本上我们的想法是返回内部调用的实际对象,并且外部请求返回格式化的JSON响应 . 你可以在这里使用像_438714这样的东西 .您应该看到的是构建某种内部
Dispatcher
,它允许您分派API请求并返回原始对象 . 调度程序还应处理格式错误的请求或错误的响应,并抛出异常以匹配 .这个想法本身很扎实 . 但规划API是一项艰苦的工作 . 我建议你写一个包含所有预期 endpoints 的好列表,然后选择几个API版本,然后选择最好的 endpoints .