crystal
crystal copied to clipboard
Add a `redirect` method to `HTTP::Server::Context`
I write web services in Crystal mostly using the standard library and with the exception of routing, I'm content with the tools it provides. However, one simple thing I find missing is a redirect
method for handling HTTP redirects. Another standard library I like working with is Go, and they provide this function on their http/server
package.
As a solution I end up opening the HTTP::Server::Context
class and adding this method myself. Here are some other common implementations of this method from the ecosystem:
We already have a respond_with_status
method in the response type, so adding a redirect
method which allows setting a URL and a HTTP status would be great.
I should also point out that aside from being a Crystal user, I'm interested in writing tutorials for new users, and not having to define the redirect method explicitly in a "Simple Web Application with Crystal Stdlib" tutorial would be much better.
An implementation is already proposed in #10412.
Looking at #10412 again, I think the documentation may need some polishing.
Perhaps we should also look at the API/supported features and compare it with prior art.
- The Go implementation implicitly expands relative paths. I'm not sure that's really necessary. You can easily achieve that by explicitly calling
URI#resolve
at the call site. - It also writes a short response body for GET requests. This might be useful. However I would wish for some customization options.
- A related question is whether there should be a way to prevent closing the response or injecting a custom body (for example via a yielding overload)?
- The
status
parameter could perhaps support numerical values as well. - The Athena implementation validates the status code. I don't think that should be necessary. And it's potentially harmful because this implementation forbids using this redirect mechanism with
201 Created
, which is a perfectly valid use case for theLocation
header. There may be other applications for status codes outside the "Redirect messages" group which allow this header.
And it's potentially harmful because this implementation forbids using this redirect mechanism with
201 Created
My thinking there was you're explicitly saying it be a redirect, e.g. by using RedirectResponse
type, or #redirect
method. Because of this using a non redirect status would be invalid. If you want to use location
header as part of a 201 Created
you are no longer doing a redirect and thus should just set it manually versus using this type/method.
I mean, if you need it to be that customizable why not write to the response by hand in that case? After all this is a convenience method for the most common scenario. And I think the most common scenario is... (whatever other languages are doing here)
I suppose the question is whether this method should be expected to validate its arguments or not. I think it's not necessary and just avoidable overhead. Of course, it's nice to produce a nice error message to alert the user about a problem. But this still isn't very useful.
I see that this has already been added to 1.6.0
milestone in #10412. Thank you Crystal team :heart:!
https://github.com/crystal-lang/crystal/pull/10412 was reverted in #12517