Zod 스키마를 사용하여 OpenAPI v3.x 문서를 생성하는 Typescript 라이브러리
npm
, yarn
또는 pnpm
통해 설치:
npm install zod zod-openapi
# # or
yarn add zod zod-openapi
# # or
pnpm install zod zod-openapi
이는 Zod를 변형하여 추가 .openapi()
메서드를 추가합니다. 진입점 상단에서 이를 호출하세요. 선호도에 따라 두 가지 방법으로 이를 달성할 수 있습니다.
import 'zod-openapi/extend' ;
import { z } from 'zod' ;
z . string ( ) . openapi ( { description : 'hello world!' , example : 'hello world' } ) ;
이는 대상으로 지정하려는 특정 Zod 인스턴스 또는 다른 라이브러리의 Zod 인스턴스가 있는 경우 유용합니다.
import { z } from 'zod' ;
import { extendZodWithOpenApi } from 'zod-openapi' ;
extendZodWithOpenApi ( z ) ;
z . string ( ) . openapi ( { description : 'hello world!' , example : 'hello world' } ) ;
.openapi()
특정 Zod 유형에 메타데이터를 추가하려면 .openapi()
메서드를 사용하세요. .openapi()
메서드는 다음 옵션이 포함된 객체를 사용합니다.
옵션 | 설명 |
---|---|
OpenAPI 옵션 | 이는 SchemaObject에 추가할 모든 옵션을 사용합니다. |
effectType | Zod 효과의 생성 유형을 재정의하는 데 사용 |
header | 응답 헤더에 대한 메타데이터를 제공하는 데 사용 |
param | 요청 매개변수에 대한 메타데이터를 제공하는 데 사용 |
ref | 이를 사용하여 스키마를 재사용 가능한 구성 요소로 자동 등록합니다. |
refType | 문서에서 참조되지 않은 구성요소의 생성 유형을 설정하려면 이를 사용합니다. |
type | 생성된 유형을 재정의하려면 이를 사용합니다. 이것이 제공되면 메타데이터가 생성되지 않습니다. |
unionOneOf | 단일 ZodUnion이 anyOf 대신 oneOf 출력하도록 하려면 true 로 설정하세요. 전역 옵션은 CreateDocumentOptions를 참조하세요. |
createDocument
OpenAPI 문서 객체를 생성합니다.
import 'zod-openapi/extend' ;
import { z } from 'zod' ;
import { createDocument } from 'zod-openapi' ;
const jobId = z . string ( ) . openapi ( {
description : 'A unique identifier for a job' ,
example : '12345' ,
ref : 'jobId' ,
} ) ;
const title = z . string ( ) . openapi ( {
description : 'Job title' ,
example : 'My job' ,
} ) ;
const document = createDocument ( {
openapi : '3.1.0' ,
info : {
title : 'My API' ,
version : '1.0.0' ,
} ,
paths : {
'/jobs/{jobId}' : {
put : {
requestParams : { path : z . object ( { jobId } ) } ,
requestBody : {
content : {
'application/json' : { schema : z . object ( { title } ) } ,
} ,
} ,
responses : {
'200' : {
description : '200 OK' ,
content : {
'application/json' : { schema : z . object ( { jobId , title } ) } ,
} ,
} ,
} ,
} ,
} ,
} ,
} ) ;
{
"openapi" : " 3.1.0 " ,
"info" : {
"title" : " My API " ,
"version" : " 1.0.0 "
},
"paths" : {
"/jobs/{jobId}" : {
"put" : {
"parameters" : [
{
"in" : " path " ,
"name" : " jobId " ,
"description" : " A unique identifier for a job " ,
"schema" : {
"$ref" : " #/components/schemas/jobId "
}
}
],
"requestBody" : {
"content" : {
"application/json" : {
"schema" : {
"type" : " object " ,
"properties" : {
"title" : {
"type" : " string " ,
"description" : " Job title " ,
"example" : " My job "
}
},
"required" : [ " title " ]
}
}
}
},
"responses" : {
"200" : {
"description" : " 200 OK " ,
"content" : {
"application/json" : {
"schema" : {
"type" : " object " ,
"properties" : {
"jobId" : {
"$ref" : " #/components/schemas/jobId "
},
"title" : {
"type" : " string " ,
"description" : " Job title " ,
"example" : " My job "
}
},
"required" : [ " jobId " , " title " ]
}
}
}
}
}
}
}
},
"components" : {
"schemas" : {
"jobId" : {
"type" : " string " ,
"description" : " A unique identifier for a job " ,
"example" : " 12345 "
}
}
}
}
createDocument
문서 생성 방법을 수정하는 데 사용할 수 있는 선택적 CreateDocumentOptions
인수를 사용합니다.
const document = createDocument ( details , {
defaultDateSchema : { type : 'string' , format : 'date-time' } , // defaults to { type: 'string' }
unionOneOf : true , // defaults to false. Forces all ZodUnions to output oneOf instead of anyOf. An `.openapi()` `unionOneOf` value takes precedence over this one.
} ) ;
createSchema
등록된 구성 요소와 함께 OpenAPI 스키마 개체를 생성합니다. OpenAPI 3.1.0 스키마 개체는 JSON 스키마와 완벽하게 호환됩니다.
import 'zod-openapi/extend' ;
import { z } from 'zod' ;
import { createSchema } from 'zod-openapi' ;
const jobId = z . string ( ) . openapi ( {
description : 'A unique identifier for a job' ,
example : '12345' ,
ref : 'jobId' ,
} ) ;
const title = z . string ( ) . openapi ( {
description : 'Job title' ,
example : 'My job' ,
} ) ;
const job = z . object ( {
jobId ,
title ,
} ) ;
const { schema , components } = createSchema ( job ) ;
{
"schema" : {
"type" : " object " ,
"properties" : {
"jobId" : {
"$ref" : " #/components/schemas/jobId "
},
"title" : {
"type" : " string " ,
"description" : " Job title " ,
"example" : " My job "
}
},
"required" : [ " jobId " , " title " ]
},
"components" : {
"jobId" : {
"type" : " string " ,
"description" : " A unique identifier for a job " ,
"example" : " 12345 "
}
}
}
createSchema
다음 옵션과 함께 CreateDocumentOptions와 동일한 옵션을 사용할 수도 있는 선택적 CreateSchemaOptions
매개변수를 사용합니다.
const { schema , components } = createSchema ( job , {
schemaType : 'input' ; // This controls whether this should be rendered as a request (`input`) or response (`output`). Defaults to `output`
openapi: '3.0.0' ; // OpenAPI version to use, defaults to `'3.1.0'`
components: { jobId : z . string ( ) } // Additional components to use and create while rendering the schema
componentRefPath: '#/definitions/' // Defaults to #/components/schemas/
} )
쿼리, 경로, 헤더 및 쿠키 매개변수는 다음과 같이 method
키 아래의 requestParams
키를 사용하여 생성할 수 있습니다.
createDocument ( {
paths : {
'/jobs/{a}' : {
put : {
requestParams : {
path : z . object ( { a : z . string ( ) } ) ,
query : z . object ( { b : z . string ( ) } ) ,
cookie : z . object ( { cookie : z . string ( ) } ) ,
header : z . object ( { 'custom-header' : z . string ( ) } ) ,
} ,
} ,
} ,
} ,
} ) ;
보다 전통적인 방식으로 매개변수를 선언하려면 매개변수 키를 사용하여 선언할 수도 있습니다. 그러면 정의가 모두 결합됩니다.
createDocument ( {
paths : {
'/jobs/{a}' : {
put : {
parameters : [
z . string ( ) . openapi ( {
param : {
name : 'job-header' ,
in : 'header' ,
} ,
} ) ,
] ,
} ,
} ,
} ,
} ) ;
일반적으로 미디어 유형을 선언하는 경우 다음과 같이 schema
Zod 스키마로 설정합니다.
createDocument ( {
paths : {
'/jobs' : {
get : {
requestBody : {
content : {
'application/json' : { schema : z . object ( { a : z . string ( ) } ) } ,
} ,
} ,
} ,
} ,
} ,
} ) ;
스키마에 OpenAPI 구문을 사용하려면 대신 OpenAPI 스키마를 schema
필드에 추가하면 됩니다.
요청 본문과 마찬가지로 다음과 같이 schema
Zod 스키마로 설정하면 됩니다. headers
키를 사용하여 응답 헤더를 설정할 수 있습니다.
createDocument ( {
paths : {
'/jobs' : {
get : {
responses : {
200 : {
description : '200 OK' ,
content : {
'application/json' : { schema : z . object ( { a : z . string ( ) } ) } ,
} ,
headers : z . object ( {
'header-key' : z . string ( ) ,
} ) ,
} ,
} ,
} ,
} ,
} ,
} ) ;
createDocument ( {
paths : {
'/jobs' : {
get : {
callbacks : {
onData : {
'{$request.query.callbackUrl}/data' : {
post : {
requestBody : {
content : {
'application/json' : { schema : z . object ( { a : z . string ( ) } ) } ,
} ,
} ,
responses : {
200 : {
description : '200 OK' ,
content : {
'application/json' : {
schema : z . object ( { a : z . string ( ) } ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ) ;
OpenAPI를 사용하면 재사용 가능한 구성 요소를 정의할 수 있으며 이 라이브러리를 사용하면 이를 두 가지 별도의 방법으로 복제할 수 있습니다.
createDocument
의 예를 취하고 대신 다음과 같이 title
생성하면
const title = z . string ( ) . openapi ( {
description : 'Job title' ,
example : 'My job' ,
ref : 'jobTitle' , // <- new field
} ) ;
문서 전체의 스키마에서 title
사용될 때마다 참조로 생성됩니다.
{ "$ref" : " #/components/schemas/jobTitle " }
그런 다음 title
문서의 구성 요소 섹션 내에서 스키마로 출력됩니다.
{
"components" : {
"schemas" : {
"jobTitle" : {
"type" : " string " ,
"description" : " Job title " ,
"example" : " My job "
}
}
}
}
이는 덜 반복적인 Open API 문서를 만드는 매우 강력한 방법이 될 수 있습니다. 참조를 포함하기 위해 공용체의 모든 스키마를 요구하는 판별자 매핑과 같은 일부 Open API 기능이 있습니다.
ref
추가하는 대신 스키마를 등록하는 또 다른 방법은 이를 구성 요소에 직접 추가하는 것입니다. 이는 여전히 ref
와 동일한 방식으로 작동합니다. 따라서 해당 Zod 유형을 만날 때마다 이를 참조로 대체합니다.
예.
createDocument ( {
components : {
schemas : {
jobTitle : title , // this will register this Zod Schema as jobTitle unless `ref` in `.openapi()` is specified on the type
} ,
} ,
} ) ;
불행하게도 이 라이브러리의 제한 사항으로 인해 구성 요소에 전달하는 스키마에 .openapi()
필드 또는 .describe()
연결해야 합니다. 그렇지 않으면 구성 요소 생성의 모든 기능을 얻지 못할 수 있습니다. 따라서 수동 등록보다는 자동 등록 구성 요소를 활용하는 것이 좋습니다.
쿼리, 경로, 헤더 및 쿠키 매개변수도 유사하게 등록할 수 있습니다.
// Easy auto registration
const jobId = z . string ( ) . openapi ( {
description : 'Job ID' ,
example : '1234' ,
param : { ref : 'jobRef' } ,
} ) ;
createDocument ( {
paths : {
'/jobs/{jobId}' : {
put : {
requestParams : {
header : z . object ( {
jobId ,
} ) ,
} ,
} ,
} ,
} ,
} ) ;
// or more verbose auto registration
const jobId = z . string ( ) . openapi ( {
description : 'Job ID' ,
example : '1234' ,
param : { in : 'header' , name : 'jobId' , ref : 'jobRef' } ,
} ) ;
createDocument ( {
paths : {
'/jobs/{jobId}' : {
put : {
parameters : [ jobId ] ,
} ,
} ,
} ,
} ) ;
// or manual registeration
const otherJobId = z . string ( ) . openapi ( {
description : 'Job ID' ,
example : '1234' ,
param : { in : 'header' , name : 'jobId' } ,
} ) ;
createDocument ( {
components : {
parameters : {
jobRef : jobId ,
} ,
} ,
} ) ;
응답 헤더도 비슷하게 등록할 수 있습니다.
const header = z . string ( ) . openapi ( {
description : 'Job ID' ,
example : '1234' ,
header : { ref : 'some-header' } ,
} ) ;
// or
const jobIdHeader = z . string ( ) . openapi ( {
description : 'Job ID' ,
example : '1234' ,
} ) ;
createDocument ( {
components : {
headers : {
someHeaderRef : jobIdHeader ,
} ,
} ,
} ) ;
전체 응답도 등록 가능
const response : ZodOpenApiResponseObject = {
description : '200 OK' ,
content : {
'application/json' : {
schema : z . object ( { a : z . string ( ) } ) ,
} ,
} ,
ref : 'some-response' ,
} ;
//or
const response : ZodOpenApiResponseObject = {
description : '200 OK' ,
content : {
'application/json' : {
schema : z . object ( { a : z . string ( ) } ) ,
} ,
} ,
} ;
createDocument ( {
components : {
responses : {
'some-response' : response ,
} ,
} ,
} ) ;
콜백도 등록 가능
const callback : ZodOpenApiCallbackObject = {
ref : 'some-callback'
post : {
responses : {
200 : {
description : '200 OK' ,
content : {
'application/json' : {
schema : z . object ( { a : z . string ( ) } ) ,
}