인프런 커뮤니티 질문&답변

김선동님의 프로필 이미지

작성한 질문수

Kotlin으로 개발하는 Spring Boot Web MVC

Web 개론

HTTP Method 설명에서요~ PATCH 메서드는 왜 없을까요?

해결된 질문

작성

·

3.6K

0

실무에서 잘 사용하지 않나요?

또, GET의 DataBody가 없다고 하셨는데, Request Body에 대한 RFC 표준이 갱신되어서 작성은 가능하지만 예전 표준의 잔재로 일부 서비스에선 해당 정보에 대해 응답하지 않을 수 있다고 알고 있습니다.

답변 5

8

Steve (예상국)님의 프로필 이미지
Steve (예상국)
지식공유자

답변이 늦어 죄송합니다. 

1. PATCH 에 대해서 답변을 먼저 드리겠습니다.

PATCH의 경우 정의는 "리소스의 일부분을 수정한다" 로 할 수 있는데요 간단하게 예를 들면 다음과 같습니다

저희가 아직 DB에 대해서 배우지 않았고, ORM , Database Mapper을 배우지 않았지만 다음과 같은 이유가 있습니다.

  "id" : 1,

  "user_name" : "홍길동",

  "age" : 10

}

을 수정하기 위해서 PATCH 로 age = 20 으로 변경하기 위해서 다음을 보낸다고 볼 수 있습니다.

{

  "id" : 1,

  "age" : 20

}

그런데 저희가 ORM을 쓴다거나 요청 mapping에서 DTO라는 객체를 받게 되면, user_name에 해당되는 field가 null로 적용이 됩니다. 이는 kotlin, java등 여러 언어에서 parsing할때 나오는 현상입니다.

그리고 우리는 이를 다시 db에 적용하기 위해서 entity로 변환하는 과정에서 userName이라는 변수가 기존에 "홍길동"이 유지되는게 아닌 실제 객체의 형태는 아래와 같이 될수가 있습니다.

class User {

  id = 1

  age = 20

  userName = null

}

이렇게 되는 경우, 실제로 저장이 될때, age는 20 으로 변경이 될 수 있지만 userName이 같이 변환이 되는 불상사가 일어날 수 있습니다. 이는 실제로 코딩을 할때 실수하면 크리티컬한 이슈로 발생할수 있기 때문에 이보다는

GET을 통해서 정보를 받아오고 PUT으로 정보를 수정함에 있어서 GET에서 받은 부분 중 원본+수정본을 같이 보냄으로써 코드의 유연함, 어떠한 field의 수정이 일어났는지 굳이 서버에서 관리를 하지 않을수 있기에 굳이 PATCH보다는 PUT을 사용한다고 할 수 있습니다.

2. GET의 RequestBody

네 말씀해주신것처럼 불가능이 아닙니다. optional입니다.

다만 여기에는 몇가지 기본 표준이 존재 합니다.

POST방식의 RequsetBody는 validation을 합니다. 즉 요청에 대해서 검증을 하는데요

기본적으로 GET방식의 파라미터는 "검증하지 않는다" 가 표준입니다. 즉 요청이 들어오는 값에 대해서 검증을 하지 않기 때문에 만일 굳이 GET에 RequestBody를 쓴다고 한다면 해당 요청값을 검증을 하지 않는게 표준에 가깝습니다.

보통 대부분 RequestBody에 대해서는 Validation을 진행하게 되는데요 그렇다보니 이는 그 순간 GET의 정의와 멀어지기 때문에 Optional하게 사용할 수는 있지만 권장하지 않습니다. 이는 혼란을 야기할 수 있기 때문입니다.

그런데 Optional이 된 이유가 있습니다. 실무에서는 모든게 아름답게 표준에 맞춰서 진행되지 않습니다. GET/POST만 쓰는 곳도 존재 합니다. 그렇기 때문에 상황에 맞춰서 사용할 수 있도록 Optional이 되어 있고,

이는 "규약"이 아닌 "표준"이라고 표시하는 이유이기도 합니다. 반드시 지켜야 하는 부분은 아니지만 다같이 약속을 지키자 라는 정도로 생각하시면 될듯 합니다.

도움이 되셨을까요~?

5

Steve (예상국)님의 프로필 이미지
Steve (예상국)
지식공유자

감사 합니다.

한가지 예를 들자면, 금융권(핀테크)에서 REST를 지키자면 GET으로 조회를 해야 합니다.

그런데 여기서 이제 개인정보 라는 부분에서 URL이 노출되는 부분에 개인정보를 담을 수 없는일이 발생 합니다.

물론 POST도 실제 패킷을 열어보면 볼 수 있지만, 여기서의 문제점은 Nginx라던지 서버로그에 request url에 사용자의 정보가 

