2

I have such a route in my routes/web.php

Route::resource('/api/surveys', 'SurveyController');

As documentation says, it creates all needed routes for API. This is a function, that gets executed when I go for /api/surveys route:

public function index()
{

    $request = request();

    if(!$request->hasHeader('token')) {

        return "No auth token found.";
    }

    $tokenCheck = $this->userService->isTokenValid($request->header('token'));

    if($tokenCheck !== true) {

        return $tokenCheck;

    }

    return $this->surveyService->all();
}

What it does, it checks if token header parameter is set, if not, it returns an error, if yes, it checks if token is valid and etc. if everything is OK, it should return surveys from database.

public function surveys() {

    $request = \Request::create('/api/surveys', 'GET');
    $request->headers->set('Accept', 'application/json');
    $request->headers->set('token', \Cookie::get('token'));
    $response = \Route::dispatch($request);

    print_r('<pre>');
    print_r($response);
    print_r('</pre>');

}

I have a website, that should use that API I just created to get all survey records. I create a new request object, set header "token" with token I get from a cookie and then try to dispatch and get a response. But the problem is that everytime I get "No auth token found." error. That means $request->hasHeader('token') returns false, even tough I set it here in my request. If I print_r $request->all() in Restful controller, I get an empty array.

I tried Postman to access this API with token parameter, and it works fine in postman, but here, it seems that Request disappears while it travels to API controller.

What I did wrong here?

cinik11
  • 65
  • 1
  • 6

1 Answers1

2

When you manually create a request and dispatch it, that works to get the routing to call the correct controller, however that does not affect the request that is bound in the container.

When your "fake" request is handled by the api controller, the request that it pulls out of the container is the original "real" request that was made by the user.

Instead of dispatching the route with your new request, you will need to app()->handle($request) the new request. This, however, will completely replace the original "real" request with your new "fake" request, so everything from the original request will be lost.

Having said all that, this method of consuming your own api is discouraged, even by Taylor. You can read his comment on this Github issue. So, consuming your own api like this may work, but you may also run into some other unforeseen issues.

The more appropriate solution would be to extract out the logic called by the api routes to another class, and then call that extracted logic from both your api routes and your web routes.

patricus
  • 59,488
  • 15
  • 143
  • 145
  • Can you give me some more information about that appropriate solution? Thanks. – cinik11 Sep 24 '17 at 09:25
  • He basically means copy the logic from inside your controller to a random function in a service or something, and then call that service function. And forget about simulating a request – Joe Yahchouchi May 04 '21 at 18:09