[Proposal] Create a way for Query Parameters to have a custom operator other than just "="
cloudbring opened this issue · 5 comments
First, love this project and being able to define APIs in a type-safe way.
The issue I'm trying to solve is I have to support a bunch of query parameters that aren't just /foo?field=value
.
Example Query Parameters:
LOTR API Documentation
Type | Example |
---|---|
match | /character?name=Legolas |
negate match | /character?name=!Frodo |
include | /character?race=Hobbit,Dwarf |
exclude | /character?race!=Orc,Goblin |
exists | /character?name |
not exists | /character?!name |
regex | /character?name=/^Fro/i |
negate regex | /character?name!=/^Fro/i |
greater than | /character?height>180 |
less than | /character?height<180 |
greater than or equal | /character?height>=180 |
less than or equal | /character?height<=180 |
equal to | /character?height=180 |
Proposal
If we define a url query as consisting of a field, a value and an operator, I want to support various operators.
-
Create an optional
operator
field on the parameters object.const params = makeParameters([ //=> /character?name=!Legolas { field: 'name', description: 'Filter results by name of character', type: 'Query', operator: '!=', // Optional: Defaults to '=' schema: z.string() }, ]);
Usage:
const response = await zodios.request({ method: 'GET', url: '/character', data: { name: 'Legolas', operator: '!='} })
-
Create a new
RAW_QUERY
query type that exposes the full parameter string (everything between and excluding the?
and&
characters).const params = makeParameters([ //=> /character?name!=/^Fro/i&... { field: 'name', description: 'Filter results by regex of name of character', type: 'RAW_QUERY', rawQuery: z // ! NOTE: The object members should are customizable .object({ field: z.string().default('name'), // Ideally this would be optional and inferred from the parent object field 'name' operator: z.string().default('!='), // Literal here but, can be a zobject to allow a function to create a query parameter. regex: z.string(), // Zod needs an isRegex() function }) .transform((data: {field,operator,regex}) => `${field}${operator}${regex}`, ), }, ])
Usage:
//=> /character?name!=/^Fro/i&... const response = await zodios.request({ method: 'GET', url: '/character', data: { field: 'name', // Optional: Defaults to 'name' operator: '!=', // Optional: Defaults to '!=' regex:'/^Fro/i' } });
Would this be better implemented as a plugin, or will this require a PR to Zodios itself?
Hello,
Thank you for the proposal,
Since query parameters are not standardized at all,
Zodios implements the most common pattern in practice.
So any custom format should be implemented in a plugin.
Zodios will not provide one. Since there are hundred of custom query formats in the wild, and zodios can't support them all.
So i suggest you implement your custom serializer in your code base as a plugin.
No need to do a PR to zodios. You can already add your custom 'operator' to your api definition, zodios and typescript will not complain.
You can then write your plugin to use the 'operator' keyword and forward your serializer to axios :
See paramsSerializer
in axios documentation on how to implement a custom query param serializer.
Thanks for the feedback. Once I'm done with my current project, I'll take a stab at making a Zodios plugin for this using paramsSerializer.
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.
closing. But feel free to share the results with the community