사전 OpenAPI
표준

OpenAPI

gabury1고친 사람 github-actions[bot]

OpenAPI 는 웹 서비스를 부르는 법을 파일 하나에 적어 두게 해 줍니다. 어느 주소로 무엇을 보내면 무엇이 돌아오는지를 정해진 형식으로 적습니다. 정해진 형식이라서 사람만 읽는 것이 아니라 프로그램도 읽습니다. 도구가 그 파일 하나를 읽어 여러 산출물을 만듭니다.

쉽고 빠른 이해

OpenAPI 는 웹 서비스 설명서를 프로그램도 읽을 수 있게 적는 약속입니다. /users/{id} 에 GET 을 보내면 회원 한 명이 돌아온다는 사실을 파일 한 줄 한 줄로 적습니다.

이게 없으면 서비스를 부르는 쪽이 서버 코드를 읽거나, 요청을 몇 번 보내 보고 짐작해야 합니다. 사람이 손으로 쓴 설명서는 코드가 바뀔 때 같이 안 바뀌기 쉽습니다.

쓰는 순서는 이렇습니다.

  1. 주소마다 받는 값과 돌려주는 값을 파일에 적습니다
  2. 도구가 그 파일을 읽어 문서 화면과 호출 코드를 만듭니다
  3. 요청과 응답이 파일과 맞는지 도구가 검사합니다

웹 요청으로 주고받는 서비스를 설명할 때 씁니다. gRPC 나 GraphQL 처럼 자기 형식으로 접점을 적는 기술에는 쓰지 않습니다.

대가는 파일을 코드와 함께 계속 고쳐야 한다는 것입니다. 파일과 서버가 어긋나면 파일에서 나온 문서와 코드가 전부 틀립니다.

상세

OpenAPI 는 HTTP(HyperText Transfer Protocol, 하이퍼텍스트 전송 규약) 위에서 도는 API(Application Programming Interface, 프로그램끼리 부르는 접점)를 설명하는 규격입니다. OpenAPI 는 설명서를 적는 문법과 키워드를 정합니다. 설명서를 쓰는 일은 각 팀이 합니다. 이렇게 쓴 파일을 OpenAPI 문서라고 부릅니다.

설명서를 파일로 두는 이유

API 를 부르는 쪽은 세 가지를 알아야 합니다. 어느 주소에 어떤 요청 메서드로 보내는지, 무엇을 담아 보내는지, 무엇이 돌아오는지입니다. 이 셋을 모르면 서버 코드를 읽거나 요청을 보내 보며 짐작하는 수밖에 없습니다.

사람이 쓰는 설명서로도 이 셋은 전할 수 있습니다. 문제는 설명서가 코드와 따로 산다는 것입니다. 필드 하나가 이름을 바꿔도 설명서는 옛 이름을 적고 있습니다. 부르는 쪽은 그 틀린 설명서를 믿고 코드를 짭니다.

OpenAPI 는 설명서를 프로그램이 읽는 파일로 바꿉니다. 그러면 서버의 실제 응답과 파일을 기계로 맞춰 볼 수 있습니다. 어긋나면 사람이 알아채기 전에 검사 도구가 먼저 잡습니다.

문서 하나의 생김새

