我不认为执行 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);
我在我的基础 API 控制器类中添加了方法“meta”,它封装了这个。