# OpenAPI 3.0.3 공통 컨벤션 KT AI 기반 소상공인 이벤트 자동 생성 서비스의 모든 마이크로서비스 API 명세서에 적용되는 공통 컨벤션입니다. ## 목차 1. [기본 정보 섹션](#1-기본-정보-섹션) 2. [서버 정의](#2-서버-정의) 3. [보안 스키마](#3-보안-스키마) 4. [태그 구성](#4-태그-구성) 5. [엔드포인트 정의](#5-엔드포인트-정의) 6. [응답 구조](#6-응답-구조) 7. [에러 응답 구조](#7-에러-응답-구조) 8. [스키마 정의](#8-스키마-정의) 9. [메타데이터 주석](#9-메타데이터-주석) 10. [기술 명세 섹션](#10-기술-명세-섹션) 11. [예제 작성](#11-예제-작성) --- ## 1. 기본 정보 섹션 ### 1.1 OpenAPI 버전 ```yaml openapi: 3.0.3 ``` - **필수**: 모든 명세서는 OpenAPI 3.0.3 버전을 사용합니다. ### 1.2 Info 객체 ```yaml info: title: {Service Name} API description: | KT AI 기반 소상공인 이벤트 자동 생성 서비스 - {Service Name} API {서비스 설명 1-2줄} **주요 기능:** - {기능 1} - {기능 2} - {기능 3} **보안:** (보안 관련 서비스인 경우) - {보안 메커니즘 1} - {보안 메커니즘 2} version: 1.0.0 contact: name: Digital Garage Team email: support@kt-event-marketing.com ``` **필수 항목:** - `title`: "{서비스명} API" 형식 - `description`: 마크다운 형식으로 서비스 설명 작성 - 첫 줄: 프로젝트명과 서비스 역할 - 서비스 설명 - 주요 기능 목록 (bullet points) - 보안 관련 서비스의 경우 보안 섹션 추가 - `version`: "1.0.0" - `contact`: name과 email 필수 --- ## 2. 서버 정의 ### 2.1 서버 URL 구조 ```yaml servers: - url: http://localhost:{port} description: Local Development Server - url: https://dev-api.kt-event-marketing.com/{service}/v1 description: Development Server - url: https://api.kt-event-marketing.com/{service}/v1 description: Production Server ``` **포트 번호 할당:** - User Service: 8081 - Event Service: 8080 - Content Service: 8082 - AI Service: 8083 - Participation Service: 8084 - Distribution Service: 8085 - Analytics Service: 8086 **URL 패턴:** - Local: `http://localhost:{port}` - Dev: `https://dev-api.kt-event-marketing.com/{service}/v1` - Prod: `https://api.kt-event-marketing.com/{service}/v1` --- ## 3. 보안 스키마 ### 3.1 JWT Bearer 인증 ```yaml components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT description: | JWT Bearer 토큰 인증 **형식:** Authorization: Bearer {JWT_TOKEN} **토큰 만료:** 7일 **Claims:** - userId: 사용자 ID - role: 사용자 역할 (OWNER) - iat: 발급 시각 - exp: 만료 시각 ``` ### 3.2 전역 보안 적용 ```yaml security: - BearerAuth: [] ``` **적용 방법:** - 인증이 필요한 모든 엔드포인트에 `security` 섹션 추가 - 공개 API (예: 로그인, 회원가입)는 엔드포인트 레벨에서 `security: []`로 오버라이드 --- ## 4. 태그 구성 ### 4.1 태그 정의 패턴 ```yaml tags: - name: {Category Name} description: {카테고리 설명 (한글)} ``` **태그 명명 규칙:** - **영문 사용**: 명확한 영문 카테고리명 - **설명 한글**: description은 한글로 상세 설명 - **일관성 유지**: 유사 기능은 동일한 태그명 사용 **예시:** ```yaml tags: - name: Authentication description: 인증 관련 API (로그인, 로그아웃, 회원가입) - name: Profile description: 프로필 관련 API (조회, 수정, 비밀번호 변경) - name: Event Creation description: 이벤트 생성 플로우 ``` --- ## 5. 엔드포인트 정의 ### 5.1 엔드포인트 경로 규칙 **경로 패턴:** ``` /{resource} /{resource}/{id} /{resource}/{id}/{sub-resource} ``` **중요: `/api` prefix 사용 금지** - ❌ 잘못된 예: `/api/users/register` - ✅ 올바른 예: `/users/register` API Gateway 또는 서버 URL에서 서비스 구분이 이루어지므로, 엔드포인트 경로에 `/api`를 포함하지 않습니다. ### 5.2 공통 엔드포인트 구조 ```yaml paths: /{resource}: {http-method}: tags: - {Tag Name} summary: {짧은 한글 설명} description: | {상세 설명} **유저스토리:** {UFR 코드} **주요 기능:** - {기능 1} - {기능 2} **처리 흐름:** (복잡한 로직인 경우) 1. {단계 1} 2. {단계 2} **보안:** (보안 관련 엔드포인트인 경우) - {보안 메커니즘} operationId: {camelCase 메서드명} x-user-story: {UFR 코드} x-controller: {ControllerClass}.{methodName} security: - BearerAuth: [] parameters: - $ref: '#/components/parameters/{ParameterName}' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/{RequestSchema}' examples: {exampleName}: summary: {예시 설명} value: {...} responses: '{statusCode}': description: {응답 설명} content: application/json: schema: $ref: '#/components/schemas/{ResponseSchema}' examples: {exampleName}: summary: {예시 설명} value: {...} ``` ### 5.3 필수 항목 - `tags`: 1개 이상의 태그 지정 - `summary`: 한글로 간결하게 (10자 이내 권장) - `description`: 마크다운 형식의 상세 설명 - 유저스토리 코드 명시 - 주요 기능 bullet points - 복잡한 경우 처리 흐름 순서 작성 - 보안 관련 내용 (해당 시) - `operationId`: camelCase 메서드명 (예: `getUserProfile`, `createEvent`) - `x-user-story`: UFR 코드 (예: `UFR-USER-010`) - `x-controller`: 컨트롤러 클래스와 메서드 (예: `UserController.getProfile`) ### 5.4 operationId 명명 규칙 ``` {동사}{명사} ``` **동사 목록:** - `get`: 조회 - `list`: 목록 조회 - `create`: 생성 - `update`: 수정 - `delete`: 삭제 - `register`: 등록 - `login`: 로그인 - `logout`: 로그아웃 - `select`: 선택 - `request`: 요청 - `publish`: 배포 - `end`: 종료 **예시:** - `getUser`, `listEvents`, `createEvent` - `updateProfile`, `deleteEvent` - `registerUser`, `loginUser`, `logoutUser` - `selectRecommendation`, `publishEvent` --- ## 6. 응답 구조 ### 6.1 성공 응답 (Success Response) **원칙: 직접 응답 (Direct Response)** ```yaml responses: '200': description: {작업} 성공 content: application/json: schema: $ref: '#/components/schemas/{ResponseSchema}' ``` **응답 스키마 예시:** ```yaml UserProfileResponse: type: object required: - userId - userName - email properties: userId: type: integer format: int64 description: 사용자 ID example: 123 userName: type: string description: 사용자 이름 example: 홍길동 email: type: string format: email description: 이메일 주소 example: hong@example.com ``` **예외: Wrapper가 필요한 경우 (메시지 전달 필요 시)** ```yaml LogoutResponse: type: object required: - success - message properties: success: type: boolean description: 성공 여부 example: true message: type: string description: 응답 메시지 example: 안전하게 로그아웃되었습니다 ``` ### 6.2 페이징 응답 (Pagination Response) ```yaml {Resource}ListResponse: type: object required: - content - page properties: content: type: array items: $ref: '#/components/schemas/{ResourceSummary}' page: $ref: '#/components/schemas/PageInfo' PageInfo: type: object required: - page - size - totalElements - totalPages properties: page: type: integer description: 현재 페이지 번호 example: 0 size: type: integer description: 페이지 크기 example: 20 totalElements: type: integer description: 전체 요소 개수 example: 45 totalPages: type: integer description: 전체 페이지 개수 example: 3 ``` --- ## 7. 에러 응답 구조 ### 7.1 표준 에러 응답 스키마 ```yaml ErrorResponse: type: object required: - code - message - timestamp properties: code: type: string description: 에러 코드 example: USER_001 message: type: string description: 에러 메시지 example: 이미 가입된 전화번호입니다 timestamp: type: string format: date-time description: 에러 발생 시각 example: 2025-10-22T10:30:00Z details: type: array description: 상세 에러 정보 (선택 사항) items: type: string example: ["필드명: 필수 항목입니다"] ``` **필수 필드:** - `code`: 에러 코드 (서비스별 고유 코드) - `message`: 사용자에게 표시할 에러 메시지 (한글) - `timestamp`: 에러 발생 시각 (ISO 8601 형식) **선택 필드:** - `details`: 상세 에러 정보 배열 (validation 에러 등) ### 7.2 에러 코드 명명 규칙 ``` {SERVICE}_{NUMBER} ``` **서비스 약어:** - `USER`: User Service - `EVENT`: Event Service - `CONT`: Content Service - `AI`: AI Service - `PART`: Participation Service - `DIST`: Distribution Service - `ANAL`: Analytics Service - `AUTH`: 인증 관련 (공통) - `VALIDATION_ERROR`: 입력 검증 오류 (공통) **예시:** - `USER_001`: 중복 사용자 - `USER_002`: 사업자번호 검증 실패 - `AUTH_001`: 인증 실패 - `AUTH_002`: 유효하지 않은 토큰 - `VALIDATION_ERROR`: 입력 검증 오류 ### 7.3 공통 에러 응답 정의 ```yaml components: responses: BadRequest: description: 잘못된 요청 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: validationError: summary: 입력 검증 오류 value: code: VALIDATION_ERROR message: 요청 파라미터가 올바르지 않습니다 timestamp: 2025-10-22T10:30:00Z details: - "필드명: 필수 항목입니다" Unauthorized: description: 인증 실패 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: authFailed: summary: 인증 실패 value: code: AUTH_001 message: 인증에 실패했습니다 timestamp: 2025-10-22T10:30:00Z Forbidden: description: 권한 없음 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: forbidden: summary: 권한 없음 value: code: AUTH_003 message: 해당 리소스에 접근할 권한이 없습니다 timestamp: 2025-10-22T10:30:00Z NotFound: description: 리소스를 찾을 수 없음 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: notFound: summary: 리소스 없음 value: code: NOT_FOUND message: 요청한 리소스를 찾을 수 없습니다 timestamp: 2025-10-22T10:30:00Z InternalServerError: description: 서버 내부 오류 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: serverError: summary: 서버 오류 value: code: INTERNAL_SERVER_ERROR message: 서버 내부 오류가 발생했습니다 timestamp: 2025-10-22T10:30:00Z ``` ### 7.4 엔드포인트별 에러 응답 적용 ```yaml responses: '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' ``` **특수 에러 (비즈니스 로직 에러):** ```yaml '409': description: 비즈니스 로직 충돌 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: duplicateUser: summary: 중복 사용자 value: code: USER_001 message: 이미 가입된 전화번호입니다 timestamp: 2025-10-22T10:30:00Z ``` --- ## 8. 스키마 정의 ### 8.1 스키마 명명 규칙 **Request 스키마:** ``` {Action}{Resource}Request ``` 예: `RegisterRequest`, `LoginRequest`, `CreateEventRequest` **Response 스키마:** ``` {Resource}{Type}Response ``` 예: `UserProfileResponse`, `EventListResponse`, `EventDetailResponse` **공통 모델:** ``` {Resource}{Type} ``` 예: `EventSummary`, `GeneratedImage`, `PageInfo` ### 8.2 스키마 작성 원칙 **필수 항목:** - `type`: 객체 타입 (object, array, string 등) - `required`: 필수 필드 목록 - `properties`: 각 필드 정의 - `type`: 필드 타입 - `description`: 필드 설명 (한글) - `example`: 예시 값 **선택 항목:** - `format`: 특수 형식 (date, date-time, email, uri, uuid, int64 등) - `pattern`: 정규식 패턴 (전화번호, 사업자번호 등) - `minLength`, `maxLength`: 문자열 길이 제한 - `minimum`, `maximum`: 숫자 범위 제한 - `enum`: 허용 값 목록 **예시:** ```yaml RegisterRequest: type: object required: - name - phoneNumber - email - password properties: name: type: string minLength: 2 maxLength: 50 description: 사용자 이름 (2자 이상, 한글/영문) example: 홍길동 phoneNumber: type: string pattern: '^010\d{8}$' description: 휴대폰 번호 (010XXXXXXXX) example: "01012345678" email: type: string format: email maxLength: 100 description: 이메일 주소 example: hong@example.com password: type: string minLength: 8 maxLength: 100 description: 비밀번호 (8자 이상, 영문/숫자/특수문자 포함) example: "Password123!" ``` ### 8.3 날짜/시간 형식 **날짜:** `format: date`, 형식 `YYYY-MM-DD` ```yaml startDate: type: string format: date description: 시작일 example: "2025-03-01" ``` **날짜/시간:** `format: date-time`, 형식 `ISO 8601` ```yaml createdAt: type: string format: date-time description: 생성일시 example: 2025-10-22T10:30:00Z ``` ### 8.4 ID 형식 **UUID:** ```yaml eventId: type: string format: uuid description: 이벤트 ID example: "550e8400-e29b-41d4-a716-446655440000" ``` **정수 ID:** ```yaml userId: type: integer format: int64 description: 사용자 ID example: 123 ``` --- ## 9. 메타데이터 주석 ### 9.1 필수 메타데이터 ```yaml x-user-story: {UFR 코드} x-controller: {ControllerClass}.{methodName} ``` **x-user-story:** - 유저스토리 코드 명시 - 여러 유저스토리와 관련된 경우 콤마로 구분 - 예: `UFR-USER-010`, `UFR-EVENT-010, UFR-EVENT-070` **x-controller:** - 컨트롤러 클래스와 메서드 매핑 - 백엔드 개발 시 참조 - 예: `UserController.registerUser`, `EventController.getEvents` ### 9.2 선택 메타데이터 (필요 시) ```yaml x-internal: true # 내부 API 표시 x-async: true # 비동기 처리 표시 ``` --- ## 10. 기술 명세 섹션 ### 10.1 x-technical-specifications **비동기 처리 서비스 (AI, Content 등):** ```yaml x-technical-specifications: async-processing: message-queue: Kafka topics: request: ai.recommendation.request response: ai.recommendation.response job-tracking: Redis (TTL 24h) timeout: 300s resilience: circuit-breaker: failure-threshold: 5 timeout: 10s half-open-requests: 3 retry: max-attempts: 3 backoff: exponential initial-interval: 1s max-interval: 10s fallback: strategy: cached-result caching: provider: Redis ttl: 7d key-pattern: "content:event:{eventDraftId}" external-apis: - name: Claude API endpoint: https://api.anthropic.com/v1/messages timeout: 60s circuit-breaker: true - name: GPT-4 API endpoint: https://api.openai.com/v1/chat/completions timeout: 60s circuit-breaker: true ``` **동기 처리 서비스:** ```yaml x-technical-specifications: database: type: PostgreSQL connection-pool: min: 10 max: 50 timeout: 30s caching: provider: Redis ttl: 30m key-pattern: "user:{userId}" security: authentication: JWT Bearer password-hashing: bcrypt encryption: algorithm: AES-256-GCM fields: [businessNumber] ``` ### 10.2 적용 기준 **필수 포함 서비스:** - Content Service: 비동기 처리, Kafka, 외부 API 통합 - AI Service: 비동기 처리, Kafka, Claude/GPT 통합 **선택 포함 서비스:** - User Service: 보안 관련 명세 - Event Service: 오케스트레이션 패턴 - Participation Service: 대용량 트래픽 대비 캐싱 --- ## 11. 예제 작성 ### 11.1 Request/Response 예제 원칙 **모든 requestBody와 주요 response에 예제 필수:** ```yaml requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RegisterRequest' examples: restaurant: summary: 음식점 회원가입 예시 value: name: 홍길동 phoneNumber: "01012345678" email: hong@example.com password: "Password123!" storeName: 맛있는집 industry: 음식점 cafe: summary: 카페 회원가입 예시 value: name: 김철수 phoneNumber: "01087654321" email: kim@example.com password: "SecurePass456!" storeName: 아메리카노 카페 industry: 카페 ``` **성공 응답 예제:** ```yaml responses: '200': description: 프로필 조회 성공 content: application/json: schema: $ref: '#/components/schemas/ProfileResponse' examples: success: summary: 프로필 조회 성공 응답 value: userId: 123 userName: 홍길동 phoneNumber: "01012345678" email: hong@example.com ``` **에러 응답 예제:** ```yaml responses: '400': description: 잘못된 요청 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: duplicateUser: summary: 중복 사용자 value: code: USER_001 message: 이미 가입된 전화번호입니다 timestamp: 2025-10-22T10:30:00Z invalidBusinessNumber: summary: 사업자번호 검증 실패 value: code: USER_002 message: 유효하지 않은 사업자번호입니다 timestamp: 2025-10-22T10:30:00Z ``` ### 11.2 예제 명명 규칙 - `success`: 성공 케이스 - `{errorType}`: 에러 케이스 (예: `duplicateUser`, `validationError`) - `{scenario}`: 시나리오별 예제 (예: `restaurant`, `cafe`) --- ## 12. 체크리스트 API 명세서 작성 시 아래 체크리스트를 확인하세요: ### 기본 정보 - [ ] OpenAPI 버전 3.0.3 명시 - [ ] info.title에 서비스명 포함 - [ ] info.description에 주요 기능 목록 포함 - [ ] info.version 1.0.0 - [ ] contact 정보 포함 ### 서버 및 보안 - [ ] servers에 Local, Dev, Prod 정의 - [ ] 포트 번호 정확히 할당 - [ ] components.securitySchemes에 BearerAuth 정의 - [ ] 인증 필요한 엔드포인트에 security 적용 ### 엔드포인트 - [ ] 모든 엔드포인트에 tags 지정 - [ ] summary와 description 작성 (한글) - [ ] operationId camelCase로 작성 - [ ] x-user-story UFR 코드 명시 - [ ] x-controller 매핑 정보 포함 ### 스키마 - [ ] Request/Response 스키마 명명 규칙 준수 - [ ] required 필드 명시 - [ ] 모든 properties에 description과 example 포함 - [ ] 적절한 format 사용 (date, date-time, email, uuid 등) ### 응답 구조 - [ ] ErrorResponse 표준 스키마 사용 - [ ] 공통 에러 응답 ($ref) 활용 - [ ] 에러 코드 명명 규칙 준수 - [ ] 페이징 응답에 PageInfo 사용 ### 예제 - [ ] requestBody에 최소 1개 이상 예제 - [ ] 주요 response에 success 예제 - [ ] 주요 에러 케이스에 예제 ### 기술 명세 (해당 시) - [ ] 비동기 처리 서비스: x-technical-specifications 포함 - [ ] Kafka 토픽, Redis 캐싱 정보 명시 - [ ] 외부 API 연동 정보 포함 --- ## 13. 참고 자료 ### 서비스별 API 명세서 - User Service API: `/design/backend/api/user-service-api.yaml` - Event Service API: `/design/backend/api/event-service-api.yaml` - Content Service API: `/design/backend/api/content-service-api.yaml` - AI Service API: `/design/backend/api/ai-service-api.yaml` - Participation Service API: `/design/backend/api/participation-service-api.yaml` - Distribution Service API: `/design/backend/api/distribution-service-api.yaml` - Analytics Service API: `/design/backend/api/analytics-service-api.yaml` ### OpenAPI 3.0.3 공식 문서 - https://swagger.io/specification/ ### 프로젝트 아키텍처 - High-Level Architecture: `/design/high-level-architecture.md` - Logical Architecture: `/design/backend/logical/` --- **문서 버전:** 1.0.0 **최종 수정일:** 2025-10-23 **작성자:** Digital Garage Team