How to accept flattened objects in query params?
It seems that the hono client calls
String()
on the query params so that any objects passed through which should normally be something like filters[key]=value
ends up becoming filters="[object Object]"
.
1. I'm pretty sure this use-case should be supported since it appears out in the wild when using query params
2. Is there a way to make this work? or is the recommendation to go with flat query objects / honojs client doesn't support objects in query params?
I think this is an error/bug that should be updated. Just want to confirm here before writing an issue on github...
[1/2]22 Replies
Console output:
[2/2]
you could make middleware that adds support for it
but it is indeed unfortunate that this happens
usually for search params, you don't do
item[]=1&item[]=2
but item=1&item=2
at least that's how it is in spring boot for example
the item[]=1
syntax is for formsyep, looks like what I sent works

it does feel intuitive to do what forms do, but for some reason there is a difference, and I don't know if there is a specification for this or if everybody copied each other's implementation
this aligns more with how Headers behave, so I'd say it's one way of remembering it
you should never construct the query string yourself though, since there is a built-in class for that
URLSearchParams

oh you were not talking about arrays, but objects?
not even forms have objects
Thanks for your responses.
To clarify, the item and filters example you're giving look like the ability to accept arrays where a zod schema would be
query: z.object({ item: z.string().array() });
But for objects like..
It should come out like this... filters[active]=true&filters[name]=Sally
I'm using the hono testApiClient and it seems to call String()
on all query params, such that even middleware doesn't work since all query params appear to be stringified as opposed to serialized and thus in any middleware, when looking for the query property, I get [object Object]
I understand I can make my query params flat, but in my conversations with Google Gemini, it seems to suggest this is a conventional method of accepting query params that should workYeah was talking about nested objects, not arrays. Sorry if I wasn't clear at first.
There's an existing issue that was closed here about the same thing:
https://github.com/honojs/middleware/issues/737
GitHub
zValidator parsing url queries containing nested object ยท Issue #7...
Hi guys, Wondering how to validate (and design schema) a route with zValidator with an url like this : http://hostname/products/paginate?limit=8&filters[productName]=fr. My issue is filters whi...
I've never seen a framework/library support such things out of the box
maybe laravel? can't remember
I see...
you could just make ur own middleware tho
zValidator is nothing special
zod does the heavy lifting
and the built-in URLSearchParams class doesn't allow such structures, so it's probably out of spec, and hono follows the specs, so it's probably not going to get added to hono
In the context of writing my own validator, since I'm using hono zod-openapi, the createRoute function doesn't accept a zValidator function right? So I assume that means the schema would need to be z.string().transform(...) to transform a string into an object but then I'd lose the openapi definitions.
I see. Okay I can understand that. It's helpful that at least that's clear. It looks like going flat is the way to go here then
Appreciate your help on this Arjix
uhh
you could keep both
and only use ur custom middleware
The middleware approach doesn't work because it gets stringified to "[object Object]" at least when I use the hono test client such that it can't be JSON.parse() 'ed back
you do
ctx.req.valid('query')
, if you simply don't do that, then you are not invoking the zValidator
but you still have the openapi types
as long as you re-use the same zod schema, it should be fine (having one source of truth)
I may be forgetting smth
uhh, I don't really use zod-openapi, so forgive me if I am wrong
I mainly use hono-openapiI'm also using hono-openapi. I think part of my issue is with the hono test client and possibly the honoClient itself
import { testClient } from "hono/testing";
When using it, when I pass a nested object in query params, it becomes a literal string value of "[object Object]"
such that middleware receives a string of "[object Object]"
so middleware doesn't work when using it with the client because the client serialization is equivalent to calling String()
So even if I don't validate the data, the data can't be passed through properly when using the hono client.
Requesting the url directly with fetch()
or app.request()
would work as in your picture.
In any case, I guess flat query params is the approach to use.
Not sure if the hono (test) client should be updated based on the above notes...you could make a utility function to convert an object to a flat query
I believe hono won't mess with the params if you directly pass a URLSearchParams instance
Yeah. I could JSON.stringify() the object passed into filter and that would work.
I think with all these special cases required by the caller to do special parsing when using the client, I'll just revert to flat structures.
Appreciate your help again
Yeah. I could JSON.stringify() the object passed into filter and that would work.that's not what I suggested, and I am unsure if you intented to say "I could also ..."
Ah. You said utility function so I was thinking the utility function would use JSON.stringify()
nah, it would recursively iterate over all keys and flatten the object
overkill, but that's basically what I did in PHP ๐
But yeah overall, I'm okay to change it to just be flat to avoid the caller needing to handle these special cases
I see