남게 됩니다. 

이러한 부분을 실제로는 마스킹 처리, 또는 암호화 처리를 해서 남겨야 하는데, 납품되는 장비라던지, 다양한 케이스가 발생하게 됩니다. 이러한 이유로 GET을 사용하지 못 하고 URL 로그에 남지 않도록 POST를 처리 하는 경우도 발생합니다 ^^

그럼 도움이 되셨기를 바랍니다~ 

4

Steve (예상국)님의 프로필 이미지
Steve (예상국)
지식공유자

Get Parameter의 검증에 대한 내용은 RFC 표준 문서등 HTTP 에 대해서 검색을 해보면 여러가지 자료들이 있고, 표준안도 나와 있습니다. 

그런데 찾아보시면 실제로 어떠한 서버는 Get의 RequestBody 요청 자체에 대해서 잘못된 요청으로 처리 하기도 하고, 또 어떤 서버들은 처리를 해주기도 합니다. 

이전에는 안된다. 라고 하기도 하였지만 이는 결국 상황에 따라서 다르게 사용할 수 있음으로 Optional로 변경이 되었습니다. 
(여기에 대한 정확한 역사적 문서는 찾기가 어렵네요)

MDN 등 여러곳에서 다르게 검색이 되지만, 이는 간단하게 생각을 해볼 수 있습니다.

GET에서 RequestBody를 사용한다면 사실상 POST/PUT/PATCH/DELETE 등 다양한 Method가 필요가 없습니다. 실제로 GET하나만으로도 모든것을 처리할 수 있습니다.

그럼에도 불구하고 HTTP Method를 구분해서 사용하는 이유는 그 역할을 나누기 위함 입니다.

해당 API의 GET, POST, PUT, DELETE 메소드만 보더라도, 

"아 이거는 생성이구나"

"아 이거는 조회용이구나"

"이거는 삭제할때 쓰는구나"

라는게 사용자 입장에서는 떠오를 수 있습니다. 그런데 GET에 아무런 이유없이 RequestBody를 해서 개발을 해둔다면 사용하는 Client입장에서는  음??? 왜지? 라는 반응이 나올 수 밖에 없습니다. "즉 일반적이지 않다" 라는 부분이 발생합니다.

REST API는 서로의 최소한의 약속 정도로 봐주시면 될듯 하며, 강의에서 말씀드린 URL 규칙, REST들은 실제 실무에서는 환경, 상황, 보안 등 여러가지 상황으로 인해서 REST 하지 않을 수 있습니다. 

이런 경우 반드시 별도의 Spec문서를 제공하는게 좋으면 이를 이용하는 개발자도 해당 문서를 읽어야 하는 추가적인 상황이 발생합니다.

안타깝게도, 현업에서는 이러한 일이 매우 많이 존재 하고 있고, 그래도 앞으로는 모두가 REST의 표준을 잘 맞춰서 개발해 나간다면 "이런 부분들이 언젠가는 사라지지 않지 않을까" 라는 생각을 하면서 강의를 진행하게 되었습니다.

0

김선동님의 프로필 이미지
김선동
질문자

친절한 답변 감사합니다.

네 아무래도 저는 현업 개발자가 아니고 강사님만큼 다양한 상황을 접해보지 않아서 많은 상황을 고려해보지 못하는 것 같아요.

검증관련된 내용을 직접 찾아보았는데, 관련된 내용은 찾지 못하고, 
"GET의 Payload는 의미를 담고 있지 않으니, 결과에 영향을 미쳐선 안된다." 는 의견을 보긴 했네요.

MDN에서도 강사님과 같이 Request Body는 No로 표시해뒀네요.

RESTful에 대해서도 공부를 해봤었는데 사실 지키기엔 너무 어려운 요소들이 많다고 생각합니다.
좋은 마음으로 강의를 해주셔서 감사합니다.

사실 팀프로젝트를 해본 입장으로는 Spec문서를 무조건 정의하는게 좋다고 생각했는데, 정말 RESTful하다면 그 마저도 필요없긴 하겠네요. 좋은 의견 잘 보았습니다!

0

김선동님의 프로필 이미지
김선동
질문자

결국 PATCH가 가질 수 있는 불안정성 때문에 실무에서는 사용을 꺼리는 것이군요.

2번에서 궁금한점이 GET Parameter를 검증하지 않는다가 표준이라는 내용은 어느곳에서 알 수 있을까요?

일반적으로 저도 GET을 사용할 때 따로 검증을 하진 않았던 것 같은데, 표준이 어디에 정의되어 있는지 궁금합니다.

강의에서 이런 내용이 포함되어 있었다면 더 좋았을 것 같습니다.

강의 잘보고 있습니다. 답변 감사합니다~