스프링

HTTP API 설계

eunkyung 2023. 5. 15. 02:16

인프런 강의 정리 - 모든 개발자를 위한 HTTP 웹 기본 지식 섹션 4

[회원 정보 관리 API 설계]

설계에 앞서 요구사항이 회원 목록 조회, 회원 조회, 회원 등록, 회원 수정, 회원 삭제라고 하자.

URI설계 시 예를 들어 회원 조회 -> /search-member-by-ID 와 같은 식으로 설계할 수 있는데 이는 좋은 URI라고 할 수 없다.

 

좋은 URI 설계란

-가장 중요한 것은 리소스 식별이다. **최근에는 리소스가 아닌 representation으로 부름

리소스란? -> 회원이라는 개념이 리소스이다. 수정이나 등록은 리소스가 아니기에 리소스 식별을 위해서는 회원이라는 리소스만 식별하면 된다. (등록, 수정, 조회를 배제하고) =>회원 리소스를 URI에 매핑

이에 따라 다시 URI 설계를 해보면

*회원목록조회 -> /members *회원조회 -> /members/{id} *회원 수정 -> /members/{id} 와 같은 결과

회원 조회와 회원 수정은 URI가 같은데 어떻게 구별할까??

 

-리소스와 행위를 분리.

URI는 리소스만 식별하고 리소스와 해당 리소스를 대상으로 하는 행위를 분리해야한다. 

리소스 - 회원, 행위 - 수정, 조회, 등록 등 | 리소스는 명사 / 행위는 동사

그렇다면 행위는 어떻게 구분할까??

 

-HTTP 메소드를 이용해 행위를 구분

HTTP 메소드를 클라이언트가 서버에 요청 시 기대하는 행동이다.

  • GET
    리소스 조회. 서버에 전달하고 싶은 데이터는 query(쿼리 파라미터, 쿼리 스트링) 통해 전달.
    메세지 바디를 사용 가능하기에 데이터 전달은 가능하지만 권장 X. 실무에서 바디에 데이터 넣어서 사용 X.
GET /members/0974 HTTP/1.1  //id가 0974인 회원 조회 요청
Host: localhost:8080

      위에 코드처럼 클라이언트가 서버에 요청을 했다면?

이와 같은 응답 데이터를 받음

 

 

 

 

 

  • POST
    요청 데이터 처리하는데 요청 시 메세지 바디에 요청 데이터를 담아서 전달. 
    서버는 요청 데이터를 처리하는데 베세지 바디의 데이터를 처리하는 모든 기능 수행. 주로 등록에 사용된다.
POST /members HTTP/1.1   //미리 /members로 요청 시 신규 등록이라고 정해놓았다고 가정.
Content-Type:application/json

{
"username":"somsom",
    "age":23
}

이렇게 요청 시 서버는 /members로 들어왔기에 신규 회원 등록.
/members/100   //신규 리소스 식별자 생성
{
"username":"somsom",
    "age":23
}

신규 생성 URI는 Location에 담아 응답 메세지가 서버 -> 클라이언트로.

 

>그렇다면 요청 데이터를 어떻게 처리할까?

대상 리소스가 고유 의미 체계에 따라 요청에 포함된 표현 처리

정리하면 POST요청 시 요청 데이터를 어떻게 처리할지 리소스마다 따로 정해야 한다. 

 

 

   *POST 사용 상황
     1. 새 리소스 생성. 2.요청 데이터 처리(단순 생성을 넘어 프로세스 처리 시). 3.다른 메서드가 처리 애매한 경우

  • PUT
    리소스 대체, 해당 리소스가 없으면 생성. 파일 생성과 유사( 같은 이름 파일이 있으면 덮어쓰기 되고 없을때는 생성)
    리소스가 있으면 대체(완전 덮어쓰기). 클라이언트가 리소스의 위치를 알고 URI를 지정한다(리소스를 식별)는 점에서 POST와 차이 .
PUT /members/100 HTTP/1.1
Content-Type:application/json

{
	"username":"newsom",
	"age":20
}

//리소스가 있을때 -> 대체. 리소스가 없으면->신규 리소스 생성.

**중요한 것은 리소스를 완전히 대체 하기에 age만 업데이트하고 싶다고 데이터에 age:20만 담아 보내면? -> username 필드는 사라지고 age만 남음(완전 덮어쓰기 개념) ->부분 변경 필요시 PATCH 사용!!

  • PATCH
    리소스 부분 변경. PATCH가 나중에 생겼기에 지원안되는 경우는 POST 사용
PATCH /members/100 HTTP/1.1
Content-Type:application/json

{
	"age":20  //age만 변경 원할 떄!! 이렇게 사용
}

//요청 시 age만 변경됨!
  • DELETE
    리소스 삭제
DELETE /members/0974 HTTP/1.1  //id가 0974인 회원 삭제 요청
Host: localhost:8080
  • HEAD , OPTIONS, CONNECT, TRACE

HTTP 메서드의 속성

  • 안전(Safe) - 호출해도 리소스를 변경하지 않는다
    GET은 조회만 하기에 안전하다고 할 수 있다. 호출 시 변경이 일어나는 것 = 안전하지 않다.
  • 멱등(Idempotent) - 몇 번을 호출하던지 결과가 항상 같다.
    GET은 같은 결과 조회 하기에 ok. PUT은 같은 요청 시 같은 걸로 대체되기에 같은 결과이기에 ok. DELETE도 같은 요청 시 결국 삭제된 결과는 같음 ok. POST는 두 번 호출 시 중복 발생 가능하기에 멱등이 아님(예를 들어 중복 결제)
    *활용 : 자동 복구 메커니즘(정상응답 X시 같은 요청해도 어차피 결과는 같기에 이를 근거로 같은 요청 다시 해도 됨)
    +) 멱등은 요청 중간에 외부 요인에 의해 리소스 변경은 고려하지 않음. 중간 변경 시 멱등 아닌걸로 판단.
  • 캐시 가능(Cacheable) -  응답 결과 리소스를 캐시해서 사용해도 되는가
    같은 요청을 중복을 줄이기 위해 중간에 저장해 놓는게 캐시
    실제로는 GET, HEAD 정도만 캐시 사용하지만 POST,PATCH도 가능(구현 힘듬)