我有一个 Laravel 应用程序,其中包含 Eloquent 实体及其各自的 RESTful resource controllers ,如下所示:
模型
class Entity extends Eloquent {
...
}
Controller
class EntityContoller {
public function index() {
Entity $entities = Entity::all();
return view('entity.index', compact($entities));
}
... // And many more routes like that
}
现在我正在构建一个 android 应用程序,而不是返回 View ,我需要数据作为 JSON。
在我当前的解决方案中,对于我从我的 Android 应用程序发出的每个请求,我添加一个获取查询参数 contentType=JSON
。我在 Controller 中检测到它,并像下面这样相应地发送数据。但这看起来很乏味,我必须到处写相同的条件。
class EntityContoller {
public function index() {
Entity $entities = Entity::all();
if(Request::get('contentType', 'JSON')) return $entities;
return view('entity.index', compact($entities));
}
... // And many more routes like that
}
无需在每个 Controller 操作中都写入此条件,我可以执行此操作的最佳方法是什么?
最佳答案
如果你不想改变你的 Controller ,那么你可以使用 middleware从 Controller 返回之后改变响应。
中间件将从 Controller 接收响应,检查 contentType == JSON
,然后返回正确的响应。
中间件看起来像这样:
use Closure;
class JsonMiddleware {
public function handle($request, Closure $next) {
// Get the response from the controller
$response = $next($request);
// Return JSON if necessary
if ($request->input('contentType') == 'JSON') {
// If you want to return some specific JSON response
// when there are errors, do that here.
// If response is a view, extract the data and return it as JSON
if (is_a($response, \Illuminate\View\View::class)) {
return response()->json($response->getData());
}
}
return $response;
}
}
然后,您可以通过将中间件附加到 $routeMiddleware
数组来在 app/Http/Kernel.php
中注册该中间件。
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
// New Middleware
'json' => \App\Http\Middleware\JsonMiddleware::class,
];
然后您只需将中间件分配给可能返回 JSON 的路由。
Route::get('user/{user_id}', ['middleware' => 'json', 'uses' => 'App\UserController@getUser']);
您可以阅读有关中间件的更多信息 here以及注册和分配中间件 here .
您可以阅读有关在 Laravel 中发送 JSON 响应的信息 here .
关于php - 根据客户端发送 HTML 或 JSON 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32383038/