fastify / fastify-swagger

Swagger documentation generator for Fastify
MIT License
926 stars 204 forks source link

Integrate with qs library #716

Open conduongtong opened 1 year ago

conduongtong commented 1 year ago

Prerequisites

šŸš€ Feature Proposal

Can we have a querystring parser for swagger? I have a problem with array in params request url image

Because swagger ui stringify params different than qs so I receive different object. Expected:

filters[roles][$or][0][name]=Super Admin&filters[roles][$or][1][permissions][name]=user:findOne

Thank you!

Example

const qs = require("qs");
const fastify = require("fastify");
const fastifySwagger = require("@fastify/swagger");
const fastifySwaggerUi = require("@fastify/swagger-ui");

const test = async () => {
  const app = fastify({ logger: true, querystringParser: qs.parse });

  await app.register(fastifySwagger, {
    openapi: {
      info: {
        title: "Test",
      },
    },
    hideUntagged: true,
  });
  await app.register(fastifySwaggerUi, {});

  app.get(
    "/users",
    {
      schema: {
        tags: ["User"],
        querystring: {
          type: "object",
          properties: { filters: { type: "object" } },
        },
      },
    },
    async (request) => {
      return request.query;
    }
  );
  app.listen({ host: "127.0.0.1", port: 3000 });
};

test();

Query:

{
  "filters": {
    "roles": {
      "$or": [{"name": "Super Admin"}, { "permissions": { "name": "user:findOne" }}]
    }
  }
}
mcollina commented 1 year ago

I'm sorry but I don't understand those snippets. Could you include a complete example?

conduongtong commented 1 year ago

I'm sorry but I don't understand those snippets. Could you include a complete example?

I have a query params like this:

Screenshot 2023-03-29 at 2 52 11 PM

It return: '/users?filters[roles][$or][name]=Super Admin&filters[roles][$or][permissions][name]=user:findOne' Because swagger stringify that object to above string. Using qs library it would parse $or to object instead of array. It should be stringify like this: '/users?filters[roles][$or][0][name]=Super Admin&filters[roles][$or][1][permissions][name]=user:findOne'

So I need swagger UI stringify with qs instead of querystring. Sorry for my bad english, btw.

mcollina commented 1 year ago

So is this a bug in Swagger UI?

conduongtong commented 1 year ago

So is this a bug in Swagger UI?

It's not because swagger maybe use querystring to stringify, I want to use qs library instead. With fastify I can change to qs by using querystringParser option.

mcollina commented 1 year ago

Can you provide steps to reproduce? We often need a reproducible example, e.g. some code that allows someone else to recreate your problem by just copying and pasting it. If it involves more than a couple of different file, create a new repository on GitHub and add a link to that.

conduongtong commented 1 year ago

Can you provide steps to reproduce? We often need a reproducible example, e.g. some code that allows someone else to recreate your problem by just copying and pasting it. If it involves more than a couple of different file, create a new repository on GitHub and add a link to that.

const qs = require("qs");
const fastify = require("fastify");
const fastifySwagger = require("@fastify/swagger");
const fastifySwaggerUi = require("@fastify/swagger-ui");

const test = async () => {
  const app = fastify({ logger: true, querystringParser: qs.parse });

  await app.register(fastifySwagger, {
    openapi: {
      info: {
        title: "Test",
      },
    },
    hideUntagged: true,
  });
  await app.register(fastifySwaggerUi, {});

  app.get(
    "/users",
    {
      schema: {
        tags: ["User"],
        querystring: {
          type: "object",
          properties: { filters: { type: "object" } },
        },
      },
    },
    async (request) => {
      return request.query;
    }
  );
  app.listen({ host: "127.0.0.1", port: 3000 });
};

test();

Here is it. You will see response different with my input

mcollina commented 1 year ago

How are you sending your input? Can you pass a curl string to send it or a Node script?

conduongtong commented 1 year ago

How are you sending your input? Can you pass a curl string to send it or a Node script?

I pass it to parameter like an example. schema -> quyerstring -> filters

mcollina commented 1 year ago

Are you using Swagger UI to generate the querystring? Is it generating a querystring that the server cannot interpret correctly?

I asked the same question in https://github.com/fastify/fastify-swagger/issues/716#issuecomment-1488136641.

conduongtong commented 1 year ago

Are you using Swagger UI to generate the querystring? Is it generating a querystring that the server cannot interpret correctly?

I asked the same question in #716 (comment).

Yes but it's not a bug in Swagger UI. I use different library to parse

Uzlopak commented 1 year ago

Please read the part regarding query serialization in

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

conduongtong commented 1 year ago

Please read the part regarding query serialization in

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

I read it before, I also try { type: 'object', style: 'deepObject', explode: true } but it's not working, unknown keyword 'style'

Uzlopak commented 1 year ago

Where is this error thrown? Typescript? Runtime at fastify start? When shown in the ui?

conduongtong commented 1 year ago

Where is this error thrown? Typescript? Runtime at fastify start? When shown in the ui?

It's strict mode schema throw error