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

When overwriting getSchema() how to get typesafe validated data? #168

Open
marceloverdijk opened this issue Aug 16, 2024 · 1 comment
Open

Comments

@marceloverdijk
Copy link
Contributor

We have already discussed this in #165 , but I think it's better to create a separate issue for this, as it is not related to the original issue.

When extending Chanfana OpenAPIRoute one can overwrite the default getSchema() or getSchemaZod() function to overwrite schema properties.

  getSchema(): OpenAPIRouteSchema {
    // Use this function to overwrite schema properties
    return this.schema
  }

For example:

export class PagingRoute extends OpenAPIRoute {
  defaultPageSize = 10;
  maxPageSize = 50;

  getSchema(): OpenAPIRouteSchema {
    // Deep copy
    const schema = { ...super.getSchema() }
    
   schema.request.query = schema.request.query.merge(z.object({
     page: z.number().int().optional()
     pageSize: z.number().int().max(this.maxPageSize).optional()
   }))    
  }

  async doSomethingWithPagingParams() {
    const validatedData = await this.getValidatedData();
    // validatedData does not know about its type, so page and pageSize are not recognized.
    ..
  }
}

export class GetCustomers extends PagingRoute {
  schema = {
    request: {
      query: z.object({
        expand: z.string(),
      }),
    },
    responses: {
      '200': {
        content: {
          'application/json': {
            schema: CustomersResponseSchema,
          },
        },
      },
    },
  };

  async handle(request: Request, ctx: Context) {
    const data = await this.getValidatedData<typeof this.schema>();
    const expand = data.query.expand; // this works, and vscode uses types.
    const page = data.query.page; // vscode does not recognize page/pageSize paramaters... 
    // is it possible to get typesafe validated data including the additional fields?
    
    doSomethingWithPagingParams();
    
    ..
  }
}

When modifying the schema like this, is it possible to get typesafe validated data in both the handle function and in the extended PagingRoute class?

Or is it not meant to be used like that @G4brym ?

@marceloverdijk
Copy link
Contributor Author

What I did for now is the following:

I defined a custom type like:

export type PaginationSchema = {
  request: {
    query: z.ZodObject<{
      page: z.ZodOptional<z.ZodNumber>;
      'pageSize': z.ZodOptional<z.ZodNumber>;
    }>,
  }
}

and in a route's handle method I can access it like together with other part of the schema like this:

  async handle(request: Request, ctx: Context) {
    const data = await this.getValidatedData<typeof this.schema & ExpandSchema>();
    ..
  }

same in the PagingRoute class I can do something like this a custom function:

  async doSomething() {
    const validatedDataTyped = await this.getValidatedData<ExpandSchema>();
    ..
  }

Not sure if it's best approach, but at least I can augment/inject common query params, and still have typesafe query arguments.

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

1 participant