ecyrbe / zodios

typescript http client and server with zod validation

Home Page:https://www.zodios.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Array type in query parameters

MalpenZibo opened this issue · comments

Hi,
I'm currently trying to use Zodios to specify a GET endpoint that receives an array of values as a query parameter. I have to respect an existing open API spec that defines that query parameter as a style: form, explode: false format (https://swagger.io/docs/specification/serialization/) so I have to accept a query string like /endpointName?id=3,4,5.

I defined the endpoint with the following code

...
{
    name: "id",
    type: "Query",
    schema: z.array(z.string()).optional().default([]),
},
...

but it works only with query strings like /endpointName?id=1&id=2&id=3 or /endpointName?id=[1,2,3].

I tried with the following code

...
{
    name: "id",
    type: "Query",
    schema: z.string().transform((v) => v.split(",")).pipe(z.array(z.string()).optional().default([])),
},
...

but then the generated client accepts only a string as an id parameter, not an array.

There's a way to make this work?

You can try to configure paramsSerializer of axios.
paramsSerializer Option

Changing the axios paramsSerializer doesn't change only how the zodios client sends the request? Because in my case the zodios client is not used

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

I'm having the same issue, could this issue be reopened/discussed @ecyrbe ?

@Ackincolor I don't think this is related to Axios. When the open-api specifies explode: false and style: form, as far as I understand, /endpointName?id=3,4,5 is the expected format. So, it should be supported by the Zodios-generated decoder.

In these cases Zodios should generate a decoder like:

z.string().transform((s: string) => s.split(",")).pipe(z.array(z.string()).optional().default([]));

Or maybe a union of the two approaches to accept them both, like:

z.union([
   z.string().transform((s: string) => s.split(",")).pipe(z.array(z.string()).optional().default([])),
   z.array(z.string()).optional().default([])
])