fetch() 메소드는 자바스크립트에서 제공되는 내장함수로 웹 브라우저의 'window'객체에 정의되어있다. 즉, Next.js에서 제공하는 메서드는 아니다. 평소 편리성에 의해 Axios만 사용하다보니 fetch API를 사용할 기회가 많이 없었지만 Next.js 13버전에서 데이터를 받을때 캐시 혹은 revalidate옵션을 fetch API와 함께 이용하므로 이참에 공식문서를 이해하기위해 예습삼아 MDN문서를 읽고 정리하는 글이다.
HTTP
HyperText Transfer Protocol (HTTP)를 사용하여 웹 서버에게 특정한 동작을 수행하도록 요청하는 메시지입니다. HTTP 요청은 클라이언트(예: 웹 브라우저)가 서버에게 정보를 요청하거나, 서버에 데이터를 전송하거나, 서버의 동작을 수행하도록 요청할 수 있습니다.
HTTP 요청은 일반적으로 클라이언트에서 서버로 데이터를 보낼 때 사용되며, 서버는 해당 요청을 수신하고 처리한 후에 클라이언트에게 응답을 보냅니다.
HTTP 요청은 주로 다음과 같은 구성 요소로 이루어집니다:
메서드(Method): 요청하는 동작의 종류를 나타냅니다. 일반적으로 사용되는 메서드에는 GET, POST, PUT, DELETE 등이 있습니다.경로(Path): 요청하는 리소스의 경로를 나타냅니다. 예를 들어, "/products"는 "products"라는 리소스에 대한 요청을 나타냅니다.헤더(Headers): 요청에 대한 추가 정보를 포함합니다. 예를 들어, 클라이언트가 어떤 유형의 데이터를 원하는지를 지정하는 "Accept" 헤더를 포함할 수 있습니다.본문(Body): 일부 요청은 데이터를 서버로 보내야 할 필요가 있을 때, 요청의 본문에 데이터를 포함시킬 수 있습니다. 일반적으로 POST나 PUT 메서드와 함께 사용됩니다.
fetch API란?
https://velog.io/@dev-redo/REST-API%EC%99%80-Fetch-api#1-get-%EB%B0%A9%EC%8B%9D
❶ fetch에 대해 알아보자!
✔ 소개
- 정의
- HTTP request 전송 기능을 제공하는 클라이언트 사이드 Web API
- 클라이언트 → 서버 : request
- 서버 → 클라이언트: response
- 라이브러리인 axios와 달리 브라우저에 내장된 함수
- 즉 1) 서버와의 통신을 통해 CRUD를 구현할 수 있게 하는, 2) 프라미스 지원 내장 함수
- HTTP request 전송 기능을 제공하는 클라이언트 사이드 Web API
- 사용법
- params
- 1번째 인자: HTTP 요청을 전달할 url
- 2번째 인자: 옵션 객체 (HTTP 요청 메서드, HTTP 요청 헤더, payload 등)
- return
- Response 객체:
HTTP 응답 상태(status), HTTP 응답 헤더(headers), HTTP 응답 전문(body) 등을 읽어올 수 있다. - Ex: Code
Resultfetch("https://jsonplaceholder.typicode.com/posts/1") .then((response) => console.log(response))
- Response.ok HTTP 응답 성공 여부를 나타내는 속성
- true = 200~299 상태코드 (응답 성공)
- false = not (응답 실패)
- Response.status HTTP 상태코드 = 서버로부터 리퀘스트 결과를 전달 즉 클라이언트가 서버를 향해 리퀘스트를 보낼 때 서버에서 그 결과가 어떻게 되었는지 알려주는 역할을 한다.
- 상태코드 클래스클래스설명
1XX Informational 리퀘스트를 받아들여 처리중 2XX Success 리퀘스트를 정상적으로 처리했음 3XX Redirection 리퀘스트를 완료하기 위해서 추가 동작 필요 4XX Client Error 서버는 리퀘스트 이해 불가능 5XX Server Err 서버는 리퀘스트 처리 실패
- 상태코드 클래스클래스설명
- Response.redirected 3XX 리스폰스와 연결되며, 리퀘스트가 정상적으로 처리를 종료하기 위해 브라우저 측에서 특별한 처리를 수행해야 함을 나타냄
- EX: 네이버 카페 일반회원이 “특정등급 회원” 게시판에 들어가려고 할 때 경고 페이지로 이동시키기
- Response.ok HTTP 응답 성공 여부를 나타내는 속성
- Response.prototype 메소드
- Response.prototype.json Response 객체에서 HTTP 응답 몸체(response.body)를 취득하여 역직렬화
- JSON 역직렬화: JSON.parse
: JSON.parse 메서드는 JSON 포맷의 문자열을 객체로 변환한다.
서버로부터 클라이언트에게 전송된 JSON 데이터는 문자열이다.
⇒ 객체로 사용하기 위해 JSON 포맷 문자열을 객체화! = “역직렬화”
EXconst todos = [ {id: 1, content: 'HTML', completed: false}, {id: 2, content: 'CSS', completed: true}, {id: 3, content: 'JS', completed: false} ] // 배열 todos를 JSON 포맷의 문자열로 변환 const json = JSON.stringify(todos); console.log(typeof(json), json); // string [{"id":1,"content":"HTML","completed":false},{"id":2,"content":"CSS","completed":true},{"id":3,"content":"JS","completed":false}] // JSON 포맷의 문자열을 배열로 변환한다. // 배열의 요소까지 객체로 변환된다. const parsed = JSON.parse(json); console.log(typeof parsed, parsed); /* object [ {id: 1, content: 'HTML', completed: false}, {id: 2, content: 'CSS', completed: true}, {id: 3, content: 'JS', completed: false} ] */
- JSON 역직렬화: JSON.parse
- Response.prototype.json Response 객체에서 HTTP 응답 몸체(response.body)를 취득하여 역직렬화
- Response 객체:
- HTTP 응답을 나타내는 Response 객체를 래핑한 Promise 객체 반환
- GET 요청 코드 수정: 역직렬화
- fetch("https://jsonplaceholder.typicode.com/posts/1") .then((response) => response.json()) .then((json) => console.log(json)) // {userId: 1, id: 1, title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', body: 'quia et suscipit\nsuscipit recusandae consequuntur …strum rerum est autem sunt rem eveniet architecto'}
- params
const promise = fetch(url [, options])
❷ 통신 규칙 “REST API” !
✔ 등장배경
개발자들이 너~무 제멋대로 통신해서 다른 개발자들이 이해하기 어려워!
GET이 있길래 당연히 특정 데이터를 받아오는 건줄 알았는데, 데이터를 삭제하네?
우리 서로 알아먹을 수 있게끔 통신 규칙을 세워보자!
✔ 정의
- HTTP의 통일성을 위해 만들어진 아키텍쳐
- HTTP 프로토콜을 의도에 맞게 디자인하도록 유도하는 권고사항
- REST API만으로도 HTTP 요청의 내용을 이해할 수 있다
✔ 구성
- REST API의 3가지 요소
- 자원(Resource)
- 행위(Verb)
- 표현(representations)구성요소내용표현 방법
자원 자원 URI 행위 자원에 대한 행위 HTTP 요청 메서드 표현 자원에 대한 행위의 구체적 내용 payload
✔ 설계원칙
➀ URI는 리소스를 표현해야 한다.
- 리소스를 표현하기 위해 명사 사용! 이름에 행위에 대한 표현(동사) 금지!
- EX:
// bad GET /getTodos/1 GET /todos/show/1 // good GET /todos/1
➁ 리소스에 대한 행위는 HTTP 요청 메소드로 표현한다.
- HTTP 요청메소드
- 정의: 클라이언트가 서버에게 request 종류와 목적(리소스에 대한 행위)를 알리는 방법
- GET, POST, PUT, PATCH, DELETEHTTP 요청 메서드종류목적페이로드
GET index/retrieve 모든/특정 리소스 취득 X POST create 리소스 생성 O PUT replace 리소스의 전체 교체 O PATCH modify 리소스의 일부 수정 O DELETE delete 모든/특정 리소스 삭제 X - 모든 / 특정 리소스 ?
- 모든: todos
- 특정: todos/1
- 리소스에 대한 행위는 HTTP 요청 메서드를 통해 표현하며 URI에 표현하지 않는다.
- EX:
- // bad GET /todos/delete/1 // good DELETE /todos/1
❸ Fetch api 실습
그럼 이제 fetch 함수를 통해 HTTP 요청을 전송해보자!
우리는 가상 REST API를 제공해주는 JSONPlaceholder 웹 사이트를 이용해서 실습을 할 것이다.
[1] GET 방식
GET 방식에서는 보낼 데이터가 없기 때문에, headers와 body 옵션이 필요가 없다.
// GET 요청
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((response) => response.json())
.then((data) => console.log(data));
// HTTP response.body 역직렬화
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit↵suscipit recusandae consequuntur …strum rerum est autem sunt rem eveniet architecto"
}
[2] POST 방식
- fetch(url, {method, headers, body})
- method = HTTP 요청 메서드
- headers = HTTP 헤더
- “Content-Type”
- 정의: HTTP 메시지에 담겨 보내는 데이터의 형식을 알려주는 헤더
- EX:
"Content-Type": "application/json" = JSON 형식으로 데이터를 보내줘
- “Content-Type”
- body = body안에 payload 작성
- payload
- 페이로드(payload)는 전송되는 데이터를 의미한다.
- 데이터를 전송할 때, 헤더와 메타 데이터, 에러 체크 비트 등과 같은 다양한 요소들을 함께 보내어, 데이터 전송의 효율과 안정성을 높이게 된다.
- 이 때, 보내고자 하는 데이터 자체를 의미하는 것이 바로 페이로드 그 이외의 데이터들은 전부 통신을 용이하게 해주는 부차적인 정보인 프로토콜 오버헤드
- payload
- EX:
이중 data가 payload로,{ "status" : "OK" "from": "localhost", "to": "https://hanamon.kr/users/1", "method": "GET", "data":{ "username" : "하나몬" } }
클라이언트도 마찬가지로 서버에게 request할 때 body 안에 넣는 데이터 객체를 뜻한다. - response 데이터

