根据客户端发送HTML或JSON响应

Joh*_*pit 4 php rest laravel laravel-5

我有一个包含Eloquent实体及其各自的RESTful资源控制器的Laravel应用程序,如下所示:

该模型

class Entity extends Eloquent {
    ...
}
Run Code Online (Sandbox Code Playgroud)

控制器

class EntityContoller {

    public function index() {
        Entity $entities = Entity::all();
        return view('entity.index', compact($entities));
    }

    ... // And many more routes like that
}
Run Code Online (Sandbox Code Playgroud)

现在,我正在构建一个android应用程序,而不是返回视图,我需要将数据作为JSON。

在当前解决方案中,对于我从Android应用程序发出的每个请求,我都会添加get query参数contentType=JSON。我在控制器中检测到该错误,并相应地发送数据,如下所示。但这似乎很乏味,我必须在所有地方都写相同的条件。

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
}
Run Code Online (Sandbox Code Playgroud)

我不必在每个控制器动作中都写此条件的最佳方式是什么?

Bro*_*ary 5

如果你不想改变你的控制器,那么你可以使用一个中间件是改变响应后,它从控制器返回。

中间件将从控制器接收响应,进行检查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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以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,
];
Run Code Online (Sandbox Code Playgroud)

然后,您只需将中间件分配给可能返回JSON的路由。

Route::get('user/{user_id}', ['middleware' => 'json', 'uses' => 'App\UserController@getUser']);
Run Code Online (Sandbox Code Playgroud)

你可以阅读更多关于中间件这里和注册和分配中间件这里

您可以在此处阅读有关在Laravel中发送JSON响应的信息