본문 바로가기
오늘은 뭘 배울까?/etc

Get과 Post의 차이가 무엇인가요?

by Kim Juhwan 2022. 6. 21.

1. 요약
2. Get
   2-1. 개념
   2-2. 특징
3. Post
   3-1. 개념
   3-2. 특징
4. 멱등성
   4-1. 개념
5. 알아두면 재밌는 이야기
   5-1. Delete로 마지막 데이터를 삭제하면 안 된다고?
   5-2. Google Accelerator 사건

 

 

 


 

 

1. 요약

xxx 지원자님, Get과 Post의 차이에 대해서 설명해보시겠어요?

우선 기본적으로 Get은 리소스를 요청하는 메서드, Post는 리소스를 생성하는 메서드입니다.
둘의 차이는 여러 가지가 있는데 몇 가지만 말씀드리자면
Get은 멱등성을 가지기 때문에 캐시가 가능하고
Post는 멱등성을 가지지 않으며 캐시가 불가능합니다.
또 Get은 데이터를 Url에 담아 보내며 데이터 길이에 제한이 있고
Post는 body에 담아 보내며 길이 제한이 없습니다.

 

+) 답변이 길어질 것 같아 잘랐지만

보안 측면이나 히스토리, 전송량의 차이에 대한 답변도 준비해두자

 

2. Get

2-1. Get의 개념

Get은 클라이언트가 서버에게 리소스를 요청할 때 사용하는 메서드이다.

쉽게 생각해보자면, 우리가 학교 공지사항 페이지로 들어갔다고 하자.

그러면 브라우저가 "야, 서버야! 공지사항 목록 좀 줘봐라"라고 요청을 하게 되는데

그때 사용하는 방식이 Get 방식인 것이다.

 

2-2. Get의 특징

  • Get은 리소스를 요청할 때 사용한다.

[목차 2-1]에서 말했던 내용과 동일하다.

삭제나 수정과 같은 작업이 아닌 요청할 때 사용한다.

ex) 공지사항 목록 불러오기(= 공지사항 요청), 검색 하기(= 검색 결과 요청) 등

 

  • Get은 캐시가 가능하다.

Get은 불필요한 요청을 막기 위해 캐시가 가능하다.

예를 들어서 지금 스마트폰의 데이터를 끄고 카카오톡 채팅방에 들어가 보자.

친구가 보낸 사진을 문제없이 확인할 수 있을 것이다.

인터넷이 안 되는 데 어떻게 친구가 보낸 사진을 확인할 수 있을까? 나는 저장한 적도 없는데?

바로 캐싱을 했기 때문이다.

 

채팅방을 들어갈 때마다 매번 서버로부터 사진 리소스를 받아온다고 생각해보자.

서버 입장에서도 부담이고 사용자 입장에서도 데이터가 쭉쭉 소모될 테니 손해이다.

그래서 사용하는 것이 캐싱인데, 이에 대해서는 다음 포스팅에서 자세히 다룰 예정이다.

일단 이번 포스팅에서는 Get은 캐시가 가능하다! 만 알고 넘어가자.

 

  • Get은 보안이 취약하다.
www.example.com/login?username=김신입&password=1234

Get은 위와 같은 구조의 Url을 가진다.

주소 뒤에 '?'가 붙고 그 뒤에 쿼리 스트링이 붙는 구조이다.

 

www.example.com/login?username=김신입&password=1234

문제는 저놈의 쿼리 스트링이다.

Get 방식으로 사용자의 정보가 담아 요청하면 Url에 그대로 다 노출되기 때문에 보안적인 측면에서 문제가 된다.

또한 서버 로그에도 그대로 남게 된다.

비밀번호 같은 민감한 정보가 로그에 그대로 찍혀있다고 생각해보면... 😱

 

  • Get은 길이 제한이 있다.

Get은 Url에 이것저것 정보를 담아서 보내기 때문에 길이가 길어질 수 있는데

만약 그 길이가 너무 길어지면 Request URI Too Large(414 에러)가 발생한다.

그 길이의 정도는 브라우저마다 다르며 일반적인 상식 내에서는(?) 길이를 넘을 일은 없을 듯하다.

bitmap 정보를 뭐 어떻게든 Url에 꾹꾹 눌러 담아서 보내려고 하지 않는 이상... 길이를 넘을 일은 없을 듯 (개인 의견)

 

  • Get은 브라우저 히스토리에 남는다.

