성장하는 API는 어떻게 만들어야 하는가?

우리는 API를 디자인하는 일을 늘 고민합니다. 성장 가능한 API를 어떻게 만들어 할까요? API 디자인 관련된 몇 가지 주제에 대해서 알아봅시다.

API를 성장시키기 위해서는 API 생명주기를 알고 다른 API와 동시에 실행되는 것을 이해해야 합니다. API 디자인은 API가 탄생하며, 살아가고, 폐기되는 API 생명주기의 한 부분에 불과합니다.

API 생명주기를 단계별로 살펴봅시다.

  • 분석 단계
    • API의 목표 요구사항을 충족하는데 필요한 것, 컨슈머가 해결하려는 것, 실제 사용자에 대한 정보, 그리고 API가 제공하는 이점과 같은 주제를 탐색합니다.
  • 디자인 단계
    • 분석 단계에서 심층적으로 조사했던 내용을 프로그래밍 인터페이스 컨트랙트로 변경합니다.
  • 구현 단계
    • 인터페이스 컨트랙트의 구현이 애플리케이션을 통해 외부로 공개됩니다.
  • 발행 단계
    • 실제로 대상 컨슈머들이 API를 사용할 수 있게 됩니다.
  • 실행 단계
    • 컨슈머가 새로운 기능이나 개선할 점들이 있는지, 피드백을 주고받습니다.
  • 분석 단계
    • 새로운 기능을 추가하거나 개선된 API 목표 요구사항을 충족하는데 필요한 것, API가 개선되었을 때, 제공하는 이점과 같은 주제를 탐색합니다.
  • 발전 단계
    • 분석 단계에서 심층적으로 조사했던 내용을 프로그래밍 인터페이스 컨트랙트로 변경합니다.
  • 구현 단계
    • 인터페이스 컨트랙트의 구현이 애플리케이션을 통해 외부로 공개됩니다.

일반적으로 API 디자이너는 API 생명주기의 다양한 단계에 모두 개입해야 합니다. 조직이 단 하나의 API만 만들고, 그것이 바뀌지 않으리란 보장은 없습니다. 오히려 항상 발전하는 여러 API를 생성하는 경우가 더 많습니다. API 디자이너는 조직을 위해 일관된 API 영역을 구축하기 위해 협력해야 합니다. 따라서 API 디자이너는 자신이 하는 일을 공유해야만 하며, 이를 통해 API를 디자인하고 리뷰할 때 참고할 지침을 제공해 서로 도울 수 있습니다. 혼자 일하는 API 디자이너도 디자인의 일관성을 유지하기 위해 과거 자신의 작업을 주시하며 스스로 지침을 제공할 수 있어야 합니다.

API 디자인 지침이 성장하는 API를 만드는데 어떤 도움이 되는가?

API 디자인은 지침은 구성원들과 지식을 공유하여 일관성 있는 디자인을 만들도록 도움이 되고, 구성원들이 학습하여 더 좋은 디자인을 만들도록 도와줍니다.

예를 들어 코드숨 좌석 예약 프로젝트에서, 예약이라는 단어를 정의하는 지침을 만들지 않아 reservation 과 book 이 혼용되고 있었습니다. 그 결과 예약 관련 기능을 사용하고 싶을 때 둘 중 어느 단어를 사용해야 하는지 알기 어려웠습니다. 이러한 문제점을 인지한 후, 컨슈머와 프로바이더가 함께 합의된 용어집을 작성함으로써 일관성 있는 코드를 작성할 수 있었습니다.

디자인 지침에는 어떤 내용들이 들어가야 되는지

참조 지침

API 지침에는 API를 디자인할 때 적용할 원칙과 규칙을 정의해야 합니다. 이 지침에는 상태 코드를 어떻게 써야 하는지, 리소스 경로는 어떤 식으로 작성해야 하는지, 데이터 포맷은 어떻게 사용하는지 등등 API를 디자인할 때 필요한 모든 구성 요소들이 있어야 합니다.

## 상태 코드

* 204: 성공적으로 처리되었고, 응답할 데이터가 없을 때 204 No Content를 응답해야 합니다.
* 404: 리소스가 존재하지 않거나, 리소스에 접근할 수 없을 때 404 Not Found를 응답해야 합니다.
* 500: 처리하지 못하는 예외가 발생할 경우 500 Internal Server Error를 응답합니다.

