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

GET request interference for query parameters #425

Open
ronsigter opened this issue Dec 1, 2023 · 2 comments
Open

GET request interference for query parameters #425

ronsigter opened this issue Dec 1, 2023 · 2 comments

Comments

@ronsigter
Copy link

ronsigter commented Dec 1, 2023

I have two API endpoints:

  getUserById: loggedInProcedure
    .meta({
      openapi: {
        tags: [USER_TAG],
        method: 'GET',
        path: '/users/{id}', /* 👈 */
        contentTypes: ['application/json'],
        summary: 'Gets user by ID',
        protect: true,

        errors: [
          {
            type: 'NOT_FOUND',
            errorMessage: 'User not found.',
          },
        ],
      },
    })
    .input(UsersSchema.getUserByIdParamsSchema) /* 👈 z.object({ id: z.string().uuid() } */
    .output(UsersSchema.getUserByIdDTOSchema)
    .query(async ({ input }) => {
      return UsersService.getUserById(input);
    }),

AND

  getUserClaim: loggedInProcedure
    .meta({
      openapi: {
        tags: [USER_TAG],
        method: 'GET',
        path: '/users/claim', /* 👈 */
        contentTypes: ['application/json'],
        summary: 'Gets the current user to be claimed',
        protect: true,

        errors: [],
      },
    })
    .input(UsersSchema.getUserClaimParamsSchema) /* 👈 z.void() */
    .output(UsersSchema.getUserClaimDTOSchema)
    .query(async ({ ctx }) => {
      return UsersService.getUserClaim({ id: ctx.user.id });
    }),

And when I try to hit /users/claim

I get:

{
  "message": "Input validation failed",
  "code": "BAD_REQUEST",
  "issues": [
    {
      "validation": "uuid",
      "code": "invalid_string",
      "message": "Invalid uuid",
      "path": [
        "id"
      ]
    }
  ]
}

It works if I remove the /users/{id} endpoint OR if I put the path: /users/claim on top of /users/{id}

Any ideas as to why this happens? Thanks!

@DJanocha
Copy link

DJanocha commented Dec 12, 2023

So you have 2 endpoints:

  1. '/users/{id}'
  2. '/users/claim'.

When you try to access the '/users/claim' route, trpc-openapi checks all of the routes, one by one, to check if there is a one that matches the endpoint you are trying to reach. If the matching route is found, searching stops(it searches until it finds). I believe both your endpoint declarations (listed above) match the endpoint you are trying to reach so the first one wins.

It looks similar to endpoint declaration in pure express.js where, if you have two routes declarations, and one is a subset of the other, you need to declare them from the most specific to the most broad.
In your case ‘/users/{id}’ is broader than ‘/users/claim’ because there is enormous combination of string you can theoretically use as id (eg “claim”) vs single word “claim”. An example of even more broad endpoint declaration is ‘/’.
in my understanding’ if you declare endpoint ‘/’ and put it before your two declarations, it will shadow/take precedence over your two endpoint declarations because it matches the ‘/users/claim’ as your endpoints and is declared first.
hope it helps anyhow. For further ingestion, look for ‘dynamic path segments’ or something like that in express.js docs.

I will check later if I’m 100% sure about that shadowing.
Happy coding!

@ronsigter
Copy link
Author

@DJanocha thanks for this! Will take a look at this shadowing 👌

For now, the workaround is, as you suggest, to make it from the most specific going to a broader scope.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants