我有一个带有Eloquent实体的Laravel应用程序及其各自的RESTful resource controllers,如下所示:
x
class Entity extends Eloquent {
...
}
现在我正在构建一个Android应用程序,而不是返回视图,我需要数据作为JSON。
在我目前的解决方案中,对于我从Android应用程序发出的每个请求,我都添加了一个获取查询参数class EntityContoller {
public function index() {
Entity $entities = Entity::all();
return view('entity.index', compact($entities));
}
... // And many more routes like that
}
。我在控制器中检测到,并按如下方式相应地发送数据。但这似乎很乏味,我必须在任何地方写出相同的条件。
contentType=JSON
我可以做到这一点的最佳方式是什么,而不必在每个控制器操作中都写出这个条件?
答案 0 :(得分:5)
如果您不想更改控制器,那么您可以使用middleware来改变之后的响应 从控制器返回。
中间件会收到控制器的响应,检查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;
}
}
然后,您可以在app/Http/Kernel.php
中注册中间件,方法是将其附加到$routeMiddleware
数组。
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 here中发送JSON响应的信息。
答案 1 :(得分:1)
自定义响应类怎么样?让我给你一个想法。创建一个新的类或服务:
class ResourceResponse{
public function __construct($request, $object, $view = null){
// setting values
}
public function __toString(){
if ($this->request->get('contentType') == 'JSON'){
return $this->object;
}
// view as fallback
return view($this->view, compact($this->object));
}
}
然后在您的资源中,如果未指定json类型,则只需使用视图名称作为后备调用函数:
public function index(Request $request) {
$entities = Entity::all();
return new ResourceResponse($request, $entities, 'entity.index');
}
如果您非常确定响应应该是JSON格式,那么您可以忘记视图名称:
public function index(Request $request) {
$entities = Entity::all();
return new ResourceResponse($request, $entities);
}
$request
方法的中所述的类型提示
index()
参数使用Laravel 5's docs
答案 2 :(得分:0)
首先使用受保护的函数createView
创建BaseControllerSelect * FROM grids
WHERE g_date_created + interval 3 day BETWEEN timestamp_1 AND timestamp_2
然后在每个控制器中扩展此基本控制器
class BaseController extends Controller
{
protected function createView($object)
{
if (Request::get('contentType', 'JSON')) return $object;
return view('entity.index', compact($object));
}
}
如果还有其他任何异常,例如多个对象或错误,则无法单独处理它。