Larvel:如何避免内部api调用中的json
Laravel 4:在使用您自己的api的上下文中,我的XyzController使用我的自定义InternalApispatcher类创建一个请求对象,将其推送到堆栈(per)上,然后调度路由:Larvel:如何避免内部api调用中的json,api,request,format,laravel-4,response,Api,Request,Format,Laravel 4,Response,Laravel 4:在使用您自己的api的上下文中,我的XyzController使用我的自定义InternalApispatcher类创建一个请求对象,将其推送到堆栈(per)上,然后调度路由: class InternalApiDispatcher { // ... public function dispatch($resource, $method) { $this->request = \Request::create($this->apiBaseUrl . '/
class InternalApiDispatcher {
// ...
public function dispatch($resource, $method)
{
$this->request = \Request::create($this->apiBaseUrl . '/' . $resource, $method);
$this->addRequestToStack($this->request);
return \Route::dispatch($this->request);
}
首先,我正在为一个集合开发一个基本的GET,并且希望响应内容的格式是一个雄辩的模型,或者任何准备好传递给视图的格式(可能是一个存储库之类的东西,稍后我会更高级)。让框架创建一个json响应,然后将其解码回其他内容以在视图中显示,这似乎效率低下。什么是一种简单/高效/优雅的方式来引导请求以我希望的格式返回响应,无论我在代码中的什么位置
另外,我已经看了很多,虽然我在BaseController中处理查询字符串的东西(多亏了),但这一切似乎变得太复杂了,我觉得我在树中迷失了方向
编辑:以下内容是否相关(来源)
通过在控制器上指定layout属性,指定的视图将为您创建,并且将是从操作返回的假定响应
如果您愿意,可以随意将其标记为OT,但我建议您可以从不同的角度重新考虑您的问题 如果您正在“使用您自己的API”,它是通过HTTP交付的,那么您应该坚持使用这种方法 尽管这看起来很奇怪,但好处是您可以将应用程序的这一部分完全替换为其他服务器。你可以在不同的盒子上运行应用程序的不同部分,你可以完全重写HTTP部分,等等。所有这些都是“网络规模”的好处 您要走的路线是连接发布者和订阅者。现在,因为他们都是你,或者更准确地说是你的单一应用,这不一定是件坏事。但是,如果您希望能够访问自己的“东西”,而不必求助于HTTP(或者至少是类似HTTP的)请求,那么我就不会费心伪造它。您最好定义一个不同的内部非web服务API,并调用它 该服务可能是“WebAPI”的基础,事实上,整个HTTP部分可能是核心服务之上相当薄的控制器层
它离您现在的位置不到一百万英里远,但与其使用用于输出HTTP请求的东西并将其弄脏,不如制作一些可以输出对象的东西,并将其包装为HTTP。以下是我如何解决这个问题的,这样就不会对我的API的内部请求进行json编码或解码。此解决方案还演示了在API层上使用路由模型绑定,以及API层使用存储库。这一切对我来说都很好 路线:
Route::get('user/{id}/thing', array(
'uses' => 'path\to\Namespace\UserController@thing',
'as' => 'user.thing'));
//...
Route::group(['prefix' => 'api/v1'], function()
{
Route::model('thing', 'Namespace\Thing');
Route::model('user', 'Namespace\User');
Route::get('user/{user}/thing', [
'uses' => 'path\to\api\Namespace\UserController@thing',
'as' => 'api.user.thing']);
//...
控制器:
UI: UserController@thing
public function thing()
{
$data = $this->dispatcher->dispatch('GET', “api/v1/user/1/thing”)
->getOriginalContent(); // dispatcher also sets config flag...
// use $data in a view;
}
API:UserController@thing
public function thing($user)
{
$rspns = $this->repo->thing($user);
if ($this->isInternalCall()) { // refs config flag
return $rspns;
}
return Response::json([
'error' => false,
'thing' => $rspns->toArray()
], 200);
回购:
下面是我如何在Laravel 5.1中实现它的。它需要对控制器进行一些基本的更改才能工作 不要使用
return response()->make($data)
输出响应,而是执行return$data
这允许使用App::make('apicontroller')->methodname()
从其他控制器调用控制器方法。返回的是对象/数组,而不是JSON
要处理外部API,现有路由保持不变。您可能需要一个中间件来对响应进行一些处理。下面是一个基本示例,其中camel对JSON的键名进行了装箱
<?php
namespace App\Http\Middleware;
use Closure;
class ResponseFormer
{
public function handle($request, Closure $next)
{
$response = $next($request);
if($response->headers->get('content-type') == 'application/json')
{
if (is_array($response->original)) {
$response->setContent(camelCaseKeys($response->original));
}
else if (is_object($response->original)) {
//laravel orm returns objects, it is a huge time saver to handle the case here
$response->setContent(camelCaseKeys($response->original->toArray()));
}
}
return $response;
}
}
这就是我所需要的那种全局性的帮助。虽然我用配置标志解决了我最初的问题,但总体结构似乎是错误的。但我看看我现在有没有。app dir中的ctrlr、模型、视图等将管理我的app的UI,它仍然可以有RESTful URL,这些ctrlr可以调用内部服务api,它将有匹配的RESTful URL,并且可以作为单独web api的基础。但现在我发现自己身处一片名称空间的灌木丛中。你能给我一个合适的目录结构的草图吗?谢谢
<?php
namespace App\Http\Middleware;
use Closure;
class ResponseFormer
{
public function handle($request, Closure $next)
{
$response = $next($request);
if($response->headers->get('content-type') == 'application/json')
{
if (is_array($response->original)) {
$response->setContent(camelCaseKeys($response->original));
}
else if (is_object($response->original)) {
//laravel orm returns objects, it is a huge time saver to handle the case here
$response->setContent(camelCaseKeys($response->original->toArray()));
}
}
return $response;
}
}