## 에러 응답 명세


{
  "code": "INVALID_PARAMETER",
  "errors": [
    { "type": "MISSING_PARAMETER", "message": "이름은 필수 입력 항목입니다.", "source": "$.name" },
    { "type": "MISSING_PARAMETER", "message": "핸드폰 필수 입력 항목입니다.", "source": "$.phone" },
  ]
} 

유즈케이스 지침

지침을 작성할 때는 사용성과 단순성을 염두 해야 합니다.

좌석 예약 조회 유즈케이스

목적
이 api는 좌석 예약을 확인할 수 있는 API 입니다

API 리소스 경로
/reservations

위와 같은 유즈케이스인 경우 어떻게 사용을 하는지 호출이 성공, 실패 된다면 어떤 일이 발생하는지 전혀 적혀있지 않아 사용하는 입장에서는 이를 파악하기 위해 api 디자인에게 물어보거나 그와 관련된 정보를 얻기 위해 시간을 낭비할 것입니다.

따라서 아래와 같이 사용 방법, 필요한 데이터, 반환되는 데이터, 성공과 실패 시 어떤 응답을 하는지에 대한 정보를 제공해야 합니다.

이 유즈케이스를 사용해야 하는 경우
컨슈머가 어떤 날짜에 계획을 하고 계획 내용과, 회고 작성 여부를 확인할 수 있습니다.

REST API에서 사용하는 법
예약 조회를 하기 위해서는 GET /reservations로 사용해 주어야 합니다.
어떤 사람의 예약인지 확인하기 위해서는 header에 accessToken 값도 넘겨주어야 합니다.

성공
호출 성공 시 204 상태 코드를 반환하며 204 상태 코드는 No Content이기 때문에 아무 값도 반환해 주지 않습니다.

실패
호출 실패 시 Not Found를 반환합니다.

디자인 절차 지침

API 디자인을 하는데 필요한 절차를 제공해야 합니다. 구성원들 간의 합의된 디자인 절차를 포함하거나 도움이 되는 책 같은 내용이 들어갈 수 있습니다.

## API 디자인 가이드

API를 디자인할 때는 컨슈머의 입장을 고려해서, 컨슈머가 사용하기 편한 API를 만들어야 합니다. 컨슈머가 
필요한 API는 사용자가 세부 사항을 몰라도 사용하기 쉬워야 합니다.

## 추천 서적

- 웹 API 디자인
- 로이 필딩의 논문

구현 시 고려 사항 지침

API 디자인하는데 필요한 세부사항들을 제공해야 합니다. 구현 담당자가 이 문서를 참고하여 API를 디자인하는 데 도움이 될 수 있습니다.

## 인증 헤더

인증 데이터는 HTTP 헤더를 통해 전송되며, `Authorization: Bearer abcd123`가 같은 형태로 전달됩니다.
인증이 필요한 요청에 권한이 없을 경우 `401 Unauthorized` 상태 코드를 응답해야 합니다.

이러한 지침들을 지속적으로 발전시키려면 어떻게 해야 하는지

작성한 지침 또한 성장하는 지침이 되어야 합니다. 처음부터 거대한 무언가를 만들기보다는 작게 시작하고, 구성원들이 인식하고 받아들이도록 꾸준히 발전시켜야 합니다.

중요한 것은 구성원들과 소통하는 것입니다. 만들고 아무도 보지 않는다면 아무 소용이 없습니다. 다른 디자이너들에게 이러한 지침이 존재한다는 사실을 알리고, 지침을 활용해서 디자인 문제를 해결하는 데 도움을 주어야 합니다. 그리고 디자이너들이 왜 일관성이 중요한지 이해해야 합니다. 그리고 왜 이런 규칙들이 정해지게 되었는지 동의할 수 있도록 충분히 설명해야 합니다.

그렇다고 해서 특정 API 디자인 지침을 강요해서는 안 됩니다. 예를 들어서 개인적인 선호도만으로 디자인 지침을 작성하고 강요해서는 안 됩니다. 디자인 지침이 발전하려면 구성원들과 공유가 되고 구성원들이 지침에 동의해야 합니다.

API 리뷰가 성장하는 API를 만드는데 어떤 도움이 되는가?

