-
Hi, I am running into a problem where a schema is already registered. I am using an apiMap object that contains a list of api's to be registered in the openapi document. The parameters, body or response refer to zod schemas that can be used multiple times, ie user/read and user.save return the same schema. I want to use the reference method but if i transform every schema like so: const setSchema = (zod_schema: z.ZodTypeAny) {
return zod_schema.openapi({
description: name,
ref: `${name}`
})
} and the snippet to generate the document for (const [name, api] of apiMap.entries()) {
paths[api.path!] = {}
let path: ZodOpenApiOperationObject = {
operationId: api.path,
summary: api.description,
responses: {
'200': {
description: 'Successful operation',
content: {
'application/json': {
schema: setSchema(api.response)
},
},
},
}
};
// we need to update the schemas for all parameter types
// and add the openapi extension
let parameters: any = {}
if (api.params) {
const paramTypes: Array<'query' | 'path' | 'header'> = ['query', 'path', 'header'];
paramTypes.forEach(paramType => {
if (api.params![paramType]) {
Object.entries(api.params![paramType]).forEach(([key, param]) => {
api.params![paramType]![key] = setSchema(param);
});
parameters[paramType] = z.object(api.params![paramType]);
}
});
console.log(parameters)
path.requestParams = parameters;
}
if (api.body) {
path.requestBody = {
content: {
'application/json': {
schema: setSchema(api.body)
},
}
}
}
paths[api.path!][api.method] = path
}
// Initialize the OpenAPI document
const document = createDocument({
openapi: '3.1.0',
info: {
title: 'Flying-Pillow Public API',
description: 'Open API definition for the Flying-Pillow system',
termsOfService: 'The API is FlyingPillow proprietary. Used at your own risk',
version: '1.0.0'
},
servers: [
{
url: host,
description: 'Public API endpoint for the Flying-Pillow services'
}
],
paths
}); An entry in the apiMap: ApiMap.set('/api/openapi', {
path: '/api/openapi',
params: {
query: {
format: z.enum(['yaml', 'json']).default('json').describe('format')
}
},
description: 'OpenAPI JSON Definition',
method: 'get',
fn: openapi,
response: z.object({ openapi: z.string() }).describe('Open API formatted JSON/YAML definition'),
tags: ['system'],
access: ['anonymous']
}); And the error
I hope i am not overcomplicating things here, but i use a typescript decorator to generate the ApiMap that automatically registers an entry in the ApiMap. Maybe i should register the different schema's manually? I have tried that but run into the same problem. Thanks for your response, Ronald |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
When you use the eg. const AString = z.string();
const ARegisteredString = AString().openapi({ ref: 'registered' });
// If you were to try and register AString again:
const BRegisteredString = AString().openapi({ ref: 'registered' });
ARegisteredString === BRegisteredString // false;
// Instead, you want to try and pass around `ARegisteredString`
const OtherSchema = z.object( { a: ARegisteredString }); |
Beta Was this translation helpful? Give feedback.
When you use the
.openapi()
method, it returns a new instance of your schema. This library will store that specific instance and when it runs into it, it will generate a reference instead.eg.