fetch API

이수정·2025년 8월 27일

JS_웹_풀스택

목록 보기
3/12

참고) Modern Javascript Deep Dive
864p) 45장 Promise

MDN: fetch API

fetch

fetch : XMLHttpRequest 객체와 비슷하게 HTTP 요청 전송 기능 제공하는 Client Side Web API(CSR)

  • Promise 객체를 사용하기에 비동기 처리를 위한 콜백 헬에서 자유로움
  • explore 제외한 모든 브라우저에서 제공
const promise = fetch(url [, options])
  • Http 응답을 나타내는 Response를 래핑한 Promise 리턴

Get

fetch ('url').then(response => console.log(response));

=> Promise 객체 리턴

Response.prototype.json()

fetch('url')
.then(response => response.json())
.then(json => console.log(json));

Response의 HTTP body를 json화

에러처리
url이 잘못되어 404 Not found가 발생해도 catch()가 실행되지 않는다. (=Response 객체 resolve)

  • 네트워크 장애에 의해 요청이 완료되지 못한 경우만 Promise reject
fetch('wrongURL')
.then(response => {
  if (!response.ok) throw new Error(response.statusText);
  return response.json();
})
.then(todo => console.log(todo))
.catch(err => console.error(err));

axios : 모든 HTTP 에러 reject하는 Promise 리턴 -> 후에 공부하기

<AI가 비유해준 fetch 시나리오>

주문하기 (fetch 호출)

fetch('/api/hamburger') 코드를 실행하면, 서버에 "햄버거 하나 주세요"라고 주문을 넣습니다.

서버는 즉시 햄버거를 주지 않습니다. 대신 "주문이 정상적으로 접수되었습니다"라는 의미의 '진동벨'(Promise)을 먼저 돌려줍니다.

진동벨 울리기 (Response 객체)

잠시 후 진동벨이 울립니다. 이제 카운터로 가면 음식을 받을 수 있는 상태가 된 것입니다.

이 '진동벨이 울린 상태'가 fetch의 첫 번째 then에 해당하며, 우리는 Response라는 객체를 받습니다. 이 객체에는 주문 성공 여부(response.status) 같은 정보가 있지만, 아직 햄버거(실제 데이터)는 손에 없습니다.

햄버거 포장 뜯기 (.json() 호출)

카운터에서 받은 햄버거의 포장을 뜯어서 먹을 준비를 해야 합니다.

response.json() 메서드를 호출하는 것이 이 과정에 해당합니다. 서버가 보낸 JSON 형식의 데이터를 자바스크립트 객체로 변환(파싱)하는 과정인데, 이 과정도 약간의 시간이 걸리는 또 다른 약속(Promise)입니다.

햄버거 먹기 (최종 데이터)

포장을 다 뜯고 드디어 햄버거를 손에 쥐었습니다.

두 번째 then에서 드디어 우리가 원했던 실제 데이터(자바스크립트 객체)를 사용할 수 있게 됩니다.

fetch 예시 코드

GET

async function getPosts() {
  try {
    // fetch는 기본적으로 GET 요청을 보냅니다.
    const response = await fetch('https://jsonplaceholder.typicode.com/posts');
    
    // 서버 응답을 JSON 객체로 변환합니다.
    const data = await response.json();
    
    console.log('GET 요청 성공:', data);
  } catch (error) {
    console.error('GET 요청 실패:', error);
  }
}

getPosts();

POST

async function createPost() {
  // 서버에 보낼 새로운 게시물 데이터
  const newPost = {
    title: '새로운 게시물',
    body: '내용입니다.',
    userId: 1
  };

  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
      // 1. 요청 메서드를 'POST'로 지정
      method: 'POST', 
      // 2. 요청 헤더에 보내는 데이터의 형식을 명시 (JSON)
      headers: {
        'Content-Type': 'application/json'
      },
      // 3. 자바스크립트 객체를 JSON 문자열로 변환하여 body에 담아 전송
      body: JSON.stringify(newPost)
    });

    const data = await response.json();
    console.log('POST 요청 성공:', data);
  } catch (error) {
    console.error('POST 요청 실패:', error);
  }
}

createPost();

Patch

: 기존 데이터의 일부만 수정 (전체 교체 시 PUT)

async function updatePostTitle() {
  // 수정할 데이터 (제목만 보냄)
  const updatedData = {
    title: '수정된 제목'
  };

  try {
    // URL에 수정할 데이터의 id(예: 1)를 포함시켜야 합니다.
    const response = await fetch('https://jsonplaceholder.typicode.com/posts/1', {
      method: 'PATCH',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(updatedData)
    });

    const data = await response.json();
    console.log('PATCH 요청 성공:', data);
  } catch (error) {
    console.error('PATCH 요청 실패:', error);
  }
}

updatePostTitle();

DELETE

async function deletePost() {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts/1', {
      method: 'DELETE'
    });

    // DELETE 요청은 성공 시 보통 빈 응답을 반환하므로, 상태 코드로 성공 여부를 확인합니다.
    if (response.ok) { // response.ok는 상태 코드가 200-299 범위에 있는지 확인
      console.log('DELETE 요청 성공: 게시물이 삭제되었습니다.');
    } else {
      console.log('DELETE 요청 실패:', response.status);
    }
  } catch (error) {
    console.error('DELETE 요청 실패:', error);
  }
}

deletePost();

0개의 댓글