Skip to content

[5.3] Implement route binding substitution using a middleware #13548

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

Merged
merged 1 commit into from
May 25, 2016

Conversation

GrahamCampbell
Copy link
Member

@GrahamCampbell GrahamCampbell commented May 13, 2016

Not only is this really elegant, but it also allows massive flexibility on when and how these bindings take place. It's a relatively common use case for people to want to run middlewares before the bindings take place for various reasons such as ACL, throttling, or whatever.

There is however a very minor upgrading requirement that people now need to register this new middleware.

@phroggyy
Copy link
Contributor

I definitely support this one. Having recently experienced an issue with wanting to go through another middleware before binding (because my binding relied on the existence of the session), I definitely think this would be a great addition, which should also be no larger upgrade step than the move to the web middleware was. Well done @GrahamCampbell 👏

@GrahamCampbell
Copy link
Member Author

Another use case I have for this is if an ID scheme has changed, and we need to redirect old URIs to the new scheme, we'd want to do this before the binding throws an exception and we end up with a 404 page. Alternatively, we may want to just transform the ID to the new scheme internally, and then continue to the route binding as if nothing had happened.

@JosephSilber
Copy link
Contributor

JosephSilber commented May 25, 2016

Just to make sure I understand this correctly:

Let's say your bindings need auth to have run first. You'll have to remove the bindings middleware from the global web group, and add it everywhere you need it as a route middleware (after the auth one)?

I think that can get a little messy, no?

@GrahamCampbell
Copy link
Member Author

GrahamCampbell commented May 25, 2016

I think that can get a little messy, no?

Better than nothing. The main use case I see isn't for custom binding middleware per route, it's just to overwrite the whole thing a single time. That way, there is no mess.

@taylorotwell
Copy link
Member

taylorotwell commented May 25, 2016

@JosephSilber note the order of when bindings / auth happen is the same before / after this change.

@taylorotwell taylorotwell merged commit 42b20c3 into master May 25, 2016
@GrahamCampbell GrahamCampbell deleted the bindings branch May 25, 2016 14:25
@mikemand
Copy link
Contributor

mikemand commented Jun 4, 2016

For those wishing this was in 5.2 as well:

  • Fork the framework.
  • Check out the 5.2.35 tag (or whichever version you are currently using, I've done it with .35 though and do not know if it will work with older versions).
  • Make a new branch, so you can keep receiving updates on the 5.2 branch. (I didn't do this, like a dummy, and now I have to go back through and do so.
  • On your new branch: git cherry-pick 42b20c3
  • Fix the merge conflicts with the tests. They are mostly whitespace, but the new middleware was also added to the tests.
  • Commit and push up to your fork. (Optionally: tag your branch somewhere within the 5.2.* release line, but make sure it won't conflict with future releases. I used 5.2.35.1 since I was working with 5.2.35 already.)
  • Add the following to your composer.json:
"repositories": [
    {
        "type": "vcs",
        "url": "https://github.com/<yourusername>/framework"
    }
],
  • If you didn't tag your branch within the 5.2.* releases then you'll have to change your required version of laravel/framework to dev-<yourbranch>. Otherwise, skip this step.
  • composer update
  • Add the new middleware (\Illuminate\Routing\Middleware\SubstituteBindings::class) to your middleware groups. I put it in the web group, but if you use bindings in your APIs and/or don't use the web group, add it to whichever group you are using.

@GrahamCampbell
Copy link
Member Author

Not something I'd actually recommend @mikemand.

@GrahamCampbell
Copy link
Member Author

If you want this in 5.2, I'd actually recommend extending the classes in your code, not forking the framework. Always avoid forking stuff to load as dependencies at all costs.

@GrahamCampbell
Copy link
Member Author

Or, just upgrade to L5.3. It's not too bad, but beware the docs are not done, and we could break more stuff, so you'd need to keep a close watch on this repo for a few more weeks.

@mikemand
Copy link
Contributor

mikemand commented Jun 4, 2016

If you want this in 5.2, I'd actually recommend extending the classes in your code, not forking the framework. Always avoid forking stuff to load as dependencies at all costs.

How would you go about extending the Router and changing visibility of the methods from protected to public? I thought that was not possible with PHP?

Or, just upgrade to L5.3. It's not too bad, but beware the docs are not done, and we could break more stuff, so you'd need to keep a close watch on this repo for a few more weeks.

Exactly why I'm not updating just yet.

@GrahamCampbell
Copy link
Member Author

How would you go about extending the Router and changing visibility of the methods from protected to public? I thought that was not possible with PHP?

Is possible. Note that you'd have to extend the application class too.

@GrahamCampbell
Copy link
Member Author

I moved my apps over to 5.3 purely to so I could delete our custom code like this. I've had this middleware in my apps for months. Only moving it to the core now.

@hipsterjazzbo
Copy link

I may just be stupid, but this change seems to have broken the ability to test routes that use model binding: #16260

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

Successfully merging this pull request may close these issues.

6 participants