Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internal requests not nestable #1164

Open
zmorris opened this issue Aug 24, 2016 · 2 comments
Open

Internal requests not nestable #1164

zmorris opened this issue Aug 24, 2016 · 2 comments

Comments

@zmorris
Copy link

zmorris commented Aug 24, 2016

I have some routes that call themselves, based on:

https://github.com/dingo/api/wiki/Internal-Requests

I have a notion of users, me and global scope where the various levels infer the current user. But I don't want to have copies of similar code in my controllers. Here is some pseudo code of what I'm trying to accomplish:

$api->addRoute(['POST'], 'users/{users}/objects', ['as' => 'api.users.objects.store', 'uses' => function ($userId) {
    // process request here
}]);

$api->addRoute(['POST'], 'me/objects', ['as' => 'api.me.objects.store', 'uses' => function () {
    return app('Dingo\Api\Dispatcher')->raw()->post("/api/users/" . \Auth::user()->id . "/objects");
}]);

$api->addRoute(['POST'], 'objects', ['as' => 'api.objects.store', 'uses' => function () {
    // works:
    return app('Dingo\Api\Dispatcher')->raw()->post("/api/users/" . \Auth::user()->id . "/objects");

    // fails due to app('Dingo\Api\Dispatcher')::raw getting reset to false:
    //return app('Dingo\Api\Dispatcher')->raw()->post("/api/me/objects");
}]);

The issue is that if I nest the app('Dingo\Api\Dispatcher')->raw()->post() calls by internally calling /api/abject -> /api/me/objects -> /api/users/{users}/objects then the middle call causes app('Dingo\Api\Dispatcher')::raw to get reset to false. Then the outermost call returns an object rather than a Response.

I tracked the issue down to Dispatcher.php's refreshRequestStack()'s $this->raw = false; which resets the value. I believe this is due to Dingo\Api\Dispatcher being a singleton. So the dispatcher needs to push its state before queuing each request and pop its state after finishing each request.

I can work around it for now by never nesting internal requests but it's not as elegant as it could be. Thanks for the hard work on Dingo, just thought you'd like to know.

@hskrasek
Copy link
Member

Just to make sure I understand this correctly, you have endpoints A, B, and C. You're calling endpoint A, which internally makes a request to B, which then makes and internal request to C?

@zmorris
Copy link
Author

zmorris commented Apr 5, 2018

Apologies for my late reply on this, I just discovered https://github.com/issues hahaha. Ya raw requests work fine, but not when they're nested. So in your example A->raw(B->raw(C)), the B->raw(C) works fine. But the A->raw(...) fails because it's nested.

The dispatcher needs to push its state and then pop it rather than explicitly performing $this->raw = false;. Otherwise the nested raw calls get their raw boolean set to false when they should actually be true since they're inside another raw call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants