메인 콘텐츠로 바로 가기
개발 모바일

OpenAPI TypeScript: 타입, 클라이언트 및 유효성 검사 생성

OpenAPI TypeScript 생성이 어떻게 작동하는지 끝까지 배워보세요. 타입을 생성하고, 클라이언트를 연결하고, 런타임에 유효성 검사를하고, CI에서 안전하게 배포하세요.

OpenAPI TypeScript: 타입, 클라이언트 및 유효성 검사 생성

팀에 있는 API pipeline이 팀에게 거짓말을 시작할 때 일반적으로 그 순간을 발견할 수 있습니다. 스키마가 변경되면 생성된 타입이 불만 없이 업데이트되고 PR이 초록색으로 가고 somebody는 프론트 엔드에서 오래된 응답 형태를 계속 읽고 있지만 wrapper가 오류를 숨겨주고 있습니다. 그게 OpenAPI TypeScript 문제, 그것이 생성기가 인터페이스를 내뱉을 수 있는지 여부가 아닌 것입니다.

유용한 질문은 더 어려운 것입니다. 스키마, 전송 및 유효성 검사 간에 어떤 계약을 원하고 어떤 부분이 빌드 타임에 빠르게 실패해야 하는지, 그리고 런타임에 누출되는지 여부를 결정해야 합니다. 한 번 프레임을 오픈API 타입스크립트 OpenAPI TypeScript

목차

왜 생성된 타입은 안전한 API과 다르다.

팀원이 옵션 응답 필드를 추가하는 PR를 병합합니다. 생성된 파일은 깨끗하게 업데이트되고 diff는 흥미롭지 않으며 모든 팀원은 다음 단계로 넘어갑니다. 그런 다음 프론트 엔드에서는 "임시로" cast된 수식에 의해 "영구적으로" 읽어 들이는 더 오래된 형태를 계속 읽습니다. as any, 그리고 프로덕션은 계약이 변경되지 않았다는 것처럼 행동합니다.

그것이 생성된 타입의 함정입니다. TypeScript는 생성된 타입을 소비하는 code만 보호할 수 있습니다., 그리고 전송層이 계약을 다시 지우지 않는 한만이如此합니다. OpenAPI 측에서는 스키마를 제공하지만, 모든 호출자가 그것을 존중하는지 보장하지는 않습니다. 생성된 타입에 대한 API 연결에 대한 이해 의 토론은 단일 도구에 대한 대화에서 시스템이 연결되는 방식으로 대화의 방향을 바꾸는 데 유용합니다.

실패가 숨겨져 있는 곳

가장 일반적인 브레이크 포인트는 흥미롭지 않습니다. 스키마 드리프트 OpenAPI 스펙과 배포된 서비스가 일치하지 않아 발생하는 문제입니다. 부분적 커버리지 만족하는 경로만 모델링한 스펙에서만 나타난다. 그러나 앱은 문서화되지 않은 에지 케이스를 의존한다. 수동으로 작성된 wrapper 타입이 약화되는 곳이 많다. 특히 alguien이 "빠르게 움직이고" 싶어 "or any a loose response cast"를 사용할 때이다.

실용적인 규칙: wrapper가 거짓말할 수 있다면, 생성기는 당신을 구원할 수 없다.

There’s also a runtime gap. TypeScript types disappear after compilation, so they can’t reject malformed JSON coming over the wire. The network does not care what your editor inferred, and that’s why a generated client is only one layer in a safer API pipeline.

더 광범위한 운영 문제는 보안과 계약 규율이다. 개발자 편의성만을 생각하는 것이 아니다. API 계약이 더 큰 앱 라이프 사이클에 어떻게 통합되는지 구조화된 시각을 원한다면, 앱 스토어 준수성을 위한 API 보안 표준에 대한 내부 가이드 API 보안 표준에 대한 내부 가이드 성숙한 방식으로 생각하는 것이 중요하다.

__CAPGO_KEEP_0__ OpenAPI TypeScript 이것이다. 이것은 엄격한 스키마-타입 연결을 제공하지만, 요청을 검증하지 않으며, 런타임 페이로드 형태를 강제하지도 않고, 느슨한 wrapper가 모든 것을 무너뜨리도록 하지도 않는다. 생성기는 쉽게 20%지만, 나머지 80%는 pipe line 설계이다. 이것은 팀이 신뢰를 얻거나 거짓된 자신감을 쌓는 것을 결정한다.

OpenAPI Spec에서 TypeScript 타입을 생성하는 방법

https://openapi-ts.dev에서 스크린샷

가장 가벼운 유용한 설정은 일반적으로 실제 리포지토리 churn을 견딜 수 있는 설정이다. OpenAPI spec을 같은 리포지토리에 유지하고, 커밋된 타입 파일을 생성하고, CI에서 드리프트를 표시하는 대신, 누군가가 리프레시 단계를 기억하도록 의존하지 않는다. 명령어 npx openapi-typescript ./openapi.yaml -o ./src/types/api.d.ts 리뷰어들이 다른 소스 변경과 같이 검토할 수 있는 결정적인 출력 파일을 제공한다.

실제로 중요하는 플래그

The -o 생성된 타입이 readonly 의도 값을 보존하고, 스키마 순서가 의미 없는 변경으로 인해 diff가 instable 할 때 유용하다. --immutable 팀이 생성된 표면에서 enum 대신 union을 선호할 때 중요하다. --alphabetize 생성된 타입이 readonly 의도 값을 보존하고, 스키마 순서가 의미 없는 변경으로 인해 diff가 instable 할 때 중요하다. --enum 팀이 생성된 표면에서 enum 대신 union을 선호할 때 중요하다.

프로젝트의 문서는 범위에 대해 명확히 설명하고 있습니다. 그것은 타입 생성기입니다. 그것은 클라이언트 런타임이나 요청 레이어가 아니며, 그 제한은 가볍고 타입 우선 설정을 원할 때 도움이 됩니다. 그들의 저장소도 이 도구의 유지 관리 모델을 보여주고 있습니다. 그 이유는 오픈 소스 도구가 프로덕션에서 유지 관리가 가능하기 때문입니다. 문서와 릴리즈가 활발하게 유지되는 경우, 오픈 소스 유지 관리의 이점에 대해 논의한 오픈 소스 유지 관리의 경우에서 설명한 바와 같이. 그 프로젝트의 GitHub 저장소와 CLI 문서.

저장소와 package.json __CAPGO_KEEP_1__ git diff 문서를 읽어보시면 그 자세한 내용을 알 수 있습니다.

Wire generation into compilerOptions.noUncheckedIndexedAccess so additionalProperties become T | undefined, 이는 호출 사이트에서 더 안전한 인덱싱을 강제하고 사용하는 것을 추천합니다. oneOf 혼합하지 않고 단독으로 사용하는 것이 좋습니다. $defs 루트에 두면 됩니다. openapi-typescript 생성된 출력에서 사라질 수 있습니다. any생성된 출력에서 사라질 수 없습니다.

명시적이면 됩니다.

버전 관리하에 스펙을 두고, 빌드 시 재생성하고, 생성된 파일을 커밋하고, 타입 체커가 불일치로 인한 오류를 신고하기 전에 anyone이 병합하기 전에, 안정적인 계약 경계를 제공합니다.

Pure Types, Full Clients, No Codegen 사이의 선택

패턴 빌드 시점 출력 파일 번들 중량 최적의 맞춤
순수 타입에 얇은 wrapper 빠른 적은 thấp 제어를 원하는 팀과 작은 런타임 표면
전체 클라이언트 코드 생성 느린 많은 높은 빠른 전달과 자동화된 작업을 원하는 팀
코드 생성 요청 빌더 없음 빠른 없음 또는 최소한의 낮은 한 개의 코드베이스 앱이 수동으로 전송 논리를 선호하는 경우

API가 경험하는 churn에 따라 팀, 리포지토리, pipe line 형태를 선택하는 것이 아니라 도구가 승리하는지 여부가 아니라. 2025년 대규모 OpenAPI 스펙(약 75,000줄, 2MB, 약 1,200개 연산)에 대한 벤치마크에서, openapi-typescript 약 75,000줄, 2MB, 약 1,200개 연산 약 1.5초 평균 약 1.5초 평균 약 8.0초 평균 약 5.5초 @hey-api/openapi-ts, 평균 약 위에서 Orval, 그리고 18.1 초 위에서 Kubb, 한 파일을 생성하는 대신 16 위에서 hey-api, 2,719 위에서 Orval, 그리고 3,877 위에서 Kubb (성능 테스트 세부 정보).

순수 타입은 제어를 선호합니다