API는 API 생명주기의 단계에서 리뷰하여 의도한 대로 동작하는지 확인해야 합니다. API를 만들고 리뷰를 하지 않는다면 모든 것들이 잘못될 가능성이 있습니다. 무엇보다도 요구사항을 명확하게 파악하고 잘 이해해야 하며, API를 만드는 것이 최선의 솔루션인지 확인해야 합니다. API가 디자인된 이후에는 린트 되어야 합니다. 그 뒤에 프로바이더 관점으로 식별된 요구사항을 충족하며 검증이 되어야 합니다. 컨슈머의 컨텍스트에서 이해할 수 있고 사용할 수 있는지 검증이 되어야 합니다. 마지막으로 API를 구현한 후에는 구현 사항을 검증해야 합니다.

요구사항에 도전하고 분석해야합니다.

무엇이 되어야 하는지, 상황이 어떤 경우인지, 어떻게 쓰일 것인지 와 같은 질문을 하다 보면 진정한 요구사항 또는 첫 번째 요구사항에 의해 가려져 있던 요구사항이 식별됩니다.

코드숨 공부방에서 좌석 예약으로 예를 들어 보겠습니다.

질문/도구 설명
무엇을 하고 싶나요? 어떤 상황인가요? 코드숨 공부방 좌석을 이용하고 싶은 사용자들이 좌석을 예약하고 싶은 상황입니다.
“이것”은 어떻게 쓰일건가요? 이것은 좌석 예약을 할 때 쓰입니다.
컨슈머는 누가 될 건가요? 컨슈머는 코드숨 강의를 듣고 있거나 수강한 사람입니다.
최종 사용자는 누가 될까요? 최종 사용자 또한 코드숨 강의를 듣고 있거나 수강한 사람이고 현재 모든 사용자는 한국인이라 한국어만 지원해도 될 것입니다. 또한 승인된 사용자만 좌석 예약을 할 수 있습니다.
5 Why 분석법 왜 최종 사용자는 승인된 사용자만 좌석 예약을 할 수 있나요? 왜냐하면 현재 구매한 사용자만 좌석 예약을 할 수 있기 때문입니다. 왜 현재는 한국어만 지원하고 있나요? 왜냐하면 현재 모든 이용자는 한국인이기 때문입니다. 나중에 추가될 일은 없나요? 현재 코드숨 강의는 한국어로만 진행되고 있습니다. 그래서 추가될 일은 없습니다.
API 목표 캔버스 위의 요구사항의 대한 분석으로 API 목표 캔버스를 사용합니다.

이런 식으로 요구사항을 명확하게 파악하고 컨텍스트를 조사하면 기존 API에 새로운 목표를 추가하건, 새로운 API를 만들건, 가장 적합한 솔루션을 디자인할 수 있게 됩니다.

API 디자인을 린트해야 합니다.

코드숨 공부방 이메일 인증 리퀘스트 POST /verification/email 가 선택 값들로 email(이메일)과 msg(메시지)를 숫자값으로 받는다면 제 3자가 봤을 때 혼란스러워 할 수 있습니다. msg는 message 라고 부르고 그 값은 문자열이어야 명확합니다. 그리고 요청 값들은 선택 사항이 아닌 필수여야 할 것입니다. 제안된 디자인에 린트를 하면 명확하게 판별 해낼 수 있을 것입니다.

또한 에러 메시지 또한 err_msg 대신에 errorMessage라는 속성 이름을 사용하여 같은 규칙을 따라 디자인 되어야합니다. API 린트는 이러한 사항을 찾는 데 도움이 됩니다.

API 린트는 디자인의 버그 검사와 디자인 지침을 준수하고 있는지, 기존 요소와 일치하는지 확인합니다. API 디자인을 린트하는 동안 API 디자인의 보안과 문서화를 함께 살펴보아야 합니다. 기본적으로는 각 모델과 해당 속성, 각 목표, 그것들의 파라미터들과 리스폰스들, 목표 흐름과 보안 정의를 분석해야 합니다. 문서 확인, 흐름 확인, 기존 요소와의 일관성 확인은 특히 주의해서 확인해야 합니다.

API 린트 체크리스트 (목표)

