해당 게시글은 영진닷컴의 <일상 속 사물이 알려주는 웹 API 디자인 - 아노드 로렛>을 바탕으로 작성 되었으며
영진닷컴의 저작권 허락을 바탕으로 게재되는 글입니다.
2편 - [좋은 웹 API 디자인] 사용하기 좋은 API 디자인 https://smaivnn.tistory.com/9
API란 무엇인가?
웹 어플리케이션 프로그래밍 인터페이스, 줄여서 API라고 부르는 이 것은 개발을 하며 정말 많이 보고 듣는 단어이다. 좋은 웹 API 디자인을 알아보기 이전에 우선 이 API가 무엇인지에 대해 정의 하는 것이 필요하다.
인터페이스(interface)란 뭘까? 사전적 의미는 상호작용이다. 즉, API란 애플리케이션이 다른 무엇과 상호작용을 하도록 하는 것이라는 추상화 된 개념을 갖는 것이다.
API 디자인이 왜 중요한데?
개발을 하며 우리는 많은 API를 활용하고, 또 내가 API를 만들기도 한다. 즉 개발자인 우리는 API를 제공하는 프로바이더(provider)이자 동시에 사용하는 컨슈머(consumer)인 것이다. 이처럼 우리가 사용하고 또 작성하는 API는 우리가 다른 API를 사용하듯이 내가 아닌 다른 개발자들이 사용 할 수 있으며, 이 때 유용하고 단순한 API를 기대한다.
자 그러면 이 API를 어떻게 디자인 해야할까? 정답은 적절하게이다. 적절하다라는 말이 참 책임감 없이 보인다. 하지만 맞는말이다. 예시를 들어 보자.만약 API를 구현하였지만 사용할 때 고려할 것이 너무 많다. 그리고 돌아오는 값도 너무 복잡하다. 그런 API는 쓰이지 않는다. API의 디자인은 직관적이고, 범용적이어야 하며, 목적성을 갖으며, 컨슈머의 입장을 고려해야 한다.
우리는 컨슈머의 입장을 고려해야 한다. 즉, 사용자의 목적을 파악한 API를 디자인해야한다. 그렇다면 사용자의 목적은 어떻게 파악할 수 있을까? 바로 누가?, 무엇을?, 어떻게?라는 질문을 통해 파악하는 것이다.
ex) 누가 이 기능을 이용하기 위해서 무엇을 하는가? 그렇다면 이 무엇을 하려면 어떻게 이루어지는가?
이때 당연하지만 들어갈 것은 입력과 출력이다. 어떤 데이터를 넣었을 때 어떤 출력이 나오나 또한 고려해야 한다.
정리하자면 API는 컨슈머의 입장에서, 컨슈머가 무엇을 어떻게 할까? 이때의 입력, 출력은 무엇일까?라는 목적에 맞게만 구현이 되면 된다. 이 것과 관련 없는 로직은 모두 프로바이더가 신경쓰고 관리할 일 이다.
REST api가 뭐야?
REST는 representational state transfer의 약자이다. 즉, 이 API는 정보(자원)를 인터넷을 통해 안전하게 서로 주고 받도록 하는 인터페이스이다.
이 때 우리는 HTTP request와 response를 사용하는데, request에는 (대표적으로)경로와 HTTP 메서드, body가 존재하며
response에는 HTTP 상태코드, response body가 존재한다.
HTTP 메서드
대표적으로 GET, POST, PUT, PATCH, DELETE가 존재한다.
Promise, axios 등 HTTP 기반 비동기 통신 라이브러리 등을 사용하였다면 한번 쯤 사용 해보았을 것이다.
해당 메서드를 언제 사용하는지만 짚어 보도록 하곘다.
GET : 읽기, 가져오기, 검색하기 등에서 사용된다. query 파라미터
POST : 리소스의 생성(추가)을 의미한다. body 파라미터
PATCH : 리소스의 부분 수정에 주로 사용된다. body 파라미터
PUT : 리소스를 완전 교체 혹은 없는 겨우 새로 생성(이 때 POST와 동일한 효과)한다. body 파라미터(단, 교체의 경우 query 파라미터)
DELETE : 리소스에 대한 삭제. query 파라미터
개발을 하다 보면 해당 내가 구현하려는 것이 어떤 HTTP메서드에 해당 되는지 애매한 경우가 있을 것이다.
이처럼 유즈케이스에 적합한 다른 메서드가 없을 때 주로 POST가 기본값으로 선택된다.
경로 파라미터와 쿼리 파라미터
경로
우리는 /를 통해서 경로를 폴더와 같은 계층적 구조로 표현한다. 그렇다면 이 경로를 나누는 것은 어떤 것을 기준으로 나누는 것일까? 명확한 기준은 없으나 경로는 반드시 사용자 친화적으로 구성해야 한다.
가령 예를 들어, /c/p 보다 /category/product가 API를 이용하는 사용자들의 해석이 쉽도록 정보를 제공한다.
가장 일반적으로 사용하는 포맷은 / {콜렉션의 아이템의 타입을 반영하는 복수형의 이름} / {아이템의 id} 꼴이다.
예를 들어, /products/{productId}와 같은 형식이다.
이러한 것을 확장하여 /상위리소스의 복수형/{상위리소스ID}/하위리소스의 복수형/{하위리소스ID} 와 같이 확장 가능하다.
경로를 구성할 때 주의할 점은 리소스 경로는 유일해야하며, 반드시 사용자 친화적이어야 (권장)한다.
쿼리
상품을 조회한다고 생각해보자. 우리는 특정한 상품을 조회하고 싶다.
우리는 이 상품을 여러가지 질의, 가령 예를 들어 상품명, 상품ID등 특정 질의어를 통해 특정할 것이다.
이 때 우리는 쿼리 파리미터라고 불리는 질의어를 경로에 함께 붙여 보낸다.
일반적으로 쿼리 파라미터는 ? 다음에 있게 되며, 이름=값 의 형태를 띈다. 여러 쌍이라면 &를 통해 연결한다.
만약, 상품 이름이 card, 상품 ID가 2라면 ?product=card&productId=2와 같은 형식을 띄는 것이다.
고려할 원칙
- 리소스 지향 설계: URL은 리소스를 나타내야 한다. 예를 들어, /users는 사용자들을 나타내고, /users/123는 ID가 123인 사용자를 나타냅니다.
- HTTP 메서드 사용: HTTP 메서드 (GET, POST, PUT, DELETE 등)는 리소스에 대한 CRUD 작업을 나타내야 합니다. 예를 들어, GET /users는 사용자들을 조회하고, POST /users는 새 사용자를 생성합니다.
- URL에는 명사 사용: URL에는 동사 대신 명사를 사용해야 합니다. 예를 들어, /getUser 대신 /users를 사용합니다.
- 쿼리 파라미터 사용: 필터, 정렬, 페이징 등의 작업은 쿼리 파라미터를 사용하여 나타내야 합니다. 예를 들어, /users?sort=age는 사용자들을 나이 순으로 정렬합니다.
- 요청 본문 사용: POST와 PUT 요청에서는 요청 본문을 사용하여 리소스의 속성을 전달해야 합니다. 예를 들어, POST /users 요청의 본문은 새 사용자의 속성을 포함합니다.
body에 들어갈 데이터는 주로 다음과 같다.
- 생성 또는 수정할 리소스의 속성: 예를 들어, 사용자를 생성하거나 수정하는 POST /users 또는 PUT /users/{id} 요청에서 body는 사용자의 속성 (예: 이름, 이메일 등)을 포함합니다.
- 작업에 필요한 추가 정보: 예를 들어, 사용자의 비밀번호를 변경하는 PATCH /users/{id}/password 요청에서 body는 새 비밀번호와 현재 비밀번호를 포함할 수 있습니다
'Web' 카테고리의 다른 글
[NestJs/트러블슈팅] NestJs에서 mongoDB find(), virtual field (0) | 2023.10.26 |
---|---|
[SERVER] 웹 서버와 WAS 그리고 DB (0) | 2023.03.14 |
[좋은 웹 API 디자인] 사용하기 좋은 API 디자인 (0) | 2023.03.03 |
[OAuth2.0] 카카오 로그인 구현 (0) | 2023.02.25 |
[node.js] socket.io 예제와 정리 (0) | 2023.02.25 |