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

Rack 3 support #277

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open

Rack 3 support #277

wants to merge 7 commits into from

Conversation

kyleplump
Copy link

@kyleplump kyleplump commented Dec 31, 2024

multiple gems are impacted and updated by this change. this gem is the most significantly changed. i'll link to the open PR's of the affected gems below. please let me know if you'd like to see any changes, thanks!

highlights

changelog for Rack 3: https://github.com/rack/rack/blob/main/UPGRADE-GUIDE.md

impacted gems

@cllns
Copy link
Member

cllns commented Dec 31, 2024

Excellent! Thanks so much for doing this. It'll be a huge win when we can make a release that supports Rack 3.

Looks like there are some Rubocop errors, can you fix those?

I have a few questions (for you and others):

  • Do we want to require rack 3 or simply support it, if people want to upgrade themselves?
    • If we require rack 3, then we should add support for people who have mixed-cased headers, so it's not a breaking change. It seems like Rack::Headers does this.
    • If we don't require rack 3, then we might have to add conditionals based on rack version. Hopefully we can avoid this or at least minimize it.
  • Do we need our input to be rewindable with Rack::RewindableInput::Middleware at all? What if we just consume the headers / form data as part of our parsing, add it to the env/params, then never need to rewind? Is that an option? I guess it's more performant.
  • Similarly, for Content-Length, do we want add Rack::ContentLength middleware to all hanami-router apps, by default?
  • Along those lines, if we need rewindable input for normal non-streaming HTTP data, then can we let people opt out so they can use Rack 3's streaming support? This could definitely be a separate PR that comes later.

@kyleplump
Copy link
Author

thanks for checking this out @cllns !

fixed the rubocop offenses

  • this is an excellent point. i feel as though the better DX would be to support and not require rack 3. the number of code changes isn't so significant that i think we can get away with only a few conditionals, though I'll defer to your judgement here
  • i'm not sure we need rewindable inputs. i think your suggestion of putting it into the env/params would certainly work (and already has some precedent, re: Router#_params). I kept the rewindable input just to match what was already there, but would be happy to do away with it if we want to avoid bringing in another middleware
  • i think having the Rack::ContentLength middleware is a great idea, and can add this in
  • another excellent point. I'd love to provide more 'rack 3+ specific' features, and will definitely start thinking about how to include that into the existing gem. including them here, or in a separate PR, i'll once again defer to your excellent judgement 😄

@cllns
Copy link
Member

cllns commented Jan 1, 2025

  • this is an excellent point. i feel as though the better DX would be to support and not require rack 3. the number of code changes isn't so significant that i think we can get away with only a few conditionals, though I'll defer to your judgement here

Sweet! If it's possible, I think that would be best, so we can keep this a minor version release.

We'll have to add rack-version to our CI matrix, but that's not a problem. It makes sense for a router.

Now that I think about it, even if Rack 3 is optional, we don't want users who are setting mixed-case headers to break their apps, so we should use Rack::Headers regardless.

  • i'm not sure we need rewindable inputs. i think your suggestion of putting it into the env/params would certainly work (and already has some precedent, re: Router#_params). I kept the rewindable input just to match what was already there, but would be happy to do away with it if we want to avoid bringing in another middleware

Outside of whether we need it, I feel like there might be reasons we want rewindable input... I guess it's more performant to keep the same input & rewind it instead of copying everything we need over. Plus users may be rewinding already (e.g. in middleware) and we don't want that to break.

Curious how others feel about this. I think it might make sense to use rewindable input by default for Rack 3 (maybe based on content type?) but hopefully there's a way to automatically allow non-rewindable inputs as well, for streams. If it can't be automatic then we should try to make it simple to opt-out of rewindable inputs.

I wish I knew more about Rack. I've read the UPGRADE_GUIDE, and started 'watching' the repo a couple weeks ago, so hopefully I can get a better grasp on it.

  • i think having the Rack::ContentLength middleware is a great idea, and can add this in

Looking into it, the Rack::ContentLength middleware only applies to responses that don't have the header already set. What if we just set it in hanami/hanami and leave it out of the router? Then we can document how users can add it. This keeps the router as small and flexible as possible. I think it's probably better to set it ourselves in the framework than rely on the middleware (which seems like more of a fallback).

  • another excellent point. I'd love to provide more 'rack 3+ specific' features, and will definitely start thinking about how to include that into the existing gem. including them here, or in a separate PR, i'll once again defer to your excellent judgement 😄

This is already a big change (across several repos, thank you!), so I think it'd be wise to keep the scope of this as small as we can. Then we can work on Rack 3+ features, and ship those independently.

So I think at this point:

  • Relax requirement to Rack > 2
  • Add testing Rack 2 and Rack 3 to CI matrix for this gem (and hanami/hanami?)
  • Make sure we support both, using RewindableInput
  • Un-do the changes for updating the specs to lowercase headers, to ensure we don't break people using mixed case headers.

Then we can get these merged, and work on non-rewindable inputs in separate PR's. We could ship rewindable-only Rack 3 support or wait until we actually support non-rewindable input to ship a new versions of the gems.

Curious to get @timriley's feedback :)

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.

2 participants