OpenAPI 문서는 YAML(YAML Ain't Markup Language, 들여쓰기로 구조를 적는 텍스트 형식)이나 JSON(JavaScript Object Notation, 자바스크립트 객체 표기법)으로 적습니다. 둘은 적는 형식만 다르고 담는 내용은 같습니다. 사람이 손으로 쓸 때는 대개 YAML 을 씁니다.

아래는 회원 한 명을 번호로 찾는 API 하나만 적은 문서입니다. 주석은 그 줄이 무엇을 정하는지 짧게 적은 것입니다.

YAML
openapi: 3.1.0       # 따르는 규격의 버전
info:
  title: 회원 API
  version: 1.0.0     # 이 API 자신의 버전
paths:
  /users/{id}:       # 주소
    get:             # 요청 메서드
      operationId: getUser
      parameters:
        - name: id
          in: path   # 주소 속 {id}
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: 찾았다
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "404":
          description: 없는 회원
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string

맨 위의 네 키가 문서의 뼈대입니다. 키는 openapi: 3.1.0 에서 콜론 앞에 오는 이름입니다.

키 담는 것
openapi 이 문서가 따르는 OpenAPI 규격의 버전
info API 의 이름과 API 자신의 버전
paths 주소마다 받을 수 있는 요청과 돌려주는 응답
components 여러 곳에서 다시 쓰는 조각

버전이 두 개 나오는 데 주의해야 합니다. 하나는 이 문서가 따르는 OpenAPI 규격의 버전입니다. 다른 하나는 설명하는 회원 API 자신의 버전입니다.

openapi 와 info 는 반드시 있어야 합니다. paths 나 components 같은 본문 키도 적어도 하나는 있어야 합니다.

이 문서를 읽고 요청을 걸러 주는 검사 도구가 있습니다. 그 도구를 서버 앞에 두면 요청을 이렇게 가를 수 있습니다. 오른쪽 주석이 문서에 비춘 결과입니다.

http
GET /users/7      # 200 · User 하나
GET /users/99     # 404 · 없는 회원
GET /users/abc    # 걸러짐 · id 는 정수

세 번째 요청은 검사 도구가 서버 코드를 부르기 전에 걸러 냅니다. 문서에 id 가 정수라고 적혀 있기 때문입니다. 요청을 보낸 쪽은 서버 대신 검사 도구가 만든 오류 응답을 받습니다.

주소에서 응답까지 내려가는 길

paths 아래는 몇 단계로 매달려 있습니다. 맨 위는 주소이고, 그 아래에 요청 메서드가 붙습니다. 주소 하나와 메서드 하나를 묶은 단위를 연산(operation)이라고 부릅니다. 앞 문서에서는 /users/{id} 의 get 이 연산 하나입니다.

flowchart TD
    P["paths"] --> U["주소 · /users/{id}"]
    U --> G["요청 메서드 · get"]
    G --> PA["parameters · 받는 값"]
    G --> R["responses · 돌려주는 값"]
    R --> C200["상태 코드 · 200"]
    C200 --> S["schema · 본문의 형식"]

연산 하나는 받는 값과 돌려주는 값을 나눠 적습니다. 받는 값은 parameters 에 적습니다. 요청 본문이 있으면 requestBody 에 따로 적습니다. 돌려주는 값은 responses 아래에 상태 코드마다 하나씩 적습니다. 그 응답 본문이 어떤 형식인지는 schema 에 적습니다.

parameters 의 값마다 어디에 실려 오는지를 in 으로 밝힙니다. 넷 중 하나를 고릅니다.

in 값이 실리는 곳 예
path 주소 안의 중괄호 부분 /users/{id} 의 id
query 주소 뒤 ? 다음 /users?page=2 의 page
header 요청 헤더 X-Request-Id
cookie 쿠키 session

responses 의 키는 "200" 처럼 따옴표로 감싼 상태 코드입니다. 따로 적지 않은 코드를 한꺼번에 받는 default 도 둘 수 있습니다.

operationId 는 연산에 붙이는 이름입니다. 문서 안의 모든 연산 사이에서 겹치면 안 됩니다. 문서를 읽어 호출 함수를 만드는 코드 생성 도구가 이 이름을 함수 이름으로 씁니다. 그래서 겹치면 같은 이름의 함수가 둘 생깁니다.

스키마와 다시 쓰는 조각

스키마는 데이터가 어떤 구조여야 하는지를 적은 규칙입니다. 이를테면 「회원은 정수 id 와 문자열 name 을 가진 객체다」가 스키마 하나입니다. 앞 문서의 User 가 바로 이 규칙을 적은 것입니다.

OpenAPI 는 스키마를 적는 문법을 새로 만들지 않고 JSON Schema 에서 빌려 씁니다. JSON Schema 는 JSON 데이터의 구조를 적는 별도 규격입니다. 앞 문서의 type: object 와 properties, type: integer 가 그 규격의 키워드입니다.

같은 구조는 여러 연산에 나옵니다. 회원 한 명 조회도, 회원 목록도, 회원 수정 응답도 User 를 돌려줍니다. 그때마다 필드를 다시 적으면 한 곳을 고칠 때 나머지를 빠뜨립니다.

그래서 되풀이되는 구조는 components 아래에 한 번만 적고 이름을 붙입니다. 쓰는 곳에서는 $ref: "#/components/schemas/User" 처럼 그 이름을 가리킵니다. # 은 「이 문서 안」을 뜻합니다. 그 뒤는 문서의 맨 위에서 User 까지 내려가는 길입니다.

components 에는 스키마 말고도 여러 번 쓰는 조각이 들어갑니다. 여러 연산이 같이 쓰는 응답과 받는 값도 여기에 한 번만 적어 둡니다.

인증 방식도 components 에 둡니다. 인증은 요청을 보낸 쪽이 누구인지 확인하는 일입니다. 인증 방식은 securitySchemes 에 적습니다. 거기에 API 키를 쓰는지 토큰을 받아 쓰는지 같은 종류를 밝힙니다. 연산은 security 키에 그 방식의 이름을 적어 가져다 씁니다.

문서 하나에서 나오는 것

도구는 이 문서를 입력으로 받아 여러 가지를 만듭니다.

산출물 하는 일
문서 화면 브라우저에서 연산 목록을 보여 주고 그 화면에서 요청을 직접 보내 볼 수 있게 합니다
클라이언트 코드 부르는 쪽 언어로 getUser(7) 같은 함수와 User 타입을 만들어 줍니다
서버 뼈대 코드 주소와 메서드를 받는 빈 함수를 만들어 두고 속은 개발자가 채웁니다
요청·응답 검사 들어온 요청과 나가는 응답이 문서의 스키마에 맞는지 봅니다
목 서버 진짜 서버 대신 문서에 적힌 대로 가짜 응답만 돌려주는 서버를 띄웁니다

앞에서 /users/abc 를 걸러 낸 것이 요청·응답 검사입니다. 목 서버는 프론트엔드 팀이 백엔드를 기다리지 않고 먼저 화면을 붙여 볼 때 씁니다.

API 게이트웨이 가운데에는 OpenAPI 문서를 읽어 주소 목록과 요청 검사를 설정하는 것도 있습니다.

먼저 쓰는 방식과 뽑아내는 방식

문서를 언제 만드느냐에 따라 일하는 순서가 둘로 갈립니다. 하나는 문서를 먼저 쓰고 코드를 거기에 맞추는 방식입니다. 다른 하나는 코드를 먼저 짜고 코드에서 문서를 뽑아내는 방식입니다.

문서 먼저 코드 먼저
순서 문서 작성 · 합의 → 구현 구현 → 어노테이션이나 코드 구조에서 문서 추출
문서의 주인 문서가 원본, 코드가 따름 코드가 원본, 문서가 따름
얻는 것 구현 전에 부르는 쪽과 요청·응답 합의 문서와 코드가 어긋날 일이 적음
내주는 것 문서와 코드가 맞는지 따로 검사해야 함 설계 논의가 코드 뒤로 밀림

어느 쪽이든 문서와 서버의 실제 동작이 맞는지를 CI(Continuous Integration, 지속적 통합)에서 자동으로 검사하기도 합니다. 어긋난 채 배포되면 그 문서로 만든 클라이언트 코드가 전부 틀린 요청을 보내기 때문입니다.

버전이 바뀌면 달라지는 것

openapi 키의 버전이 다르면 같은 뜻을 적는 키워드가 달라집니다. 도구는 이 키를 먼저 읽습니다. 그 값으로 어느 버전의 규칙을 따를지 정합니다. 그래서 도구가 지원하는 버전과 문서의 버전이 맞아야 합니다.

이 규격의 예전 이름은 Swagger 였습니다. 옛 이름으로 불리던 버전의 문서는 맨 위 키가 openapi 가 아니라 swagger 입니다. 되풀이되는 스키마도 components 아래가 아니라 맨 위의 definitions 에 모읍니다. 키워드가 달라진다는 것이 이런 차이입니다.

이름은 OpenAPI 로 바뀌었지만 이 계열의 도구 이름에는 Swagger 가 남아 있습니다. 그래서 실무에서는 「스웨거 문서」와 「OpenAPI 문서」를 같은 뜻으로 섞어 부릅니다.

다루지 않는 것

OpenAPI 는 HTTP 로 주고받는 API 만 설명합니다. gRPC 는 .proto 파일로, GraphQL 은 자기 스키마 언어로 접점을 적습니다. 이들은 OpenAPI 문서로 옮겨 적지 않습니다.

연산 하나하나는 설명하지만 연산 사이의 순서는 적지 않습니다. 「주문을 만든 다음에 결제를 부른다」 같은 흐름은 문서 밖에서 따로 알려야 합니다. 서버가 속에서 무엇을 계산하는지도 적지 않습니다. 적는 것은 경계에서 오가는 요청과 응답뿐입니다.

관련 항목

OpenAPI 가 설명하는 대상

HTTP · API · REST · 엔드포인트 · 요청 메서드 · 상태 코드 · API 설계

OpenAPI 문서를 적는 형식과 규격

YAML · JSON · JSON Schema · 스키마 · JSON Pointer

OpenAPI 문서가 담는 구성 요소

경로 매개변수 · 쿼리 문자열 · 헤더 · 쿠키 · 요청 본문 · 인증 · API 키 · OAuth 2.0

OpenAPI 문서로 만드는 도구와 산출물

Swagger UI · 코드 생성 · 목 서버 · API 게이트웨이 · 계약 테스트 · CI

같은 일을 다른 방식으로 하는 인터페이스 기술

gRPC · Protocol Buffers · GraphQL · WSDL · AsyncAPI

문서를 쓰는 순서를 가르는 방식

API 우선 설계 · 코드 우선 · 하위 호환 · 버전관리

다른 이름: OpenAPI Specification · OAS · OpenAPI 문서 · OpenAPI 규격 · Swagger Specification