🌵 개요
http 메서드란,
클라이언트와 서버 사이에서 이루어지는 리퀘스트(request, 요청) 및 리스폰스(response, 응답) 데이터를 전송하는 방식으로,
서버가 수행해야 할 동작을 지정하여 리퀘스트를 보내는 방법입니다.
- Inpa Dev
리퀘스트는 헤드(head)와 바디(body)로 이루어져 있으며,
서버는 헤드 속에 들어있는 헤더(header)에 적힌 메서드의 종류를 보고 해당 리퀘스트가 어떤 동작을 원하는 리퀘스트인지 판단합니다.
http 메서드의 종류에는 총 9가지가 존재합니다.
- 주요 메서드
- GET: 기존의 데이터를 조회하는 리퀘스트
- POST: 새로운 데이터를 추가하는 리퀘스트
- PUT: 기존의 데이터에 새로운 데이터를 덮어씀으로써 수정하는 리퀘스트
- DELETE: 기존의 데이터를 삭제하는 리퀘스트
- PATCH: 기존 데이터의 일부를 새로운 데이터로 수정하는 리퀘스트
- 기타 메서드
- HEAD: 기존 데이터에서 바디를 제외한 헤드 부분만 조회하는 리퀘스트
- OPTION: 서버에게 지원되는 http 메서드나 헤더 등에 대한 정보를 요청하는 리퀘스트
- CONNECT: 클라이언트와 서버 간에 TCP/IP 터널을 설정하는 리퀘스트
- TRACE: 클라이언트가 보낸 리퀘스트 그대로를 서버에게 되돌려 받는 리퀘스트
주요 메서드 5가지와 + 기타 메서드 4가지를 예시 코드 및 JSON 파일과 함께 알아보겠습니다.
❗️예시로 작성한 결과 속 JSON 파일들은 글에서 작성된 메서드의 순서에 따라 모습이 변하니(이전 메서드의 결과가 반영된 파일) 글의 순서대로 보시는 것을 추천드립니다:)
🌵 GET
서버에 있는 리소스를 요청합니다.
리퀘스트의 헤더에 특정 메서드를 명시하지 않으면 기본값(default)으로 GET 메서드가 수행됩니다.
예를 들어, 사용자 데이터를 조회하는 코드는 다음과 같습니다.
fetch('https://api.example.com/users')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
예시 JSON 파일입니다.
[
{
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Smith",
"email": "jane.smith@example.com"
}
]
🌵 POST
서버에 새로운 리소스를 추가합니다.
예를 들어, 새로운 사용자를 추가하는 코드는 다음과 같습니다.
fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Emma Oh',
email: 'emma.oh@example.com'
})
})
.then(response => response.json())
.then(data => console.log('User created:', data))
.catch(error => console.error('Error:', error));
마지막에 새로운 사용자가 추가된 것을 볼 수 있습니다.
[
{
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Smith",
"email": "jane.smith@example.com"
}
{
"id": 3,
"name": 'Emma Oh',
"email": 'emma.oh@example.com'
}
]
🌵 PUT
사용자가 지정한 특정 리소스 전체를 새로운 리소스로 교체합니다.
만약 지정한 리소스가 존재하지 않을 경우 새롭게 생성합니다.
예를 들어, 기존 사용자의 정보를 수정하는 코드는 다음과 같습니다.
fetch('https://api.example.com/users/1', { // id=1인 객체를 특정해줌
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Harry Potter',
email: 'harry.potter@example.com'
})
})
.then(response => response.json())
.then(data => console.log('User updated:', data))
.catch(error => console.error('Error:', error));
id=1인 사용자 객체의 프로퍼티가 수정된 것을 볼 수 있습니다.
[
{
"id": 1,
"name": "Harry Potter",
"email": "harry.potter@example.com"
},
{
"id": 2,
"name": "Jane Smith",
"email": "jane.smith@example.com"
}
{
"id": 3,
"name": 'Emma Oh',
"email": 'emma.oh@example.com'
}
]
만약 위와 같은 코드에서 email 프로퍼티만 명시했다면
fetch('https://api.example.com/users/1', { // id=1인 객체를 특정해줌
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Harry Potter',
})
})
.then(response => response.json())
.then(data => console.log('User updated:', data))
.catch(error => console.error('Error:', error));
아래의 결과처럼 새로운 데이터가 덮어씌워져 name 프로퍼티는 사라지게 됩니다.
[
{
"id": 1,
"email": "harry.potter@example.com"
},
... 생략 ...
]
따라서 기존 리소스를 유지하면서 특정 프로퍼티만 수정하고 싶다면, 나머지 프로퍼티들도 함께 작성해주어야 합니다.
참고로 id 프로퍼티를 바디에 따로 적어주지 않았는데 사라지지 않은 이유는 객체의 id 필드를 보존하도록 설계된 API를 사용한다고 가정했기 때문입니다. 이는 API를 구현하는 방식에 따라 다르지만, id 필드를 포함하지 않아도 기존 리소스의 id가 보존되는 것이 일반적인 관례입니다.
🌵 DELETE
사용자가 지정한 특정 리소스를 삭제합니다.
예를 들어, 기존 사용자의 정보를 삭제하는 코드는 다음과 같습니다.
fetch('https://api.example.com/users/1', {
method: 'DELETE'
})
.then(response => response.json())
.then(data => console.log('User deleted:', data))
.catch(error => console.error('Error:', error));
id=1인 사용자 객체가 삭제된 것을 볼 수 있습니다.
[
{
"id": 2,
"name": "Jane Smith",
"email": "jane.smith@example.com"
}
{
"id": 3,
"name": 'Emma Oh',
"email": 'emma.oh@example.com'
}
]
🌵 PATCH
사용자가 지정한 특정 리소스의 일부를 새로운 리소스로 교체합니다.
기존 데이터 전체를 새 데이터로 덮어쓰는 대신 기존의 데이터 중 새로운 데이터와 형식이 일치하는 데이터만 수정합니다.
예를 들어, 기존 사용자의 email 정보만 수정하는 코드는 다음과 같습니다.
fetch('https://api.example.com/users/3', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: 'emma.oh.new@example.com'
})
})
.then(response => response.json())
.then(data => console.log('User partially updated:', data))
.catch(error => console.error('Error:', error));
id=3인 사용자 객체의 email 프로퍼티만 수정되고, 다른 프로퍼티들은 동일한 것을 볼 수 있습니다.
[
{
"id": 2,
"name": "Jane Smith",
"email": "jane.smith@example.com"
}
{
"id": 3,
"name": 'Emma Oh',
"email": 'emma.oh.new@example.com'
}
]
🌵 기타 메서드
HEAD
GET과 마찬가지로 서버에 있는 리소스를 요청하지만, 리소스의 헤더 정보만 가져오고 바디(리스폰스 본문)는 반환하지 않습니다.
주로 리소스의 메타 데이터를 확인하는 용도로 사용됩니다.
예를 들어, 사용자 목록의 헤더 정보를 가져오는 코드는 다음과 같습니다.
fetch('https://api.example.com/users', {
method: 'HEAD'
})
.then(response => {
console.log('Headers:', response.headers);
console.log('Status:', response.status);
})
.catch(error => console.error('Error:', error));
OPTIONS
서버가 특정 url에 대해 지원하는 http 메서드를 확인하는 데 사용됩니다.
주로 CORS(Cross-Origin Resource Sharing, 교차 출처 리소스 공유) 리퀘스트에서 많이 사용됩니다.
예를 들어, 특정 경로에서 지원하는 http 메서드를 확인하는 코드는 다음과 같습니다.
fetch('https://api.example.com/users', {
method: 'OPTIONS'
})
.then(response => {
console.log('Allow methods:', response.headers.get('Allow'));
})
.catch(error => console.error('Error:', error));
CONNECT
클라이언트와 서버 사이의 터널링을 설정하는 데 사용됩니다. 주로 https를 통해 프록시 서버에 연결할 때 사용됩니다.
TRACE
리퀘스트가 서버에 도달하는 과정을 추적(trace)하기 위해 사용되며, 서버는 받은 리퀘스트 메시지를 그대로 반환합니다.
보통 디버깅의 목적으로 사용됩니다.
예를 들어, 특정 경로에 대해 TRACE 리퀘스트를 보내는 코드는 다음과 같습니다.
fetch('https://api.example.com/trace', {
method: 'TRACE'
})
.then(response => response.text())
.then(data => {
console.log('TRACE response:', data);
})
.catch(error => console.error('Error:', error));
🌵 멱등성(Idempotence)
멱등성이란 어떤 연산을 특정 대상에 여러 번 수행하여도 그 결과가 달라지지 않는 성질입니다.
동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니고, 서버의 상태 또한 동일하게 남을 때,
해당 http 메서드는 멱등성을 가졌다고 말합니다.
기본 메서드 | 기타 메서드 | |||||||||
종류 | GET | POST | PUT | DELETE | PATCH | HEAD | OPTIONS | CONNECT | TRACE | |
멱등성 | O | X | O | O | X | O | O | X | O |
멱등성의 중요성에 대한 자세한 내용은 다음 링크를 참고해주세요.
읽어주셔서 감사합니다:)