crystal icon indicating copy to clipboard operation
crystal copied to clipboard

Add a `redirect` method to `HTTP::Server::Context`

Open analogsalad opened this issue 2 years ago • 5 comments

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.

analogsalad avatar Sep 17 '22 15:09 analogsalad

An implementation is already proposed in #10412.

straight-shoota avatar Sep 18 '22 14:09 straight-shoota

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 the Location header. There may be other applications for status codes outside the "Redirect messages" group which allow this header.

straight-shoota avatar Sep 18 '22 16:09 straight-shoota

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.

Blacksmoke16 avatar Sep 18 '22 17:09 Blacksmoke16

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)

asterite avatar Sep 18 '22 17:09 asterite

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.

straight-shoota avatar Sep 18 '22 17:09 straight-shoota

I see that this has already been added to 1.6.0 milestone in #10412. Thank you Crystal team :heart:!

analogsalad avatar Sep 24 '22 10:09 analogsalad

https://github.com/crystal-lang/crystal/pull/10412 was reverted in #12517

straight-shoota avatar Sep 25 '22 12:09 straight-shoota