- status code: 201 created
- POST가 성공적으로 이루어져 생성이 되었다는 의미이다.
- 생성된 리소스는 response 메시지의 본문(body)에 동봉된다.
코드
fetch("https://jsonplaceholder.typicode.com/posts", {
// method 옵션 POST 지정
method: "POST",
// JSON 포맷 (JSON으로 보낼거야~)
headers: {
"Content-Type": "application/json",
},
// body안에 payload 넣기
body: JSON.stringify({
title: "Test",
body: "I am testing!",
userId: 1,
}),
})
.then((response) => response.json())
.then((data) => console.log(data));
{title: "Test", body: "I am testing!", userId: 1, id: 101}
async / await
async function run() {
const res = await fetch(`https://jsonplaceholder.typicode.com/posts`, {
method: 'POST',
body: JSON.stringify({
title: "HI",
body: "NICE TO MEET YOU",
userId: 1,
}),
headers: {
'Content-type': 'application/json; charset=UTF-8',
},
}
)
const payload = await res.json();
console.log(payload);
}
[3] PATCH 방식
fetch("https://jsonplaceholder.typicode.com/posts/1", {
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "프론트공부",
body: "프론트를 사랑하는 프론트공부"
}),
})
.then((response) => response.json())
.then((data) => console.log(data));
{userId: 1, id: 1, title: '프론트공부', body: '프론트를 사랑하는 프론트공부'}
[4] PUT 방식
fetch("https://jsonplaceholder.typicode.com/posts/1", {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Test",
userId: 1,
}),
})
.then((response) => response.json())
.then((data) => console.log(data));
{title: 'Test', userId: 1, id: 1}
[5] DELETE 방식
DELETE 방식에서는 보낼 데이터가 없기 때문에, headers와 body 옵션이 필요가 없다.
fetch("https://jsonplaceholder.typicode.com/posts/1", {
method: "DELETE",
})
.then((response) => response.json())
.then((data) => console.log(data));
// {}
[+] request 객체를 만들어서 fetch하자!
매번 fetch 메소드를 작성하면 번거로우니, 객체로 저장해서 간편하게 써보자!
request 객체
const request = {
get(url) {
return fetch(url);
},
post(url, payload) {
return fetch(url, {
method: 'POST',
headers: { 'content-Type': 'application/json' },
body: JSON.stringify(payload)
});
},
patch(url, payload) {
return fetch(url, {
method: 'PATCH',
headers: { 'content-Type': 'application/json' },
body: JSON.stringify(payload)
});
},
put(url, payload) {
return fetch(url, {
method: 'PUT',
headers: { 'content-Type': 'application/json' },
body: JSON.stringify(payload)
});
},
delete(url) {
return fetch(url, {method: 'DELETE'});
}
};
POST 예시
request.post('https://jsonplaceholder.typicode.com/posts', {
id: 1,
userId:1,
title: "프공",
body: "프론트공부"
})
.then(res => res.json())
.then(data => console.log(data));
DELETE 예시
request.delete("https://jsonplaceholder.typicode.com/posts/1")
.then((response) => response.json())
.then((data) => console.log(data));
(ref)
'Next.js(ver.13)' 카테고리의 다른 글
Data Fetching_Caching (0) | 2023.07.14 |
---|---|
Data Fetching_Fetching (0) | 2023.07.10 |
Data Fetching_Overview (0) | 2023.06.27 |
Rendering (0) | 2023.06.27 |