-
-
Notifications
You must be signed in to change notification settings - Fork 102
[fix] Updated to include the new Closure (Laravel 9.x support) #79
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
Conversation
Hi there, thanks for the PR. The codebase can be a rather tricky one with the variety of little workarounds to achieve what is achieved with the package. I welcome any PR's to improve the logic too. Rather than us adding in more exception handles, could you post code to reproduce this error with a fresh Laravel install? That way we can try and narrow it down on whether we need another exclusion here, or if it's a different issue. |
Just need to use a Laravel API resource and a closure in the route function: So create a basic resource (
And then declare the route in your route file:
This closure used in the route used to be handled as an Opis type, and is now the Laravel type of Serializable closure. Probably don't need a resource, to be honest, probably just a function in the route file. |
@almightynassar what Laravel version are you using? I just tried it on a Laravel 8 and 9 project and was unable to reproduce the issue. Did you try this on a brand new, fresh install of Laravel? Route::get('/users', function () {
return new \App\Http\Resources\UserResource(
\App\Models\User::first()
);
})->name('users.index'); |
Also that's weird, since Laravel forked the original Maybe my example didn't trigger the serializable closure part of the route.... I'll go through my stuff a bit more thoroughly to see. Just an example of the error message:
|
@andreaselia would you prefer that I change this to This may be a niche case since most people will use the common Controller method for routing, but the official Laravel docs still mention using Closures in their routes (see here and here). Just FYI, these route closures will be serialized when the routes are cached. It may still "work" if you do not clear you cache when switching Laravel versions. laravel-api-to-postman should not work in Laravel 9.x when using route closures, since |
And just to give extra detail using the code inside of Laravel... Laravel 9.x In There is no reference to Laravel 8.x Actually reviewing the code, it seems that Line 17 imports |
When I get more time, I can do some quick testing by updating |
@almightynassar thanks for the extra information. So long as a test case is added for this that supports the backwards compatibility of the package, I'm happy to roll with that. I have still been unable to reproduce the issue, so if there's a test case that can do that, then I look forward to seeing that too. |
@andreaselia any idea on how to trigger caching of the route data in tests? Your current tests will only check Closures and will never get serialised. So this feature was never checked in the first place. Also, it uses the older version of the orchestra testbench, so it will only pull laravel v8 instead of v9 |
Just renamed this with Laravel 9 in the header so people who are using caching (i.e. you generate In
And then change the entry to:
And you will be using the Laravel 9.x closure libraries instead of the incompatible older ones. The code is backwards compatible (as it still checks the older Opis library that Laravel 8.x uses). |
Alternative @andreaselia If you don't want to support Serialized closures, why not add a route cache clear command at the start of the Export? So just run a Only issue is that the cache is still loaded in memory for the export, so need to clear that too.... but running the command a second time works. I'm probably forgetting something that will clear and reload the routes in memory, but for now my patch fixes the issues when there is a cache file and goes into your Serialized Closure checks. |
I don't have any ideas off the top of my head at the moment, but will try and check this out again in the AM. I'm open to any suggestions regarding the testing setup though, and if anything needs to change to make sure we catch all cases (like updating the testbench) then I'm all for it 👍 |
@almightynassar I think in previous issues where people have mentioned using a closure in their routes, I've simply suggested moving the code to a controller, as I also believe that to be a lot more maintainable than setting a standard of having closures within your routes file. Edit: I'm heading off for the night now, but will check back here tomorrow with a fresh mind and re-read what you've commented. Thanks again for your work on this, it is very much appreciated. |
@andreaselia all good, this is a very niche bug that only happens when you use caching and closures. And only because PHP doesn't have a way to serialize closures natively. Most people won't encounter that in development as they will never generate the cache file in the first place. Another idea would be to catch the Testing is a pain since there is practically no documentation about testing with a route cache generated, other than some cryptic reference on line 304 of |
Apologies for the late reply @almightynassar, I haven't had time or energy today to properly go through this. I'll aim to have gone through this by the end of the week at the latest, and come back with hopefully a better idea of what's going on within this issue (I still do not fully understand it, but I'm pretty tired, so that could be it), and also a direction for the solution. |
It might be worth looking here (https://github.com/orchestral/testbench-core/blob/b1a35c479091ce6e3876971ffa0a4648d96b21f2/src/Concerns/HandlesRoutes.php) to see if you can create cached routes for testing. |
This looks like a good start so that we can replicate things as part of our testing. What do you think @almightynassar? |
Been a bit busy (sorry if I sound terse and rushed, had other projects on the line so did my quick fix and moved on 😅) Definitely interesting, as my biggest roadblock is basically creating the cache file in testing and then running the command (if that cache doesn't exist then you won't get the error) As to my last point about just catching the exception and letting the user know to clear the cache is what caught my mind... most of the time you want to generate the api from the latest route changes, which may not be reflected in the route cache. So clearing the cache might be desirable default behaviour.... only issue is user scripts that might have cached the routes and cruised on the old checks |
Thanks for the update @almightynassar. I think this PR can be merged if you're also happy with that? We can always add a test case for this another time. cc @tomirons |
Before we merge, just wondering what you think of (can spin this into a different topic):
The test itself should be pretty straightforward, just gotta figure out how all the parts fit in the trait file that @tomirons linked... at a glance it does what we need, just gotta get code onto the screen 😅 I'll put any orchestra and dependency update that I get time to do into another PR since that doesn't affect this issue |
Sounds good the me @almightynassar, I don't see any issues with us clearing the route cache. |
…test version so that we can use cached routes during testing
Created a test, but had to update orchestra to successfully use the Once updated the Tests run correctly, then removing the second part of my Serialize check in the Export Command will fail the cached export test as we cannot deserialize correctly (in Laravel 9). I got to move onto another project right now so I'll look at the style guide issues.... also not 100% sure if the Note: Orchestra update means that it will be testing in Laravel 9 and not 8. |
@almightynassar I'm sure there's a way to keep the BC for Laravel 8 as well? @andreaselia we still want to support Laravel 8, right? |
Fantastic work @almightynassar! Your time is greatly appreciated on this, and I'm grateful that you're taking the time to contribute to the package. @tomirons so long as it's not too much of a pain, it would be nice to still support Laravel 8 until at least the official bug fix phase support ends for it in July. I wonder why there were issues with the previous version of the Orchestra package though 🤔 |
@tomirons I'm probably sleep deprived but I'm drawing a blank on BC acronym 😅 @andreaselia For some reason the |
@almightynassar BC = backwards compatible. I haven't thought much on how to resolve this route caching issue, but we could add some version checks within the package and do different logic based on the Laravel version at hand. |
@tomirons oh lol, of course 😅 So the actual change isn't a breaking change, since it checks both Laravel 8 (Opis closure) and Laravel 9 (in-house Laravel closure). So it'll work for either version of Laravel if the routes are cached.
The route caching stuff only comes into play with testing, and that requires the Orchestra Testbench designed on Laravel 9. My quick suggestions on the path forward (@andreaselia):
Just to reiterate, the actual code change (Export command) will work for both Laravel 8 and 9. It's only the tests that are a bit finicky with Laravel versions for some reason |
Went ahead and did the second option.... had an inkling that the error was probably because of my local environment set-up The two test jobs for each laravel version seem to pass; not 100% sure if they are using the corresponding Laravel versions (orchestra v6 => Laravel 8, orchestra v7 => Laravel 9) because the CI command is set to quiet, but at least on my machine composer installs the correct version |
Sorry for the late reply @almightynassar, and thanks for rolling with the 2nd option as I think it's the one I'd have gone with too. This looks good to me, and seems to be passing, so thanks again for all of your time and effort on this. @tomirons are you happy with this too? |
@almightynassar thanks for the contribution on this! |
Similar issue to #31 except instead of
Ops\Closure\SerializableClosure
it'sLaravel\SerializableClosure\SerializableClosure
. Most likely because Laravel 9 uses a new closure system.Probably can get rid of the
!== false
equality because it makes no sense....