trpc-openapi icon indicating copy to clipboard operation
trpc-openapi copied to clipboard

Example for using array and objects in query

Open maloguertin opened this issue 3 years ago • 7 comments

It would be nice to have an example for array and object since I think it's a common use case.

Let's say I want to have a route the allows me to pass a list of ids:

/users?ids[]=user-1&ids[]=user-2

what would be the best way to do it with preprocess?

maloguertin avatar Jan 13 '23 18:01 maloguertin

Hi @maloguertin, I think a possible solution could be that you pass your array as a string seperated by a comma, for example:

/users?ids=user-1,user-2

Than you can split the string with the preprocess into an array again, e.g.

z.object({ ids: z.preprocess((ids) => ids.split(',').map(id => id.trim()), z.array(z.string())) })

kammeph avatar Jan 31 '23 21:01 kammeph

am I wrong in thinking that openapi actually supports the array as a repeating of the parameters in queries?

https://swagger.io/docs/specification/serialization/

style explode URI template Primitive value id = 5 Array id = [3, 4, 5] Object id = {"role": "admin", "firstName": "Alex"}
form * true * /users{?id*} /users?id=5 /users?id=3&id=4&id=5 /users?role=admin&firstName=Alex
form false /users{?id} /users?id=5 /users?id=3,4,5 /users?id=role,admin,firstName,Alex
spaceDelimited true /users{?id*} n/a /users?id=3&id=4&id=5 n/a
spaceDelimited false n/a n/a /users?id=3%204%205 n/a
pipeDelimited true /users{?id*} n/a /users?id=3&id=4&id=5 n/a
pipeDelimited false n/a n/a /users?id=3|4|5 n/a
deepObject true n/a n/a n/a /users?id[role]=admin&id[firstName]=Alex

maloguertin avatar Feb 01 '23 17:02 maloguertin

Hey @maloguertin, yes repeating parameters in the querie is specified within openapi. But this don't mean that it works out of the box. The purpose of Swagger/OpenApi is only the documentation of the api. It does not add any functionality. This feature must be added to the trpc-openapi package. The valid inputs are described in the docs https://github.com/jlalmes/trpc-openapi#query-parameters

kammeph avatar Feb 01 '23 19:02 kammeph

Oh I know, I was mostly wondering if since this lib is aimed towards supporting openapi spec would it be possible to support those types of queryParams without zod preprocess in the future? I am also open to making a PR!

maloguertin avatar Feb 04 '23 19:02 maloguertin

I wanted to use objects, so I did following patch on the package.

diff --git a/src/generator/schema.ts b/src/generator/schema.ts
index cadf3bf..3e1d187 100644
--- a/src/generator/schema.ts
+++ b/src/generator/schema.ts
@@ -72,14 +72,13 @@ export const getParameterObjects = (
       let shapeSchema = shape[shapeKey]!;
       const isShapeRequired = !shapeSchema.isOptional();
       const isPathParameter = pathParameters.includes(shapeKey);
+      const extraProps: Partial<OpenAPIV3.ParameterObject> = {};
 
       if (!instanceofZodTypeLikeString(shapeSchema)) {
         if (zodSupportsCoerce) {
           if (!instanceofZodTypeCoercible(shapeSchema)) {
-            throw new TRPCError({
-              message: `Input parser key: "${shapeKey}" must be ZodString, ZodNumber, ZodBoolean, ZodBigInt or ZodDate`,
-              code: 'INTERNAL_SERVER_ERROR',
-            });
+            extraProps.style = 'deepObject';
+            extraProps.explode = true;
           }
         } else {
           throw new TRPCError({
@@ -107,6 +106,7 @@ export const getParameterObjects = (
         required: isPathParameter || (isRequired && isShapeRequired),
         schema: openApiSchemaObject,
         description: description,
+        ...extraProps,
       };
     });
 };

Tomas2D avatar Mar 03 '23 18:03 Tomas2D

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[bot] avatar May 02 '23 19:05 stale[bot]

Good afternoon from Helsinki. My use-case sounds like it could be related to this topic. When I define my endpoint procedure, I call tRPC's procedure builder function .input( someSchema ) for all procedures query | mutation. The plugin works fine for parsing the request body on mutation endpoints but it does not seem to understand that my query endpoint procedure receives its input via a url query key input=someSchema. I could maybe work around this but frankly see that as unnecessary work given that tRPC library is automatically doing this for me. Any ideas for how we could support this with the plugin? I wouldn't mind contributing to the project if someone has some understanding of the code base and can point me where to get started. Thanks for the support and insight(s).

For example:

  • Current Behaviour https://some-api-root/someEndpoint?someParameter="someValue"
  • Desired Behaviour https://some-api-root/someEndpoint?input={"someParameter":"someValue"}

ChrisK1982 avatar Feb 29 '24 09:02 ChrisK1982