-
OpenAPI와 스웨거를 활용한 실전 API 설계를 읽고 ... (4, 마지막)개발하면서/타인글보면서 2024. 5. 12. 20:42반응형
지금까지 구현한 API에서 오류가 발생하는 상황을 살펴보고 예외 처리를 어떻게 하는지 알아본다.
그리고 JSON 스키마를 이용하여 엄격하게 입력값 유효성 검증 하는 방법도 알아본다.
모든 일이 다 잘되기를 바라지만 현실은 그렇지 못하다.
실패를 항상 피해 갈 수는 없지만 그 실패를 발견하고, 복구하고, 고치는 방법을 찾아내야 한다.모든 API에 대해 클라이언트 에러가 발생할 상황을 나열하고 범주화해서 상태 코드 3개로 매핑한다.
상태 설명 발생 위치 400 유효하지 않은 입력 POST, PUT, 쿼리 파라미터가 포함된 GET을 사용하는 엔드포인트 403 허용되지 않은 접근 권한 관련 비즈니스 로직이 포함된 모든 엔드포인트 404 자원이 존재하지 않음 리소스 엔드포인트 및 서브 리소스 컬렉션 엔드포인트 오류 메시지가 사람이 이해하는 것을 넘어 클라이언트에서 에러 처리를 하기 위해선 일관된 형식의 에러 메시지가 필요하다.
두 개의 에러 형식을 알아보자.
1. OAS 도구 형식
{ "message": "error", # 전반에 걸쳐 사람이 이해할 수 있는 에러 메시지 "errors": [ { "path": "/jobs", # 입력값 유효성 오류일 때는 JSONPath, 그 외에는 URL 경로 "message": "error", # 필드에 발생한 특정 에러에 대해 사람이 읽을 수 있는 에러 메시지 "errorCode": "식별자" # 에러 타입을 알려주는 식별자 ex: "type.openapi.validation" } ] }
2. problem+json 형식
응답을 반환할 때 Content-Type 헤더가 application/json이 아닌 application/problem+json 으로 지정한다. RFC 7807
{ "type": "https://petsitter.designapis.com/problem/not-found", # 에러 타입을 설명하는 URI "title": "not found resource", # 사람이 읽을 수 있는 짧은 에러 제목 "status": 404, # HTTP status code "detail": "not found resource #2 in jobs", # 사람이 읽을 수 있는 상세한 에러 설명 "instance": "/jobs/2" #문제 발생을 가리키는 URI }
두개의 에러 응답을 components에 추가해 보자.
openapi: 3.0.3 #... components: schemas: OASError: # <-- OAS 도구 에러 형식 공통 스키마 type: object properties: message: type: string description: Human-readable error message errors: type: array items: type: object properties: path: type: string description: | For input validation errors, identifies where in the JSON request body the error occurred. message: type: string description: Human-readable error message. errorCode: type: string description: Code indicating error type. Problem: # <-- problem+json 에러 형식 공통 스키마 type: object properties: type: type: string description: URI indicating error type. title: type: string description: Human-readable error title. status: type: integer description: HTTP status code. detail: type: string description: Human-readable error details. instance: type: string description: URI indicating error instance.
OAS 도구 처리: 입력값 유효성 검사(400), 인증 오류(401)
Problem 처리: 리소스가 존재하지 않은 경우(404), 권한 오류(403)
고급 JSON 스키마를 이용한 입력값 유효성 검증
- 필드를 읽기 전용 또는 쓰기 전용으로 설정
- 숫자 제약 조건 강제
- 문자열 형식 강제
- 배열 제약 조건 강제
- 열거형 데이터 정의
- 필수 및 선택 프로퍼티 나열
- 기본값 설정
readOnly: 값을 읽을 수만 있고 값을 변경할 수는 없다. 응답에만 사용. ex: id property
writeOnly: 값을 읽을 수는 없고 값을 변경할 수는 있다. 요청에만 사용. ex: password property
multipleOf: 입력한 수의 배수만 입력 가능
minimum: 하한값(입력값 포함)
exclusiveMinimum: 하한값 입력값 제외 여부
maximum: 상한값(입력값 포함)
exclusiveMaximum: 상한값 입력값 제외 여부
minLength: 문자열 최소 길이
maxLength: 문자열 최대 길이
pattern: 정규표현식 지정
format: JSON 스키마와 OpenAPI 명세에서 유효성 검증할 때 사용하는 공통 형식 strings
minItems: 배열에 저장 가능한 최소 개수
maxItems: 배열에 저장 가능한 최대 개수
uniqueItems: 중복 허용 여부
정의된 값만 입력으로 받는다면 enum사용을 추천한다.
파라미터는 개별 파라미터에 required: true/false 지정이 가능한데
프로퍼티는 객체에 required를 사용하고 프로퍼티 이름을 지정한다.마지막으로 프로퍼티의 기본값 설정은 default를 이용한다.
지금까지 알아본 JSON 스키마 기능을 예제로 알아보자
openapi: 3.0.3 info: title: PetSitter API version: "0.1" paths: {} components: schemas: SchemaName: type: object properties: id: type: integer readOnly: true # readOnly password: type: string format: password # password format writeOnly: true # writeOnly my_number: type: integer multipleOf: 2 # 숫자형 제약조건 minimum: 2 maximum: 20 exclusiveMinimum: true exclusiveMaximum: true MyBingoNumber: type: object properties: my_numbers: type: array minItems: 1 # 배열 제약조건 maxItems: 2 uniqueItems: true items: type: integer gender: type: string enum: # enum - male - female - others Contact: type: object properties: name: type: string email: type: string format: email # email format phone: type: string default: 010-0000-0000 # default keyword address: type: object required: # 필수 프로퍼티 지정 - name - email
지금까지 "OpenAPI와 스웨거를 활용한 실전 API 설계" 소개한 내용 중 기술적인 내용들을 나름 정리해 보았다.
이렇게 편안하게 읽히는 책을 접하면 다음번에 저자 또는 번역가 분이 책을 내면 관심이 가는 건 어쩔 수 없다.
주식 쪽 OpenAPI 연동을 쉽게 하려고 책을 집었는데 생각 외로 좋은 시간이었다.
반응형