elysia icon indicating copy to clipboard operation
elysia copied to clipboard

Object encoding in query parameters

Open m1212e opened this issue 10 months ago • 10 comments

Calling the API via the treaty encodes objects passed as query params as literally "[object Object]" instead of URL encoding it.

      this.iam.auth.domain.user.get({
        query: {
          role: [{ id: orga.adminRoleId }, { id: orga.memberRoleId }],
        },
      })

and on the receiving end:

      query: t.Optional(
        t.Object({
          role: t.Optional(
            t.Array(t.Partial(t.Pick(Role, ["id", "name", "authProviderId"]))),
          ),
        }),
      ),

results in

   "type": "validation",
   "on": "query",
   "property": "/role",
   "message": "Expected array",
   "expected": {},
   "found": {
     "role": "[object Object],[object Object]"
   },
   "errors": [
     {
       "type": 6,
       "schema": {
         "type": "array",
         "items": {
           "description": "Composition of RolePlain, RoleRelations",
           "additionalProperties": false,
           "type": "object",
           "properties": {
             "id": {
               "type": "string"
             },
             "name": {
               "type": "string"
             },
             "authProviderId": {
               "type": "string"
             }
           }
         }
       },
       "path": "/role",
       "value": "[object Object],[object Object]",
       "message": "Expected array"
     }
   ]
 }. Thrown at Error: {
   "type": "validation",
   "on": "query",
   "property": "/role",
   "message": "Expected array",
   "expected": {},
   "found": {
     "role": "[object Object],[object Object]"
   },

Is this as it should work and we are just expected to only send primitive values via query parameters? Thanks!

m1212e avatar Apr 11 '24 22:04 m1212e

Just realized that it may not be the intended usage for query parameters to be anything beyond strings: https://elysiajs.com/validation/schema-type#query

If thats the case, maybe it would make sense to only every allow strings or optional strings to be passed as query schema to the handler?

m1212e avatar Apr 15 '24 14:04 m1212e

Object encoded query is implemented in 1.0.23, let me know if it works or not

SaltyAom avatar Jun 09 '24 11:06 SaltyAom

Hi @SaltyAom,

unfortunately I get some errors when I try to use object encoded queries:

  server.get(
    "/domain/:domainId/user",
    ({ params, query }) => {
      // this is a prisma db query
      return db.user.findMany({
        where: {
          domainId: params.domainId,
          roles: query?.role
            ? {
                some: query.role,
              }
            : undefined,
        },
      });
    },
    {
      response: t.Array(User),
      query: t.Optional(
        t.Object({
          // role: t.Optional(t.String()),
          role: t.Optional(t.Object({ id: t.Optional(t.String()) })),
        }),
      ),
    },
  )

results in

Error in GET /domain/2a42f947-93c9-4493-9f9a-93254a6e171f/user: UNKNOWN JSON Parse error: Unexpected identifier "undefined". Thrown at SyntaxError: JSON Parse error: Unexpected identifier "undefined"
    at <parse> (:0)
    at parse (native)
    at <anonymous> (:67:29)
    at handle (:50:32)
    at map (:259:35)
{"originalLine":67,"originalColumn":29}

which is probably not what should happen ? :D This happens on an empty query, I don't send along any query.

When using this endpoint from the treaty client like this:

.user.get({
  query: {
    role: {
      id: "054ce000-cc5a-4e5b-a7e1-1cfd45c18c3f",
    },
  },
});

I get

Error in GET /domain/2a42f947-93c9-4493-9f9a-93254a6e171f/user: UNKNOWN JSON Parse error: Unexpected identifier "object". Thrown at SyntaxError: JSON Parse error: Unexpected identifier "object"
    at <parse> (:0)
    at parse (native)
    at <anonymous> (:67:29)
    at handle (:50:32)
    at map (:256:32)
{"originalLine":67,"originalColumn":29}

instead. I have normalization enabled.

m1212e avatar Jun 10 '24 13:06 m1212e

Should I open a new issue?

m1212e avatar Jun 10 '24 13:06 m1212e

Should be related to #677, let me know if the latest commit fix the problem

SaltyAom avatar Jun 18 '24 07:06 SaltyAom

Still seeing this issue.

87 |                             Object.assign(c, transformed)
88 | 
89 | if(params.Check(c.params) === false) {
90 |                             c.set.status = 422; throw new ValidationError('params', params, c.params)
91 |                     }
92 | if(typeof c.query['ids'] === "object") c.query['ids'] = JSON.parse(c.query['ids'])
                                                                       ^
SyntaxError: JSON Parse error: Unable to parse JSON string

Where the validation is:

  query: t.Object({
    ids: t.Union([t.Array(t.Numeric()), t.Numeric()])
  })

On ElysiaJS 1.0.25

MatthewAry avatar Jun 27 '24 19:06 MatthewAry

Just some additional feedback related to query parameters. Trying to set up query param validations for sorting, filtering, grouping and such is very difficult right now. Would be awesome to see some design patterns, even something that would combine Drizzle ORM and ElysiaJS for filtering on a data table for strings, numbers, and dates.

MatthewAry avatar Jun 28 '24 21:06 MatthewAry

@MatthewAry should be fixed in 1e0331f, including test case, published under 1.0.27

SaltyAom avatar Jul 02 '24 13:07 SaltyAom

Still getting the same issue, object aren't being encoded using eden + elysia.

adarshaacharya avatar Jul 19 '24 19:07 adarshaacharya

Still getting the same issue, object aren't being encoded using eden + elysia.

update: this has been fixed in latest eden release

adarshaacharya avatar Jul 29 '24 09:07 adarshaacharya