이 특징은 보안에 취약하다는 특징과 연관성이 있다.

Get 요청을 할 때 민감한 정보를 담아서 요청한다고 생각해보자.

그럼 브라우저 히스토리에 민감한 정보가 잔뜩 남아 있을 것이다.

 

3. Post

3-1. Post의 개념

Post는 리소스를 생성할 때 사용하는 메서드이다.

ex) 회원 가입(= 계정 생성), 글쓰기(=글 생성)

 

3-2. Post의 특징

  • Post는 리소스를 생성할 때 사용한다.

[목차 3-1]에서 말한 것처럼 리소스를 생성할 때 사용한다.

기본적으로는 그렇다. 하지만 때론 다른 용도로 쓰이기도 한다.

예를 들어 로그인 API를 만든다고 했을 때, Get을 사용해야 할까 Post를 사용해야 할까?

로그인을 하려면 아이디와 비밀번호를 쿼리로 넘겨야 하는데 이렇게 하면 Url에 개인정보가 그대로 노출된다.

🤔 흠... 그러면 Post를 써야 하나?

근데 Post는 리소스를 생성할 때 사용하는 것. 즉, 서버가 가지고 있는 데이터에 변화를 줄 때 사용한다.

🤔 아니 그러면 대체 뭘 써야 하지...?

이 경우에는 Post가 권장된다.

 

url에 정보를 노출하는 건 정말 좋지 않은 아이디어이기도 하고

때로는 메서드가 다른 용도로도 쓰일 수 있기 때문이다.

하지만 기본적으로는 리소스를 생성할 때 쓴다는 것을 기억해두자.

 

  • Post는 캐시가 되지 않는다.

[목차 2-2]에서 설명했지만

캐시는 예를 들어 반복적인 요청을 할 때 비용/속도 면에서 이점을 가져오기 위해 사용하는 것이다.

그러므로 리소스를 생성할 때 사용하는 Post는 캐시가 되지 않는다.

 

  • Post는 body에 데이터를 담아 보낸다.
www.example.com/login?username=김신입&password=1234

Get의 경우는 위 예시처럼 Url에 쿼리가 들어가기 때문에 값이 그대로 노출된다고 했다.

하지만 Post의 경우는 값이 숨겨져서(=body에 담아서) 보내지기 때문에 값이 노출되지 않는다.

 

단, 그렇다고 해서 보안이 강하다고 말할 수는 없다.

Get처럼 대놓고 보여주지 않을 뿐, 맘만 먹으면 얼마든지 까 볼 수 있다.

마치 연애편지를 펼쳐진 상태로 책상 위에 올려놓느냐

아니면 봉투에 담아서 책상위에 올려놓느냐 차이일 뿐

누구든 맘만 먹으면 편지를 읽을 수 있는 것과 같다.

(뭐라구요? 그런 거 받아본 적 없다구요? 아앗...)

 

  • 데이터 길이의 제한, 전송량의 제한이 없다.

전송량의 제한이 없기 때문에 대용량의 데이터를 전달하기 위해서는 Post가 적절하다.

 

4. 멱등성

4-1. 개념

수학이나 전사학에서의 정의: 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질

프로그래밍 관점에서의 정의: 작업을 1번 수행하든 N번 수행하든 효과가 같은 성질

 

갑자기 이 이야기를 하는 이유는 Get과 Post의 차이 중 하나가 바로 멱등성이기 때문이다.

예제를 통해 멱등성을 좀 더 자세히 알아보자.

 

  • Get

Get 요청은 리소스를 요청하는 효과로 1번을 실행하든 10번을 실행하든 항상 같은 효과를 기대할 수 있다.

즉, 멱등성을 가진다고 말할 수 있다.

 

  • Post

Post 요청은 리소스를 생성하는 효과로 1번 실행할 때랑 10번 실행할때 다른 효과가 나타난다.

예를 들어 냉장고 테이블에 식재료를 넣는 API가 있다고 치자.

사과를 Post 요청으로 1번 날리면 1개의 사과가 들어갈 것이고

10번 날리면 10개의 사과가 들어갈 것이다.

효과가 다르다. -> 멱등성을 가지지 않는다.

 

  • Put

