yesodweb / yesodweb.com-content

Content for the www.yesodweb.com site
http://www.yesodweb.com/
Other
67 stars 112 forks source link

Add documentation for special case of empty args #277

Closed schoettl closed 5 months ago

schoettl commented 5 months ago

Hi there, I recently stumbled upon the question how Yesod handles empty strings like in @{MyRouteR ""}.

First, the behavior was quite irritating for me, then I understood the logic behind.

I documented it and thought it might fit well in the book chapter on routes?

What do you think?

In my case, I deliberately wanted pass "" in /orders/#Text. I wanted to use query string args – submitted through a form with method=get – to redirect from /orders/-?order_number=123456 to /orders/123456.

schoettl commented 5 months ago

Fixed cross reference according to https://docs.asciidoctor.org/asciidoc/latest/macros/xref/#anchors

snoyberg commented 5 months ago

This is a good thing to include, but I'd recommend reframing the prose. The new section currently starts with the question:

How to pass the empty string to routes with +#String+ or +#Text+ pieces?

Instead, I'd start the other way around: how could we possibly distinguish between "user requested /hello/ but accidentally included a trailing slash and really wants HomeR" vs "user really wanted to request /hello/ which is logically different from HomeR."

As an aside, I'd strongly advise against this kind of overloading; using empty strings should almost never happen in a Yesod app IMO. Treating this as disambiguating a corner case, as opposed to a roadblock to be overcome, would be better.

schoettl commented 5 months ago

Right, that FAQ-like question might be good for SEO but sounds like it encourages the use of empty args. I understand that we don't want to encourage it. I'll see how I can change the formulation the next days.

Thanks for your aside advice. Do you have a different solution in mind for this scenario of using a simple GET form to open a specific order by order number? I mean, I could just use a dedicated new route that takes no arguments, just the query string param. I just thought it's simpler and more concise to use the same route and handler for showing one specific order.

snoyberg commented 5 months ago

I don't know enough about the use case, but I'd ask a few questions:

  1. Is there a reason you need to use query strings instead of the path?
  2. Could you just have a single HomeR route and have it do the query string parsing and decide which version of the page to display instead?
schoettl commented 5 months ago
  1. Is there a reason you need to use query strings instead of the path?

Using query strings, I could use a simple HTML form with an <input type=text name=ordernumber> and a "Jump to order" button.

I guess it would require an onclick JS handler to open an URL with a dynamic path piece depending on the input's value. And for the URL I wouldn't be able to use the type-safe #{HelloR "ordernumber"} because the order number depends on the user input.

  1. Could you just have a single HomeR route and have it do the query string parsing and decide which version of the page to display instead?

Yes, that would be possible. But HomeR then would be kind of overloaded because it already has a lot of different filters passed by query args, and more interactive functionality on its own. Merging it with HelloR would make it more complex.

I could use it only for the "Jump to order" GET and let it redirect to HelloR if I wanted to avoid the empty #String piece. But the redirect functionality seems more coherent with HelloR.

snoyberg commented 5 months ago

If the goal is really to provide a GET form that redirects to a path-based route, I'd probably recommend having a dedicated route for handling that redirect. Lumping it in with any existing route seems to be where the pain points are coming from. I think we have something similar in yesod-auth for the redirect-to-logout functionality.

schoettl commented 5 months ago

Thanks for taking the time, Michael, I appreciate your advice!

schoettl commented 5 months ago

I changed the documentation. Feel free to give feedback, merge or adapt it if you have concrete change requests.