turkerdev / fastify-type-provider-zod

MIT License
411 stars 25 forks source link

How to add response headers with cookies in Swagger using fastify-type-provider-zod? #127

Open LivioAlvarenga opened 2 weeks ago

LivioAlvarenga commented 2 weeks ago

Hello!

I am using fastify-type-provider-zod to document my API with Swagger, and I would like to add response headers that include cookies, such as Set-Cookie, to my Swagger documentation.

I attempted to define the headers directly within the schema, but it didn't work as expected. Here is a simplified version of my code:

app.withTypeProvider<ZodTypeProvider>().post(
  '/v1/public/auth/login/user/credential',
  {
    schema: {
      summary: 'Authenticate a user with credential provider',
      tags: ['auth'],
      body: requestSchema,
      response: {
        201: {
          description: 'Successful authentication with session and refresh tokens as cookies',
          headers: {
            'Set-Cookie': {
              type: 'array',
              items: {
                type: 'string',
                example: [
                  'refreshToken=tokenValue; Path=/; HttpOnly; Secure; SameSite=Strict',
                  'sessionToken=tokenValue; Path=/; HttpOnly; Secure; SameSite=Strict',
                ],
              },
              description: 'Cookies for session and refresh tokens',
            },
          },
        },
      },
    },
  },
  async (request, reply) => {
    // Controller logic
  },
)

When I try this, I receive an error indicating that zod-to-json-schema cannot process this configuration.

TypeError: Cannot read properties of undefined (reading 'typeName')   
    at parseDef (node_modules/zod-to-json-schema/dist/cjs/parseDef.js:52:46)
    at zodToJsonSchema (node_modules/zod-to-json-schema/dist/cjs/zodToJsonSchema.js:22:45)
    ...

Question:

Is there a recommended approach for documenting response headers with Set-Cookie or other cookies using fastify-type-provider-zod? Any guidance on how to set up these response headers would be much appreciated.

Thank you!

troncoso commented 1 week ago

Hi @LivioAlvarenga. I believe this could be failing because you don't have the handler setup correctly. It should look like this:

app.withTypeProvider<ZodTypeProvider>().post(
  '/v1/public/auth/login/user/credential',
  {
    schema: {
      summary: 'Authenticate a user with credential provider',
      tags: ['auth'],
      body: requestSchema,
      response: {
        201: {
          description: 'Successful authentication with session and refresh tokens as cookies',
          headers: {
            'Set-Cookie': {
              type: 'array',
              items: {
                type: 'string',
                example: [
                  'refreshToken=tokenValue; Path=/; HttpOnly; Secure; SameSite=Strict',
                  'sessionToken=tokenValue; Path=/; HttpOnly; Secure; SameSite=Strict',
                ],
              },
              description: 'Cookies for session and refresh tokens',
            },
          },
        },
      },
    },
    handler: async (request, reply) => {
        // Controller logic
    },
  }
)

I think that's necessary for this library to understand what type the request and reply are.