순수 타입 설정은 수동으로 요청 레이어와 잘 어울립니다. 런타임이 작고 API 표면이 단순해질 수 있기 때문입니다. 이게 번들러에 민감한 프론트 엔드와, 하나의 팀이 스펙과 소비자 모두를 관리하는 앱에서 중요합니다. 개발자 경험은 단순한 구문으로만 구성된 것이 아니라는 것을 잊지 마세요. 개발자 경험 관점에서 클라이언트 code이 짧고 명확하며 검토 가능한 경우 더 쉽게 판단할 수 있습니다.

전체 클라이언트는 전달 속도에 중점을 둡니다.

openapi-generator, hey-api, Orval, 그리고 Kubb 모두 타입 외에도 요청 메서드, 모델, 플러밍을 함께 생성하려고 시도합니다. 이는 백엔드와 프론트엔드 팀 간의 큰 전달에서 특히 유용합니다. 그러나 벤치마크 상에 명시된 것과 같이, 더 많은 생성된 파일, 더 많은 런타임 표면, 더 많은 빌드摩擦가 발생합니다.

코드 생성이 없는 경우에는 로컬 리팩터링이 좋습니다.

타입된 요청 빌더 및 fetch wrappers는 한 코드베이스가 양쪽 끝을 소유하고 API 변경이 밀접하게 조정되는 경우 잘 작동합니다. 그러나 유지보수 규율이 필요합니다. 프로듀서와 컨슈머 사이에 여러 팀과 저장소가 존재할수록, 수동으로 요청 레이어를 작성한 경우 드리프트가 발생할 수 있습니다. 이를 방지하려면 강력한 계약 테스트를 강제해야 합니다.

핵심적인 결정 지점은 이념적이지 않습니다. 배포 비용이 제한된 경우, 순수 타입이 매력적입니다. 팀이 최대 scaffold를 원하고 출력을 흡수할 수 있다면, 전체 클라이언트는 설정 시간을 단축합니다. 계약이 가까운 경우, 최소한의 이동 부분을 원한다면, 코드 생성이 없는 요청 빌더가 올바른 내부 거래일 수 있습니다.

Fetch 또는 Axios를 둘러싸는 얇은 타입된 클라이언트를 연결하는 방법

타입된 클라이언트 wrapper 프로세스를 minh họa하는 다이어그램. 생성된 TypeScript API 정의를 사용하여 웹 요청에 대한 정의를 사용합니다.

A thin wrapper은 생성기가 멈추고 code 애플리케이션 code이 시작되는 곳입니다. wrapper는 하나의 함수를 노출하고, 타입이 지정된 매개 변수와 쿼리 객체를 받으며, 호출을 전달하여 fetch 또는 주입된 axios 인스턴스에 대한 호출을 시도하지 말아야 합니다. 대부분의 프로덕션 설정에서, 그 레이어는 30–60 줄 30–60 줄 이러한 정신 모델이 유지되는 곳입니다:

경로 매개 변수는 타입이 지정되어 있으므로

  • 따라서 __CAPGO_KEEP_0__이 호출되지 않습니다. so /users/{id} 따라서 선택적 필터가 문자열로 변하지 않습니다. id.
  • 응답 본문은 타입이 지정되어 있습니다. 생성기가 멈추고 __CAPGO_KEEP_0__ 애플리케이션이 시작되는 곳입니다.
  • 생성된 타입이 이미 대부분의 형태를 가지고 있기 때문에 남아 있습니다. 이러한 code을 파싱할 수 있는 code을 신뢰할 수 있습니다. narrow shape이 기대하는 것과 일치합니다.

그런 wrapper는 의도적으로 재미없습니다. 그것은 재시도, 변환, 또는 인증 정책을 만드는 것을 피해야합니다. 그것은 유형화된 연산에서 요청을 전송층으로 옮기고 유형화된 결과를 다시 올려줍니다.

__CAPGO_KEEP_0__을 재미없고 의존성-light로 유지하면, 모든 미래의 코드 생성 변경이 앱에 반영되지 않습니다.

API 스크립트에서 일치하지 않는 부분을 패치하는 일반적인 오류는 as any Axios를 선호하는 팀의 경우, 패턴은 동일하지만 Transport 구현만 변경됩니다. 더 간단한 브라우저 __CAPGO_KEEP_0__을 원하는 팀의 경우, __CAPGO_KEEP_0__은 종종 충분합니다. 중요한 것은 요청 함수가 생성된 경로 타입을 수용하고 유형화된 응답을 반환하는 것입니다. 나중에 변형되도록 loosely shaped 객체를 반환하는 것이 아닙니다.

