Skip to content

Open API Spec 스키마 타입 정리

KimDaeGeon edited this page Jan 15, 2026 · 2 revisions

Note

본 문서는 openapi-types@12.1.3 버전을 기준으로 OAS(OpenAPI Spec) Schema 의 구조와 타입 관계를 정리했습니다

1. 버전별 문서타입 (V2, V3, V3.1)

openapi-types 에서 최상위 문서 타입(OpenAPI.Document)은 union 타입으로 구성되어있음

export declare namespace OpenAPI {
    type Document<T extends {} = {}> = |
                 OpenAPIV2.Document<T> | 
                 OpenAPIV3.Document<T> | 
                 OpenAPIV3_1.Document<T>;
    // ...
}

런타임에서 Document 는 V2, V3, V3.1 을 포함하기 때문에 버전판별을 위한 type guard 를 설정해야 이후 구조 탐색이 원활해짐

// packages/patchlogr-oas/src/utils/oasVersionUtils.ts

export function isOpenAPIV2(doc: OpenAPI.Document): doc is OpenAPIV2.Document {
    return "swagger" in doc && doc.swagger === "2.0";
}

export function isOpenAPIV3(doc: OpenAPI.Document): doc is OpenAPIV3.Document {
    return "openapi" in doc && doc.openapi.startsWith("3.");
}

1.1. OAS 3.0 (OpenAPIV3.Document), OAS 3.1 (OpenAPIV3_1.Document) 구조

A) info : 메타데이터

// 3.0
interface InfoObject {
    title: string;
    description?: string;
    termsOfService?: string;
    contact?: ContactObject;
    license?: LicenseObject;
    version: string;
}
// 3.1
interface InfoObject {
    title: string;
    description?: string;
    termsOfService?: string;
    contact?: ContactObject;
    license?: LicenseObject;
    version: string;
    summary?: string;
}
const docV3: OpenAPIV3.Document = {
  openapi: "3.0.x",
  info: {
    title: "Pet API",
    version: "1.0.0",
    description: "Example OpenAPI 3.0 doc",
    contact: { name: "API Team", email: "team@example.com" },
    license: { name: "Apache-2.0", url: "https://www.apache.org/licenses/LICENSE-2.0.html" },
  },
  servers: [{ url: "https://api.example.com", description: "prod" }],

  paths: {
    "/pets/{petId}": {
      summary: "Pet endpoint",

      // PathItemObject.parameters: (ReferenceObject | ParameterObject)[]
      parameters: [
        {
          name: "petId",
          in: "path",
          required: true,
          schema: { type: "string" }, // ✅ SchemaObject
        },
      ],

      // HttpMethods.get → OperationObject
      get: {
        operationId: "getPet",

        // OperationObject.parameters: (ReferenceObject | ParameterObject)[]
        parameters: [
          {
            name: "include",
            in: "query",
            required: false,
            schema: { type: "string", enum: ["basic", "full"] },
          },
        ],

        // requestBody: ReferenceObject | RequestBodyObject
        requestBody: {
          description: "Optional body for example",
          required: false,
          content: {
            "application/json": {
              schema: {
                type: "object",
                properties: {
                  traceId: { type: "string" },
                },
                required: ["traceId"],
              },
            },
          },
        },

        // responses: ResponsesObject (Record<string, ReferenceObject | ResponseObject>)
        responses: {
          "200": {
            description: "ok",
            headers: {
              "x-request-id": {
                schema: { type: "string" },
              },
            },
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    id: { type: "string" },
                    name: { type: "string" },
                  },
                  required: ["id", "name"],
                },
              },
            },
            links: {
              PetById: {
                operationId: "getPet",
                parameters: { petId: "$response.body#/id" },
              },
            },
          },
          "404": { description: "not found" },
        },

        security: [{ bearerAuth: [] }],
        deprecated: false,
      },
    },
  },

  // components: 재사용 창고
  components: {
    schemas: {
      Pet: {
        type: "object",
        properties: { id: { type: "string" }, name: { type: "string" } },
        required: ["id", "name"],
      },
    },
    securitySchemes: {
      bearerAuth: {
        type: "http",
        scheme: "bearer",
        bearerFormat: "JWT",
      },
    },
  },
};

Clone this wiki locally