Send HTML or JSON response depending on client

I have a Laravel application with worms and their respective RESTful resource controllers , for example:

Model

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
}

Now I am creating an Android application, and instead of returning the views, I need the data as JSON.

In my current solution, for each request that I make from my Android application, I add a request request parameter contentType=JSON. I detect this in the controller and send the data accordingly as follows. But that seems tedious, and I have to write the same condition everywhere.

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
}

How can I do this without writing this condition to every controller action?

+4
3

, 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']);

, .

JSON Laravel .

+4

? . :

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() type-hint, Laravel 5 docs

+1

BaseController createView

class BaseController extends Controller
{
    protected function createView($object)
    {
        if (Request::get('contentType', 'JSON')) return $object;
        return view('entity.index', compact($object));
    }
}

class EntityController extends BaseController
{
    public function index()
    {
        $entities = Entity::all()
        return $this->createView($entites);
    }

    public function get($id)
    {
        $entity = Entity::find($id);
        return $this->createView($entity);
    }
}

- , , .

0
source

Source: https://habr.com/ru/post/1605810/


All Articles