이 seam을 잘 사용하면, code은 앱이 유형화된 연산을 보는 대신 ad hoc 요청 code을 보는 대신 스키마가 spec에, Transport가 wrapper에, 앱이 유형화된 연산을 보는 대신 ad hoc 요청 code을 보는 대신 스키마가 spec에, Transport가 wrapper에 있습니다. fetch __CAPGO_KEEP_0__을 잘 사용하면, __CAPGO_KEEP_0__은 앱이 유형화된 연산을 보는 대신 ad hoc 요청 __CAPGO_KEEP_0__을 보는 대신 스키마가 spec에, Transport가 wrapper에 있습니다.

openapi typescript zod, ajv, 또는 io-ts와 함께 런타임 유효성 검사 추가 code

__CAPGO_KEEP_0__

TypeScript 타입은 런타임에서 사라지고 네트워크는 편집기의 자신감에 관심이 없습니다. 따라서 안전한 패턴은 '타입을 생성하고 희망'이 아니라 '타입을 생성하고 에지에서 데이터가 앱에 들어오는 곳에서 검증'입니다. 생성된 스키마는 진실의 근원이며, 라이브러리들처럼 zod, ajv, 그리고 io-ts 은 에지에서 경계 점검을 처리하는 것을 처리합니다.

Validate 데이터가 앱에 들어오는 곳에서

React 앱의 경우, 요청이 해결되고 데이터가 상태에 들어가기 전에 일반적으로 에지입니다. 서버의 경우, 데이터가 데이터베이스에 기록되기 전에 또는 비즈니스 규칙에 넘겨지기 전에 에지입니다. 규칙은 간단합니다. 검증을 경계 근처에 유지하고 기능 code에서 수동 검사를 퍼뜨리지 마세요.

A zod 은 스키마가 옵션 필드를 검증하고 런타임 검증을 생성된 생성자와 일치시킵니다.

import { z } from "zod";

const WeatherForecastSchema = z.object({
  date: z.string(),
  temperatureC: z.number(),
  summary: z.string().nullable(),
  temperatureF: z.number().optional(),
});

은 서버에서 높은 처리량 JSON 스키마 검증을 원할 때 강력한 선택입니다. 여전히 ajv 은 이미 io-ts 스타일의 구성성을 사용하는 팀에도 적합합니다. fp-ts 은 너무 늦게 검증하는 것을 오류로 여깁니다. 데이터가 앱에 들어가기 전에, 타입 시스템은 이미 우회되었으며 버그는 숨을 곳을 찾았습니다. 에지에서 데이터가 앱에 들어오는 곳에서 검증하는 짧은 가이드입니다.

The big mistake is validating too late. If the payload crosses into your app first, the type system has already been bypassed and the bug has a place to hide. A short guide on 자바스크립트 단위 테스트 이 마음가짐과 잘 어울립니다. 단위 테스트와 경계 검증은 모두 나쁜 가정에 대한 조기 발견이 가장 잘 작동하기 때문입니다.

깨끗한 계층 구조는 예측 가능합니다. 오픈 API 타입스크립트 code가 생성한 계약, 검증기는 런타임 페이로드를 검사하고 앱은 두 단계 모두 통과한 데이터만 볼 수 있습니다. 이는 정적 타입이 불신스러운 응답을 경찰하는 것보다 훨씬 더 좋은 경계입니다.

CI에 Generation, Validation, Contract 테스트를 넣기

https://github.com에서 가져온 스크린샷

pipeline이 지속되면 계약을 게이트로 변환합니다. Regenerate types, fail on drift, run tsc --noEmit, API shape을 mock 또는 계약 도구와 연동하여 merge하기 전에 연습합니다. 만약 생성기 버전을 API에 고정하면 package.json, 두 엔지니어도 같은 스펙에서 다른 출력을 생성할 수 없습니다.

단순한 GitHub Actions shape

실용적인 워크플로우는 다음과 같습니다:

  1. 리포지토리나 생성된 소스에서 스펙을 pull합니다.
  2. 타입을 재생성합니다.
  3. 작업을 실패시킵니다. git diff 변경이 보입니다.
  4. 실행 tsc --noEmit.
  5. 컨트랙트 테스트를 프라즘 또는 스펙트럴 백드드 체크를 지원하는 가상 서버에 실행합니다.

