회원 정보 관리 API를 만들어보자
[요구사항]
1. 회원 목록 조회
2. 회원 조회
3. 회원 등록
4. 회원 수정
5. 회원 삭제
[API URI 설계]
*URI : Uniform Resource Identifier
1. 회원 목록 조회 : /read-member-list
2. 회원 조회 : /read-member-by-id
3. 회원 등록 : /create-member
4. 회원 수정 : /update-member
5. 회원 삭제 : /delete-member
=> 이것은 좋은 URI 설계일까?
API URI 고민
UR에서 가장 중요한 것은 리소스 식별이다.
리소스는 또 뭘까?
회원을 API URI 설계에서 회원을 조회하고, 등록하고 수정하는 것이 리소스가 아닌
회원이라는 개념 자체가 리소스이다.
리소스를 어떻게 식별하는 게 좋을까?
회원을 등록하고 수정하고 조회하는 것을 모두 배제한다.
회원이라는 리소스만 식별하면 되므로 회원 리소스를 URI에 매핑한다.
[API URI 설계시 리소스를 식별, URI 계층 구조 활용]
1. 회원 목록 조회 : /members
2. 회원 조회 : /members/{id}
3. 회원 등록 : /members/{id}
4. 회원 수정 : /members/{id}
5. 회원 삭제 : /members/{id}
*계층 구조상 상위를 컬렉션으로 보고 복수 단어 사용을 권장한다.(member (x) -> members(o))
위처럼 URI를 설계하면 URI가 모두 같은데 어떻게 구분하지?
[리소스와 행위를 분리]
- URI는 리소스만 식별한다.(가장 중요)
- 리소스와 해당 리소스를 대상으로 하는 행위를 분리한다.
리소스 : 회원
행위 : 조회, 등록, 삭제, 변경
- 리소스는 명사, 행위는 동사가 된다.
행위를 구분하기 위하여 사용되는 것이 HTTP 메서드이다.
HTTP 메서드
주요 메서드
- GET : 리소스 조회
- POST : 요청 데이터 처리, 주로 등록에 사용
- PUT : 리소스를 대체, 해당 리소스가 없으면 생성
- PATCH : 리소스 부분 변경
- DELETE : 리소스 삭제
기타 메서드
- HEAD : GET과 동일하지만 메시지 부분을 제외하고, 상태 줄과 헤더만 반환
- OPTIONS : 대상 리소스에 대한 통신 가능 옵션(메서드)을 설명(주로 CORS에서 사용)
- CONNECT : 대상 자원으로 식별되는 서버에 대한 터널을 설정
- TRACE : 대상 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행
*CORS란? Cross-Origin Resource Sharing의 약자. 교차 출처 리소스 공유로 번역, 브라우저에서 다른 출처의 리소스를 공유하는 방법이다.
GET
- 리소스 조회에 사용
- 서버에 전달하고 싶은 데이터는 query(쿼리 파라미터, 쿼리 스트링)을 통해서 전달
- 메시지 바디를 사용해서 데이터를 전달할 수 있지만, 지원하지 않는 곳이 많아서 권장하지 않음.
클라이언트 : 서버야 나 100번 회원 조회 좀 할게
클라이언트가 리소스 조회 요청 메시지를 전달한다.
리소스 조회 요청 메시지가 서버에 도착한다.
서버 : ㅇㅋ! 100번 회원 리소스 보내줄게
서버는 클라이언트의 요청에 요청 데이터를 응답 메시지로 만들어서 반환한다.
POST
- 요청 데이터 처리
- 메시지 바디를 통해 서버로 요청 데이터 전달
- 서버는 요청 데이터를 처리
메시지 바디를 통해 들어온 데이터를 처리하는 모든 기능을 수행한다.
- 주로 전달된 데이터로 신규 리소스 등록, 프로세스 처리에 사용한다.
클라이언트 : 내가 데이터 줄테니까 처리해줘.
클라이언트가 POST 방식으로 데이터를 담아 서버에 메시지를 전달한다.
서버는 POST로 신규 등록하는 요청이란걸 알고 처리한다.
신규 자원 생성은 200이나 201로 응답을 보낸다.
자원이 생성된 경로(location)과 데이터도 보낼 수 있다.
POST는 요청 데이터를 어떻게 처리한다는 뜻일까?
-스펙 : POST 메서드는 대상 리소스가 리소스의 고유한 의미 체계에 따라 요청에 포함된 표현을 처리하도록 요청합니다. (구글 번역)
=> 이게 대체 뭔 소린가?
정리하자면 이 리소스 URI에 POST 요청이 오면 요청 데이터를 어떻게 처리할지 리소스마다 따로 정해줘야 한다는 것이다.
(정해진 것이 없음)
POST 사용 예시
- HTML 양식에 입력된 필드와 같은 데이터 블록을 데이터 처리 프로세스에 제공한다.
HTML 폼에 입력한 정보로 회원 가입, 주문
- 게시판, 뉴스 그룹, 메일링 리스트, 블로그 또는 유사한 기사 그룹에 메시지를 게시한다.
게시판 글쓰기, 댓글 쓰기
- 서버가 아직 식별하지 않은 새 리소스를 생성한다.
신규 주문 생성
- 기존 자원에 데이터를 추가한다
한 문서 끝에 내용 추가
POST 정리
1. 새 리소스 생성(등록)
-서버가 아직 식별하지 않은 새 리소스 생성
2. 요청 데이터 처리
-단순히 데이터를 생성하거나 변경하는 것을 넘어서 프로세스를 처리해야 하는 경우
예)주문 -> 결제 완료 -> 배달 시작 -> 배달완료처럼 단순히 값 변경을 넘어 프로세스의 상태가 변경되는 경우
-POST의 결과로 새로운 리소스가 생성되지 않을 수도 있다.
POST /orders/{orderId}/start-delivery(컨트롤 URI)
3. 다른 메서드로 처리하기 애매한 경우
예)JSON으로 조회 데이터를 넘겨야 하는데, GET 메서드를 사용하기 어려운 경우(GET메서드는 바디를 허용하지 않는 경우가 많다)
-애매하면 POST를 쓴다.(POST는 모든 것을 할 수 있다)
PUT
-리소스를 대체
리소스가 있으면 대체, 없으면 생성 (쉽게 말해 덮어버린다.)
-클라이언트가 리소스를 식별한다.(중요!)
클라이언트가 리소스 위치를 알고 UR를 지정한다. PUT : /members/100
이것이 POST와의 큰 차이점이다. POST : /members
클라이언트가 서버에게 100번 회원에게 리소스를 보내겠다고 요청한다.
기존에 있던 100번 회원은 요청으로 인하여 리소스가 대체된다.
username : "young" -> "old"
age : 20 -> 50
만일 서버의 자원 중에서 100번 회원이 없다면 신규로 생성한다.
주의할 점은 덮어씌우기와 개념이 같기 때문에 필드를 덜 보내게 된다면 덜 보낸 채로 리소스가 대체된다.
PATCH
-리소스 부분 변경
PUT과 달리 부분적으로 데이터를 보내면 받은 데이터만 변경이 된다.
DELETE
-리소스 제거
HTTP 메서드의 속성
안전(Safe Methods)
- 호출해도 리소스를 변경하지 않는다.
- 단순 조회만 하는 GET은 안전하다. 리소스를 변경하는 POST, DELETE, PATCH, PUT은 당연히 안전하지 않다.
- GET이 안전하다고 해서 계속 호출하여 로그가 잔뜩 쌓여 서버에 장애가 발생한다면?
=> 안전은 해당 리소스가 변하는지 여부만 고려하기 때문에 이런 부분은 고려하지 않음.
멱등(Idempotent Methods)
- f(f(x)) = f(x)
- 한 번 호출하든, 두번 호출하든, 100번 호출하든 결과가 똑같다.
- GET : 몇 번 호출하던지 같은 결과가 조회된다.
- PUT : 결과를 대체한다. 똑같은 파일에 똑같은 요청을 하면 계속 기존의 것을 새로운 것으로 덮기 때문에 항상 결과가 같다.
- DELETE : 같은 요청을 여러번 해도 삭제된 결과는 같다.
- POST : 멱등아님!! 두 번 호출하면 같은 결제가 중복해서 발생할 수 있다.
멱등의 활용
- 자동 복구 메커니즘
- 서버가 TIMEOUT 등으로 정상 응답을 주지 못했을 때, 클라이언트가 같은 요청을 해도 되는지에 대한 판단 근거가 된다.
하지만 재요청을 하는 중간에 다른 곳에서 리소스를 변경해버리면 멱등이 적용되지 않는 건 아닐까?
예를 들어
사용자 1 : GET username : A , age : 20
사용자 2 : PUT username : A, age : 30
사용자 3 : GET username : A, age : 30 -> 사용자 2의 PUT으로 바뀐 데이터 조회
*멱등은 외부 요인으로 중간에 리소스가 변경되는 것 까지는 고려하지 않는다. 내가 동일한 요청을 했을 때에만 고려한다.
캐시 가능(Cacheable Methods)
응답 결과로 온 리소스를 캐시에 저장해 두고 사용해도 되는가?
(큰 용량의 데이터를 요청하고 같은 요청을 반복할 때 데이터를 로컬에 데이터를 저장해 두고 써도 되는가?)
-GET, HEAD, POST, PATCH는 캐시를 사용할 수 있다.
-하지만 실제로는 GET, HEAD 정도만 캐시로 사용한다.
캐시를 사용하려면 똑같은 리소스랑 키가 맞아야 하는데, POST와 PATCH는 본문 내용까지 고려하기가 복잡하기 때문
-GET은 URI만 키로 잡고 캐시 하면 간단하다.
'CS' 카테고리의 다른 글
HTTP 상태 코드 (1) | 2022.10.02 |
---|---|
HTTP 메서드 활용 (0) | 2022.09.25 |
HTTP 기본 (0) | 2022.09.05 |
URI와 웹 브라우저 요청 흐름 (0) | 2022.09.04 |
인터넷 네트워크 (1) | 2022.09.04 |