asteasolutions / zod-to-openapi

A library that generates OpenAPI (Swagger) docs from Zod schemas
MIT License
955 stars 60 forks source link

Add option to disable default property evaluation #254

Closed WilliamABradley closed 1 month ago

WilliamABradley commented 2 months ago

This breaks our API schema as it evaluates the .default(() => createId()) in our models, and creates a random cuid on each evaluation.

This causes our API to shard with allOf in an unfriendly way, and it is also an unexpected behaviour.

I believe this is related to https://github.com/asteasolutions/zod-to-openapi/pull/63

Perhaps function based defaults should just be left alone, as this doesn't happen with constant defaults. It doesn't make sense to evaluate a default function.

AGalabov commented 1 month ago

@WilliamABradley I see your point however I do not agree that this is a problem on our side.

The regular scenario for people to use default is to actually define a default value - and we would want to "evaluate" that. Let's say z.number().default(42). That way you would want to have default: 42 in the API specs.

In your case - your default is "unique" every time => it is not really something to add you your documentation at all. So I think semantically you would be off using something like preprocess (or refine).

const schema = z
  .preprocess(val => val ?? Math.random(), z.number())
  .openapi('Schema');

this would result in the following OpenAPI schema:

"Schema": {
  "type": "number",
  "nullable": true
}

note that from an API standpoint having nullable: true is correct since you can pass an empty argument and that the default would appear on an application level. And if you want to have an indication that there is a defaul you can alter it like that:

const schema = z
  .preprocess(val => val ?? Math.random(), z.number())
  .openapi('Schema', { default: '<a-generated-cuid>'}); // you can add whatever you want here

Since I believe this is the way that this library should work I will be closing the issue. Hope my suggestions help you out. And if you still feel like there should be a fix on out end - feel free to re-open the issue and/or open up a new one with further explanation.