Mock 서버를 실행하여 계약 테스트를 수행합니다. 예를 들어, Prism 또는 Spectral-backed 체크를 사용합니다.

A mock server is especially useful when backend and frontend work are separated by time or team boundaries. It gives consumer code a predictable API surface while still checking the actual contract rather than a hard-coded fixture. The 통합 빌드 설정 가이드 CI 설정 가이드

제네레이터 버전을 pin하는 것은 코드 제네레이션 PIPELINE에서 가장 끔찍한 실패 중 하나를 피하는 데 도움이 됩니다. 제네레이터 버전이 로컬로 업그레이드된 개발자와 업그레이드되지 않은 개발자가 있을 때, 생성된 파일은 노이즈가 아닌 신호가 될 수 있습니다. CI는 이러한 노이즈를 피해야 합니다.

결과적으로 스키마 변경, 타입 생성, 컴파일러 체크, 계약 테스트가 모두 서로를 강화하는 PIPELINE이 됩니다. 이러한 워크플로가 진실되게 됩니다.

유지 보수 가능한 PipeLine, 성능, 최종 확인 목록

OpenAPI TypeScript PipeLine을 위한 소프트웨어 개발 프로젝트 유지 보수에 대한 4 가지 주요 단계를 보여주는 확인 목록입니다.

생존하는 PipeLine은 지속적인 관리를 하는 PipeLine입니다. 스펙 버전을 관리하고, 스키마 변경을 code과 같이 검토하고, 생성기 버전을 고정하고, 깨진 변경 사항이 승인되는 방법을 문서화합니다. 프로세스가 불분명하면 사람들은 이를 회피하고, 생성된 타입이 강제가 아닌 장식으로 변하게 됩니다.

몇 가지 성능 조절기가 실제로 중요합니다

incremental generation은 monorepos에서 스펙이 자주 변경되지만 단일 패키지만 소비하는 경우에 도움이 됩니다. tsc --incremental 중복된 컴파일러 작업을 제거하고, 프로덕션 빌드에서 필요하지 않은 출력 플래그를 비활성화하여 생성된 표면을 작게 유지할 수 있습니다. 실제로 가장 큰 이익은 여전히 사회적이지 않고 기술적이지 않습니다. 예측 가능한 PipeLine은 지능적인 PipeLine보다 더 자주 실행됩니다.

아래에 나열된 확인 목록은 유지 보수에 가장 중요한 목록입니다:

  • 버전 고정: 버전을 openapi-typescript 버전(버전) package.json 스키마 검토:
  • ]} 변경 사항은 계약 변경 사항으로 간주하고, 관리 업무로 간주하지 마십시오.
  • 드리프트 감지: CI에서 재생성하고 diff가 발생하면 실패하십시오.
  • Edge 검증: 미신뢰할 수 있는 페이로드를 앱 상태나 영속성에 도달하기 전에 해석하십시오.
  • 계약 테스트: code의 mock-backed 확인을 통해 소비자가 code이 스키마와 일치하는지 증명하십시오.
  • 파괴적인 변경 정책: 형태 변경에 대한 승인자와 클라이언트에게 알리기 위한 방법을 기록하십시오.

그게 게이트를 포함한 pipeline이 생성하는 타입만이 아니라, 계약을 보이게 만드는 것입니다. 계약의 가시성은 팀이 안전해 보이는 파일만으로 신뢰하지 않도록 합니다.

Capacitor 또는 Electron 앱을 배포하고자 하시며, 업데이트 PIPELINE이 동일한 discipline로 동작하고 싶으시다면, Capgo은 JavaScript, CSS, 복사본, 설정, 및 자산 수정을 빠르게 적용할 수 있는 실용적인 방법을 제공합니다. Visit Capgo 속도와 제어를 잃지 않고 릴리스 프로세스에 속도 제어 기능, 롤백 보호 기능 및 릴리스 제어 기능이 어떻게 통합되는지 알아보세요.

실시간으로 Capacitor 앱을 업데이트하라

웹层 버그가 실시간으로 살아 있다면, 앱 스토어 승인 대기 없이 Capgo를 통해 픽스를 배포하라. 사용자는 배경에서 업데이트를 받으면서 네이티브 변경은 일반적인 검토 경로에 남아있다.

최신 뉴스

Capgo은 전문적인 모바일 앱을 만들기 위해 필요한 최고의 통찰력을 제공합니다.