Put은 리소스를 수정하는 효과로 1번을 실행하든 10번을 실행하든 항상 같은 효과를 기대할 수 있다.

유저의 닉네임을 `Faker`로 수정하는 Put 요청을 10번 다다닥 날린다고 해도

이건 Put 요청을 1번 날리는 것과 동일한 효과를 보여줄 것이다.

(결국에는 Faker로 수정된다는 사실은 동일하니까)

즉, 멱등성을 가진다.

 

  • Delete

Delete는 리소스를 삭제하는 효과로 1번을 실행하든 10번을 실행하든 항상 같은 효과를 기대할 수 있다.

유저 정보를 삭제하는 Delete 요청을 1번 날리든 10번 날리든

그 데이터가 존재하든 말든

유저 정보가 사라진다는 효과는 동일하다.

즉, 멱등성을 가진다.

 

결론적으로 Post만 멱등성을 가지지 않고 나머지는 다 멱등성을 가진다.

따라서 Get과 Post의 차이 중 하나는 멱등성을 가지는지의 유무라는 것이다.

 

5. 알아두면 재밌는 이야기

5-1. Delete로 마지막 데이터를 삭제하면 안 된다고?

멱등성은 몇 번을 실행하든 항상 같은 효과를 기대할 수 있어야 하는데

Delete를 이용해 목록의 마지막 데이터 삭제를 하면 멱등성을 어기는 것이 된다.

몇 번 실행하느냐에 따라 삭제되는 데이터가 달라지기 때문이다.

mozilla 홈페이지 - 멱등성 에서 이에 대해 짧게 다룬 글이 있으니 참고해보자.

 

5-2. Google Accelerator 사건

앞서 Get은 리소스를 요청한다, Delete는 리소스를 삭제한다와 같은 역할을 설명했지만

사실 Delete 메서드로 Get의 기능을 수행할 수도 있고

Post로 Delete 기능을 수행할 수도 있고 걍 원하면 아무 메서드나 가져다 쓸 수 있다.

다만 그냥 우리끼리의 약속인 것이다.

만약 이 약속을 지키지 않으면 어떤 일이 발생할까?

그래서 발생했던 사건이 그 유명한 Google Accelerator 사건이다.

 

구글에서 웹서핑 체감속도를 높이기 위한 목적으로 Accelerator라는 것을 발표했었다.

쉽게 말하면 이런 것이다.

내가 네이버 홈에 접속을 하면 Accelerator가 네이버 홈에서 이동할 수 있는 링크들(뉴스, 웹툰, 메일 등등..)을

미리 방문해서 이미지와 같은 것들을 미리 캐싱해두는 것이다.

이렇게 하면 사용자가 실제로 그 링크에 접속했을 때 캐싱된 데이터를 받아오니 체감속도가 향상될 것이다!

라는 의도에서 만들어진 게 Accelerator이다.

 

결론은? 망했다.

개발자들이 메서드들을 각 역할에 맞게 사용했으면 아무런 문제가 없었겠지만

이를 혼용해서 사용하는 개발자들이 있었기 때문이다.

예를 들어 메일을 삭제하는 API를 Delete가 아닌 Get으로 만들어버리니

Accelerator는 어? Get이네? 미리 조회해서 캐싱해야지~ 하고 링크를 클릭했다가

메일이 삭제되어버리는 대참사가 벌어진 것이다. 😱

 

 

 


💡 느낀 점

  • Delete로 마지막 데이터를 삭제하는 것이 멱등성을 어기는 것인지 이번에 처음 알았다. 맨날 클라이언트만 개발해서 몰랐는데 백엔드 친구들은 이런 거를 고려하면서 개발을 하는구나... 흥미로웠다.
  • 우리 학교가 홈페이지 리뉴얼 전에 공지사항 불러오는 메서드로 Post를 썼었다. 대체 왜 그랬을까..? 아무튼 생각보다 이걸 안 지키는 개발자들이 많은가 보다.
  • 이 질문을 면접에서 처음 받았을 때는 "난 안드로이드 개발자인데 왜 이걸 물어볼까?"라고 생각했는데 클라이언트 개발자도 알아야 하는 부분이 맞는 것 같다. 그저 받아서 쓰기만 하면 된다고 냅다 쓰지 말고 뭐가 다른지는 알고 써야겠다.

📘 참고한 자료


 

 

반응형

댓글