확인사항 설명
카테고리화 이것은 의무는 아니지만, 목표를 분류하면 API를 쉽게 이해할 수 있습니다.
경로(path) 적합성 경로 포맷은 지침을 준수하고, 기존 구성 요소와 일관성을 지녀야 합니다. 성공 리스폰스와 경로 파라미터도 리뷰 해야 합니다.
HTTP 메서드 적합성 HTTP 메서드가 지침을 준수하고 기존 구성 요소와 일관성을 지니며 수행해야 하는 목표에 적합합니다.
성공, 에러 제어 목표는 성공과 실패의 경우 필요한 리스폰스를 반환해야 합니다.
보안 각 목표는 보안 메커니즘으로 보호받아야 합니다.

프로바이더 관점에서 디자인을 리뷰해야 합니다.

위 과정을 만족했다 하더라도 프로바이더 관점에서 모든 게 문제없음을 의미하지는 않습니다. API 리뷰 시 광범위한 지식이 없는 관련된 모두가 쉽게 리뷰할 수 있어야 합니다. 이를 위해서는 API 목표 캔버스와 같은 문서가 중요합니다.

프로바이더 관점 디자인 체크리스트 예시 (목표)

확인사항 설명
목표 적합성 요구사항에 부합해야 합니다.
안전한 경로 민감한 데이터 노출을 피하고 외부 노출이 필요한 경우 안전하게 변경하여 노출하라.
보안 과도한 권한은 제공하지 않습니다.
구현 가능성 실제로 구현이 가능해야 합니다.
확장성 미래에 있을 발전을 수용해야 합니다.

컨슈머 관점에서도 디자인을 리뷰해야 합니다.

API에 대해 전혀 모르는 컨슈머의 입장을 취해야 합니다. 여기까지 검토 과정(API 린트, 프로바이더 리뷰, 컨슈머 리뷰)이 마무리되면 마지막으로 API는 구현이 가능해집니다. 이제 실제로 설계한 인터페이스 컨트랙트가 기대처럼 구현되는지 확인하는 데 도움을 줄 수 있습니다.

컨슈머 관점 디자인 체크리스트 예시 (목표)

확인사항 설명
경로 적합성 경로 구조의 이름과 파라미터는 이해가 쉬워야 합니다.
목적 적합성 컨슈머에게 필요해야 합니다.
유효한 성능 추정 컨슈머의 요구에 부합해야 합니다.

마지막으로, 구현을 검증해야합니다.

API 구현하는 개발자는 API를 검증하기 위해서 다양한 테스트에 의존할 수 있습니다. 이때, 특별히 주의해서 다루어야할 몇 가지 사항이 있습니다.

  • 보안 테스트 우회 금지
    • 보안 테스트는 API에 있어서 매우 중요한 작업입니다. 접근 제어 및 민감한 데이터가 실제로 올바른 방식으로 처리되도록 해야 합니다.
  • 생성된 문서를 사용하여 구현 검증 시 주의
    • 빌드 되는 시점에서 생성된 API 명세 파일은 원래 API 성명 파일과 비교하여 구현에 의해 노출된 인터페이스 컨트랙트가 예상되던 것을 준수하는지 검증할 수 있습니다. 그러나 유효성 검증은 API 설명 파일을 생성하기 위해 특별히 작성된 애노테이션에서 오지 않은 요소에서만 수행 가능합니다.
  • 인터페이스 컨트랙트 런타임에 확인하기
    • 구현이 런타임에서 기대했던 동작을 하는지 확인해야 합니다. 예를 들어, 생성된 유효한 인터페이스 컨트랙트에 필수 속성이 누락된다면 에러를 반환하더라도 실제 케이스를 대체할 수 없기 때문입니다.
  • 리스폰스에서 속성의 특성을 확인하기
    • 속성이 필요하거나 필수인 경우 혹은 API 설명이 최솟값과 최댓값 등에 대한 정보를 제공하는 경우 항상 반환되어야 합니다.
  • 전체 네트워크 간의 연결 확인하기
    • 반드시 전체 네트워크 간의 연결을 포괄하는 테스트 호출을 수행 해야 합니다. 이 네트워크 간의 연결에는 예를 들면 방화벽, 프록시, VIP 또는 API 게이트웨이를 포함합니다. 방화벽은 유명한 버그 유발자입니다.