-
Notifications
You must be signed in to change notification settings - Fork 419
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
[Question] Handling empty query params #4010
Comments
The problem here is that Tapir is quite simplistic in how it handles query parameters: a How to fix this? I see three options. First, by providing an explicit codec. The def query[T: Codec[List[String], *, TextPlain]](name: String): EndpointInput.Query[T] It needs a codec which converts a In our custom one, we need to take the raw list of query parameters, filter out the empty ones, and then copy the logic from given Codec[List[String], Option[LocalDate], CodecFormat.TextPlain] = Codec
.list[String, String, CodecFormat.TextPlain]
.map(_.filter(_.nonEmpty))(identity)
.mapDecode {
case Nil => DecodeResult.Value(None)
case List(e) => Codec.localDate.decode(e).map(Some(_))
case l => DecodeResult.Multiple(l)
}(v => v.map(Codec.localDate.encode).toList)
.schema(Codec.localDate.schema.asOption) The first The second solution would be more general, if there's a lot of such query parameters. You could create a Finally thirdly, I think we could add an attribute, so that you could instruct the server interpreter's decoder to treat empty values as absent. This would be sth like: Let me know what you think! |
Hi Adam, thank you for your quick and thorough response! So, for my upcoming demo, the codec will do ^^ However, for the application as a whole, this might be error prone (accidentally not importing the custom codec and a date filter won't work). I now better understand how the query param handling in Tapir works. This approach of building up codecs composes well, but unfortunately, it's blind to the final type. Bc. parsing an empty string "" fails - of course it does. But when the expected result is not a So yeah, not sure what the best design would be here. Or how other servers handle this. Attributes might be the easiest way to implement this. I saw that flag params got a special case with |
There are indeed similarities with my issue, I'd have to see if the 3rd proposed solution would fix my issue, I don't know exactly what the behaviour will be with an My need was to differentiate between the 3 possible cases :
A native codec that allows this is a flexible codec that allows the user to manage all cases according to their specific needs. It also means taking into account that semantically ‘absent’ and ‘empty’ are 2 different things. Today Tapir is confusing the two from my point of view. |
I am using Tapir in combination with an HTMX frontend.
Sending a GET request from an input field, HTMX will include the input as a query parameter, even if the value is empty, in some cases - it seems like this is purposefully replicating HTML form behavior.
E.g., I have a date input and use the date pickers "clear" button to reset the value. HTMX will issue a request to
mypath?date=
.Tapir does not like this, I get a
400 - Invalid value for: query parameter date
.My endpoint looks something like this:
I would have expected this to yield a
None
. My IDE suggests, that this query param usesCodec.listHeadOption
and I assume withCodec.localDate
as underlying codec.This seems to try to do something similar to
strings.map(LocalDate.parse).headOption
, in the sense that theLocalDate.parse
fails bc. it might receive an empty string.This does not work:
I don't understand the codec selection fully, so I'm a bit at a loss.
Also, I wonder if this behavior by Tapir is correct? It seems like many servers do accept query params of that sort?
Tapir version: 1.10.10
Scala version: 2.13.14
The text was updated successfully, but these errors were encountered: