-
OpenAPI와 스웨거를 활용한 실전 API 설계를 읽고 ... (1)개발하면서/타인글보면서 2024. 5. 6. 20:00반응형
어느 날 DigitalOcean 블로그에서 "journey to Python Client generation" 글을 보았다.
최근 전자공시시스템의 OPENDART와 한국투자증권의 OpenKIS 연동하면서
규격화된 무언가가 있어서 간단하고 빠르게 클라이언트 코드 생성 했으면 좋겠다고 생각하던 차였다.요약하면 DigitalOcean의 api를 OpenAPI로 정의하고 Micosoft에서 개발한 autorest(https://github.com/Azure/autorest)로
클라이언트 코드를 생성한다는 내용이다.
와우!! 한번 배워두면 RestAPI로 연동하는 코드는 쉽게 만들겠다 싶어 OpenAPI 책을 읽게 되었다.
autorest는 Github wiki 보면서 정리할 예정
1. API와 OpenAPI 정의
API는 각 서비스가 제공할 수 있는 것이 무엇이고, 다른 서비스와 어떻게 상호작용할 수 있는지를 정의한다.
API 생태계에서 API는 생태계가 흩어지지 않고 잘 유지되도록 붙잡아 두는 역할을 담당하고 있다.
API 생태계에서 개별 서비스들이 어떻게 연결돼 있는지를 알아야 전체를 이해할 수 있는 큰 그림을 그릴 수 있는데
이를 OpenAPI에 정의함으로써 쉽게 알 수 있다.
또한 API의 변경사항도 쉽게 파악 가능해져서 API 생태계가 깨지는 걸 막아준다.
2. 스웨거란?
스웨거 프로젝트는 스웨거 UI와 대략적인 YAML 파일 작성 가이드로 시작됐고,
이를 토대로 더 많은 도구가 만들어졌고 명세와 표준이 되었다.
이런 도구와 명세를 모두 합쳐서 스웨거(Swagger)라고 부른다.
2015년, 스웨거 프로젝트는 스마트베어에 인수되고 명세 부분은 리눅스 파운데이션에 OpenAPI라는 이름으로 기부되었다.
https://spec.openapis.org/oas/latest.html#openapi-specification
https://swagger.io/docs/specification/about/
3. HTTP 호출하기
포스트맨으로 하는법과 terminal에서 command를 이용하여 호출하는 법을 소개하는데 command 방법을 소개한다.
$> telnet farmstall.designapis.com 80 <-- http $> openssl s_client -quiet -connect farmstall.designapis.com:443 <-- https # Header GET /v1/reviews HTTP/1.1 <enter> Host: farmstall.designapis.com <enter> <enter> # 아래는 Body
4. OpenAPI 첫인상
openapi 에는 버전(3.0.3)을 입력한다.
info에는
version: API version
title: API title
description: API 설명 "|-"로 여러 줄을 마크다운으로 작성 가능하다.
contact: 연락처.
license: API 라이센스
가 올 수 있다.
externalDocs에는 외부 문서링크를 입력하고 tag를 달 수 있으며 마지막으로 servers에 서버 목록을 정의할 수 있다.
openapi: 3.0.3 info: version: v1 title: FarmStall API description: |- 마크다운 작성 An API for writing reviews about your favourite (or worst) farm stalls. ...중략 "A totally average place." — Jane Fair <br/> ![3 stars](https://farmstall.designapis.com/img/rating-3.png) contact: name: Josh Ponelat email: jponelat+daso@gmail.com url: https://farmstall.designapis.com license: url: https://www.apache.org/licenses/LICENSE-2.0 name: Apache 2.0 externalDocs: url: https://farmstall.designapis.com description: Hosted docs tags: - name: Reviews description: Reviews of your favourite/worst farm stalls - name: Users description: Users and authentication servers: - url: "https://farmstall.designapis.com/v1" description: Production server
5. OpenAPI 조회 GET
paths 아래
실제 구현된 API의 path를 정의하고 ※ /reviews/{reviewId}
HTTP method를 넣는다. get, post, delete, put
HTTP method 별로 정의된 tag를 추가할 수 있고, description으로 API 설명도 가능하다.
parameters에는 name, in, schema를 선언할 수 있다.
in에는 path, query, header, cookie가 올 수 있다.
보다 자세한 parameters 설명은 swagger 페이지를 참고하자.
... paths: /reviews/{reviewId}: get: tag: - Reveiws description: Get a single review parameters: - name: reviewId in: path required: true schema: type: string description: The review's ID example: 3b5b1707-b82c-4b1d-9078-157053902525 minLength: 36 maxLength: 36 pattern: "[a-zA-Z0-9-]+" response: "200": description: A single review
6. OpenAPI 조회 응답 정의
parameters와 같은 depth에 responses를 정의한다.
응답 코드를 적고 description에 설명을 적는다.
parameters와 조금 다르게 json 리턴은
content -> application/json -> schema 순으로 데이터를 정의한다.
responses: "200": description: A single review content: application/json: schema: type: object properties: message: type: string example: An awesome time for the whole family. rating: type: integer minimum: 1 maximum: 5 example: 5 userId: minLength: 36 maxLength: 36 pattern: "^[a-zA-Z0-9-]+$" nullable: true example: 3b5b1707-b82c-4b1d-9078-157053902525 uuid: minLength: 36 maxLength: 36 pattern: "^[a-zA-Z0-9-]+$" example: 3b5b1707-b82c-4b1d-9078-157053902525 "404": description: Review not found
6-1. 응답 코드 카테고리
범위 카테고리 참고 1xx Informational 서버가 요청을 받았다는 임시 응답.
웹소켓 연결로 업그레이드 됐을 때 사용되는것이 가장 대표적인 예2xx Success 200 OK나 201 Created 처럼 요청 성공을 의미 3xx Redirects 요청 자원의 위치/URI가 변경됐음을 의미 4xx Client Error 클라이언트가 제공한 요청 정보에 오류가 있음을 의미 5xx Server Error 서버 처리 과정에 오류가 있음을 의미 6-2. 주요 미디어 타입
미디어 타입 설명 text/html 웹 서버가 반환해 주는 HTML text/csv 쉼표로 구분된 값 image/png PNG 형식으로 인코딩된 이미지 application/json JSON 데이터 application/xml XML 데이터 7. OpenAPI 자원생성 Post
GET과 다른 부분은 parameters 대신
requestBody -> content -> application/json -> schema로 데이터 정의가 바뀌었다는 점이다.
paths: /reviews: post: tags: - Reviews description: Create a new Review requestBody: description: A new Review content: application/json: schema: type: object properties: message: type: string example: An awesome time for the whole family. rating: type: integer minimum: 1 maximum: 5 example: 5
8. OpenAPI 자원생성 응답 정의
응답은 GET 방식의 응답과 다르지 않다.
... minimum: 1 maximum: 5 example: 5 responses: "201": description: Successfully created a new Review content: application/json: schema: type: object example: message: A lovely experience rating: 4 properties: message: type: string example: An awesome time for the whole family. rating: type: integer minimum: 1 maximum: 5 example: 5
9. 인증과 인가
인증: 누구인지를 증명하는 일이며 아이디와 비밀번호를 통해 증명한다.
인가: 사용자 상세 정보를 조회하거나 새 후기를 생성하는 것처럼 특정 행위나 특정 자원에 대한 접근을 허가받는 것을 의미한다.
9-1. 인증 준비
POST /users로 신규 유저를 등록하고
POST /token을 통해 MyUserToken 값을 얻어오는 API를 정의한다.
#... paths: /users: post: tags: - users description: This can only be done by the logged in user. operationId: createUser requestBody: description: Created user object content: application/json: schema: type: object properties: username: type: string example ponelat password: type: string format: passwrod fullname: type: string example: Josh Ponelat response: '201': description: Successfully created a new user content: application/json: schema: type: object properties: username: type: string example: ponelat uuid: type: string example: f7f680a8-d111-421f-b6b3-493ebf905078 /tokens: post: description: Create a new token operationId: createToken requestBody: description: Created token object content: application/json: schema: type: object properties: username: type: string example: ponelat password: type: string format: password response: '201': description: Create a new token for gaining access to resources. content: application/json: schema: type: object properties: token: type: string
9-2. 인가 처리
POST /tokens에서 가져온 token을 Post /reviews Authorization 헤더에 추가해서
인증과 인가된 사용자만 후기 생성할 수 있도록 작업한다.components -> securitySchemes -> [SecurityName]으로 보안 스킴을 정의하고
인가가 필요한 API에는 security를 정의하고 [SecurityName]을 추가한다.
openapi: 3.0.3 #... paths: /reviews: post: #... security: - {} # <-- 보안이 필수가 아닌 선택으로 할 경우 해당 line 추가 - MyUsertoken: [] componets: securitySchemes: MyUserToken: type: apiKey in: header # apiKey, http, oauth2, openIdConnect name: Authorization
10. OpenAPI 브라우저에서 보기
yaml로 작성한 OpenAPI를 호스팅 하는 방법을 알아본다.
https://github.com/designapis/openapi/tree/main/ch08/site
ch08에 예제파일 index.html과 openapi.yml을 다운로드한다.
그리고 다운로드한 폴더에서 아래 명령어를 입력하고 http:/localhost:8080에 접속하면!!
$> python -m SimpleHttpServer 8080 # Python2 기준
$> python -m http.server 8080 # Python3 기준
책의 1부는 이미 만들어져 있는 직판장 API를 OpenAPI로 작성하는 법을 배웠다면
2부에는 백지상태에서 웹 애플리케이션에 필요한 새로운 API를 새롭게 설계하는 법을 배운다.반응형