일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- AES
- XSS 예방
- 내도메인 한국
- fk컬럼 삭제
- 스왑 메모리
- jstl dependency
- jenkins git ignore file 추가
- 하이브리드암호화
- rsa java
- jstl 종류
- aws lightsail 배포
- Flutter
- rsa 복호화
- Stored Procedure log
- spring
- git
- aws
- 지속쿠키
- 하이브리드 암호화
- docker error
- springboot3 jstl
- springboot 배포
- Docker
- lightsail 도메인 연결
- 제약조건 제거
- RSA
- 세션쿠키
- aws lightsail
- 플러터
- swap file
- Today
- Total
easycode
[CS] RESTful API란? (feat. REST API 명세서 작성 가이드) 본문
(혹시 글이 제대로 보이지 않으시면 다크모드를 잠시 꺼 주세요. 감사합니다)
이번 프로젝트는 이전에 했던 프로젝트와 달리 프런트엔드와 백엔드로 나뉘어 진행했다. 나는 백엔드 쪽이었고, 프런트엔드와 소통하기 위해선 API 명세서를 작성해야 했다. API 명세서를 적으면서 공부했던 기록을 간단하게 남겨보려 한다.
RESTful API를 말하기 전에 우리는 먼저 REST를 알아야 한다.
REST는 어떻게 나오게 되었나?
REST(Representational State Transfer)는 월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식으로, HTTP의 주요 저자 중 한 사람인 로이 필딩의 박사학위 논문에서 최초로 소개되었다.
REST란?
쉽게 말하자면, 자원의 현재 상태를 표현한 것이다. 자원의 현재 상태라니? 자원을 주고 받는 게 아닌가요? 아니다. 실제 자원(resource)은 DB에 저장되어 있다. 따라서 우리는 URI를 통해 자원(resource)을 표현하고, HTTP Method를 통해 해당 자원에 대해 CRUD를 적용하는 것이다. 즉, 우리는 REST API를 통해 자원의 실재를 주고받지 않는다. resource(자원)는 DB에 저장되어 있고, 우리는 restful한 api를 통해 DB에 저장되어 있는 해당 자원의 현재 상태를 주고받는 것이다.
REST의 구성요소
- URI (자원, resource)
- HTTP 메서드 (행위)
- REST (resource가 어떻게 표현되는지)
즉, RESTful API 혹은 REST API는 앞서 말한 REST 가이드를 잘 지켜 작성된 api라는 뜻이다.
RESTful API 설계 규칙
RESTful한 API를 설계하기 위해선 REST 가이드를 잘 지켜야 한다. REST 구성요소와 함께 어떤 규칙이 있는지 살펴보자.
URI
- URI에는 어떤 자원인지 명시되어 있어야 한다.
GET /users
위와 같은 uri가 있다면, 여기서 자원은 user를 가리킨다 (user가 아닌 users인 이유는 user가 특정한 하나의 객체가 아니기 때문이다)
- 리소스명은 동사보단 명사를 사용한다.
- URI에는 어떤 행위인지가 나타나면 안된다.
- 행위는 올바른 HTTP Method를 통해 나타낸다.
- URI를 작성할 땐 되도록이면 모두 소문자로 작성한다.
- /(슬래쉬)는 계층을 나타내는 데 사용되며, 계층은 3개를 넘어가지 않는 게 좋다.
- URI의 마지막엔 /를 넣지 않는다.
- 구별해야 할 일이 있다면 _(언더바)를 사용하지 않고, -(하이픈)을 사용한다.
예를 들어, 회원가입을 통해 user를 추가하는 API가 있다고 하자.
POST /users/insertUser
위 API는 좋은 URI일까? 답은 "아니다"이다.
1) insert라는 행위가 드러나있고, 2) -(하이픈)이 아닌 낙타 표기법으로 구분해 줬다.
왜 그렇게 쓰면 안 될까?
URI에는 어떤 리소스를 다루고 있는지와 리소스의 계층 구조에 대한 것만 드러나야 한다.
또한, -(하이픈) 대신 낙타 표기법이나 대문자를 섞어 쓰는 등의 표현은 해당 API를 사용하는 사람에게 혼동을 줄 수 있으며 오타가 났을 경우 서버에 요청을 보내는 것 자체가 실패한다.
따라서 해당 URI는 아래와 같이 바꿀 수 있다.
POST /users/register
이렇게 되면 1) 리소스로 user를 다루고 있고, 2) 행위는 POST라는 메서드로만 표현됐으며, 3) URI에 등록이라는 뜻의 register를 넣어 회원가입할 때 쓰이는 URI임을 명시해 줬다.
HTTP Method
- 올바른 HTTP 메서드를 사용하자
- HTTP Method
- POST (resouce를 생성)
- PUT (부분적으로 수정)
- PATCH (대체)
- GET (조회)
- DELETE (삭제)
다음은 자주 구분되는 메서드들 간의 차이점이다.
POST vs GET
POST | GET |
- 서버에 리소스를 새로 생성하는 것 - SQL문으로 보자면 CREATE에 가까움(그러나 생성만 하는 것은 아니다) - Body가 존재하고, 요청하는 데이터를 Body에 담아서 보낸다(따라서 URL에 값이 바로 보이는 GET보다 보안적으로 낫다) - 멱등성이 보장되지 않는다. |
- 서버에 리소스를 요청하는 것 - SQL문으로 보자면 SELECT에 가까움 - 요청하는 데이터를 파라미터에 담아서 보내므로 URL에 데이터가 노출된다 - Body가 존재하지 않는다. - 멱등성 보장 |
PUT vs PATCH
PUT과 PATCH는 보통 둘 다 데이터를 수정할 때 쓰이긴 하지만 아래와 같은 차이점이 있다.
PUT | PATCH |
- 멱등성이 보장되지 않는다. - 요청한 URI에 payload(Request Body)에 있는 자원으로 대체 - 대체 == 전체적인 수정이므로 만약 데이터가 제대로 들어가지 않았을경우, 부분적으로 데이터가 null로 저장될 수 있다. |
- 멱등성이 보장 되게도, 보장 되지 않게도 설계할 수도 있다. - 요청한 URI에 payload(Request Body)에 있는 자원으로 부분적 수정 |
멱등성이란?
어떤 연산을 여러 번 수행해도 결과가 달라지지 않는 성질을 뜻한다. 즉, 멱등성을 보장한다는 건 해당 행위를 계속 반복해도 응답이 동일하다는 뜻이다. 그러나 POST와 PUT의 경우 새로운 걸 생성하거나 대체하므로 항상 응답이 동일하지는 않다.
(번외) 그럼 멱등성과 일관성은 뭐가 다를까? (더 보기)
멱등성 : 어떤 연산을 여러 번 수행해도 결과가 달라지지 않는 성질, API 호출과 같은 상위 수준의 작업에 사용
일관성 : 데이터 분산 시스템에서 데이터의 일관성과 관련된 것
(번외) uri와 url의 차이점은 뭘까? (더 보기)
uri(uniform resource identifier) : 자원을 식별하기 위한 것
url(uniform resource locator(위치)) : 인터넷 자원의 위치
* 참고했던 글 (제 글보다도 훨씬 쉽게 풀이되어 있고, 세세하게 알려주고 있기 때문에 읽어 보는 걸 추천드립니다)
RESTful API에 관한 글
https://evan-moon.github.io/2020/04/07/about-restful-api/
https://donghun.dev/Restful-API
GET vs POST 차이
https://brilliantdevelop.tistory.com/33
PUT vs PATCH 차이
https://tecoble.techcourse.co.kr/post/2020-08-17-put-vs-patch/
'CS' 카테고리의 다른 글
[자료구조] Map과 Map 컬렉션들(HashMap, HashTable, LinkedHashMap) (1) | 2024.02.27 |
---|---|
SQL Injection 설명과 예방법(Mybatis&JPA) (0) | 2024.01.16 |
세션쿠키와 지속쿠키의 차이점 (feat.cookie secure) (0) | 2024.01.15 |
크로스 사이트 스크립팅 (XSS)의 의미와 예방법(feat.innerText vs textContent) (2) | 2024.01.15 |