Skip to content
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

[Proposal] Create a way for Query Parameters to have a custom operator other than just "=" #475

Closed
cloudbring opened this issue Jun 13, 2023 · 5 comments
Labels
wontfix This will not be worked on

Comments

@cloudbring
Copy link

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.

  1. 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: '!='}
    })
  2. 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' 
        }
      });
@cloudbring
Copy link
Author

Would this be better implemented as a plugin, or will this require a PR to Zodios itself?

@ecyrbe
Copy link
Owner

ecyrbe commented Jun 14, 2023

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.

@cloudbring
Copy link
Author

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.

@stale
Copy link

stale bot commented Jul 15, 2023

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.

@stale stale bot added the wontfix This will not be worked on label Jul 15, 2023
@ecyrbe
Copy link
Owner

ecyrbe commented Jul 15, 2023

closing. But feel free to share the results with the community

@ecyrbe ecyrbe closed this as completed Jul 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants