我正在使用Laravel创建一个JSON REST API,到目前为止它已经存在。但是我需要用一些由metaDataController
(或者可能是模型)创建的元状态JSON来包装我的JSON输出,我很好奇这是一个很好的方法。
例如,所有回复都采用以下格式:
{
"meta": {
"status": 200,
"notifications": 2
},
"response": {
//JSON from the route's Controller/Model/etc
}
}
据我所知,我要么需要修改Laravel Response
默认值并委托给metaDataController,要么创建某种Route::any
来合并{{3}中提到的JSON的两个部分。 }}。虽然我总是知道metaDataController,但另一个控制器根据路径不断变化。
我认为必须有一种方法可以将此结构声明为所有路由或Route :: group的默认值。
谢谢!
答案 0 :(得分:2)
我不认为做json_decode-> json_encode循环是一个可接受的解决方案(如Chris回答)。
这是另一种解决方案
use Illuminate\Http\Response;
use Illuminate\Http\Request;
Route::filter('apisuccess', function($route, Request $request, Response $response = null) {
$response->setContent(json_encode([
'data' => $response->original,
'meta' => ['somedata': 'value']
]));
});
然后我会将此过滤器附加到我的REST API路由。
编辑:另一种解决方案(更复杂)。
use Illuminate\Http\Response;
class ApiResponse extends Response
{
protected $meta;
protected $data;
public function __construct($content = '', $status = 200, $headers = array())
{
parent::__construct([], $status, $headers);
$this->meta = [];
}
public function withMeta($property, $value = null)
{
if (is_array($property))
$this->meta = $property;
else
array_set($this->meta, $property, $value);
return $this;
}
public function withData($data)
{
$this->data = $data;
return $this;
}
public function sendContent()
{
echo json_encode(['success' => true, 'data' => $this->data, 'meta' => $this->meta, 'echo' => ob_get_contents()]);
}
}
将其作为IOC容器中的单例:
$this->app->bindShared('ApiResponse', function() {
return new \Truinject\Http\ApiResponse();
});
最后,创建过滤器并将其用作"之前"在你的路线上:
Route::filter('apiprepare', function(Illuminate\Routing\Route $route, Illuminate\Http\Request $request) {
$data = $route->run();
return App::make('ApiResponse')->withData($data);
});
因此我们基本上覆盖了我们自己的默认响应类,但仍然使用$ route-> run()调用适当的控制器来获取数据。
要设置元数据,请在控制器中执行以下操作:
\App::make('ApiResponse')->withMeta($property, $value);
我添加了方法" meta"在我的基本API控制器类中,它封装了这个。
答案 1 :(得分:0)
您可以使用app.php
中的全局后置过滤器来捕获所有回复,然后根据需要重新配置它:
App::after(function($request, $response)
{
if(is_a($response, 'Illuminate\Http\JsonResponse')) {
$response->setContent(json_encode(array(
'data' => json_decode($response->getContent()),
'foo' => 'bar',
'cat' => 'dog'
)));
}
});
在上面的示例中,您将获取所有现有的json数据并将其放入子数据元素(在您的示例中这将是“响应”),然后添加foo和bar。所以foo,bar和data将是顶级json对象。
如果你不喜欢全球定位,after
是一个发送的事件,所以你也可以在控制器/其他地方听它。