본문 바로가기
프로그래밍

fetch API 의 응답 분석 :: response, data 의 정체는?

by 로맨틱스터디 2025. 10. 8.
728x90
반응형
fetch('https://example.com/users')  // API 호출
  .then(response => response.json())
  .then(data => console.log(data));

 

1️⃣ fetch() 도 API인가?

맞아요! ✅

  • fetch() 자체가 브라우저(혹은 JS 환경)가 제공하는 Web API
  • 내부 구현(서버와 통신하는 로직)은 우리가 볼 수 없음
  • 우리는 기능만 호출해서 사용
  • 즉, API = 이미 만들어진 기능을 호출해서 쓰는 인터페이스라는 정의와 정확히 맞음

2️⃣ fetch('https://example.com/users') 반환값

fetch('https://example.com/users')
  • fetch()는 Promise 객체를 반환
  • Promise는 비동기 처리 완료 후 응답(response) 객체를 전달
  • 따라서 첫 번째 .then(response => ...)에서 response라는 이름으로 받을 수 있음

중요한 점: response라는 변수 이름사용자가 정의한 이름일 뿐, 규칙에 정해진 이름은 아님

fetch('url')
  .then(r => console.log(r)); // r로 받아도 똑같이 response 객체

3️⃣ response.json() 메서드

  • response 객체는 HTTP 응답 전체를 포함
    • 상태 코드(status), 헤더(headers), 본문(body) 등
  • response.json() = 응답 body를 JSON으로 파싱
    • 서버가 JSON 형태로 응답했을 때 → JS 객체로 변환해줌
    • 이 메서드도 Promise를 반환 → .then(data => ...)에서 실제 데이터 접근 가능
 
response.json().then(data => console.log(data));
  • 여기서 data도 사용자가 정의한 변수 이름
    • response.json().then(result => ...) 해도 동일하게 작동

4️⃣ 변수 이름 규칙

변수 정의 여부 설명
response 사용자가 정의 가능 fetch()가 반환한 HTTP 응답 객체
data 사용자가 정의 가능 response.json()으로 변환 JS 객체
  • 즉, response, data는 이름일 뿐
  • 중요한 건 첫 .then()에서 fetch Promise가 response 객체를 전달하고, 그 객체의 .json() 메서드가 또 Promise로 실제 데이터 반환이라는 흐름

5️⃣ 요약 흐름

 
fetch(url) 
 └─> Promise (response 객체) 
       └─> response.json() 
             └─> Promise (JS 객체로 변환된 데이터)
  • 변수 이름은 자유롭게 지정 가능
  • 내부 로직은 볼 수 없고, 제공되는 기능만 사용

💡 비유

  • fetch() = 택배 시스템
  • response = 택배 박스(주소, 송장, 내용물 포함)
  • response.json() = 박스 안에서 실제 물건(JSON 데이터) 꺼내기
  • data = 꺼낸 물건을 담는 바구니(사용자가 이름 정함)

728x90

1️⃣ 서버 응답과 json() 메서드

  • 서버가 보내는 데이터(body)는 JSON 문자열 형태로 옵니다.
'{"name":"Alice","age":23}'
  • 이 상태는 문자열일 뿐이어서 JS 코드에서 바로 속성 접근 불가:
console.log(response.body.name); // ❌ undefined

 

1️⃣ response.json()의 진짜 의미

  • **response.json()**은 서버에서 온 JSON 문자열을  -> JS 객체로 변환하는 메서드예요.
  • 즉, **“JSON으로 처리하겠다” = JSON 문자열을 -> JS 객체로 해석하겠다”**라는 의미입니다.

오해하기 쉬운 점

  • .json()을 보면 “JSON으로 만들겠다(JSON.stringify처럼)”라고 생각할 수 있는데,
  • 실제로는 JSON 문자열 → JS 객체로 변환이 맞아요.

2️⃣ 내부 동작 예시

 
// 서버가 보낸 JSON 문자열
const jsonString = '{"name":"Alice","age":23}';

// response.json() 내부적으로 실행되는 것과 동일
const jsObj = JSON.parse(jsonString);

console.log(jsObj.name); // Alice
  • 서버 응답(JSON 문자열) → .json() → JS 객체
  • JSON 문자열 그대로 두면 속성 접근 불가, JS 객체로 만들어야 코드에서 사용 가능

3️⃣ 한 줄 요약

메서드 의미
response.json() JSON 문자열을 JS 객체로 변환해서 처리하겠다
JSON.stringify(obj) JS 객체 → JSON 문자열로 변환

💡 비유

  • JSON 문자열 = 택배 상자 속 포장지
  • response.json() = 포장지 개봉실제 내용물(JS 객체) 꺼내기
  • JSON.stringify() = 내용물(JS 객체) 다시 포장지(JSON 문자열)에 담기

 

fetch()가 반환하는 response 객체

우리가 실제로 쓰고 싶은 JS 객체 데이터

 

완전히 다른 “객체”라는 점을 구분해야 해요.


1️⃣ fetch()가 반환하는 객체

 
fetch('https://example.com/users')
  .then(response => console.log(response));
  • 여기서 response는 Response 객체
  • Response 객체 안에는 여러 정보가 들어 있음:
속성/메서드 의미
status HTTP 상태 코드 (200, 404 등)
headers 응답 헤더 정보
body 실제 서버가 보내온 데이터 (문자열, 스트림 등)
json() body를 JSON으로 파싱하는 메서드
text() body를 문자열로 읽는 메서드

즉, fetch가 반환하는 response 객체 자체가 서버 데이터를 바로 담고 있는 JS 객체는 아님

그냥 응답 전체를 다루기 위한 래퍼 객체(wrapper)

더보기

**“왜 서버가 JSON 보내도 fetch()에서는 Response 객체가 오는지,

Response 객체 구조는 어떻게 생겼는지”**에 대한 거군요. 차근차근 설명할게요.


1️⃣ 서버가 JSON 보내도 Response 객체가 오는 이유

  • 서버가 보내는 건 HTTP 응답이에요:
    • 상태 코드(status)
    • 헤더(headers)
    • 본문(body, JSON 문자열 등)
  • fetch()는 단순히 body만 주는 게 아니라 HTTP 응답 전체를 다루게 설계되어 있음
  • 따라서 fetch()가 반환하는 Promise는 Response 객체를 줌

즉:

 
서버 → HTTP 응답(JSON 문자열 등)
fetch() → Response 객체(Promise로 감싸서) 반환
  • Response 객체 안에 **body(JSON 문자열)**가 들어 있고, json() 같은 메서드로 쉽게 파싱할 수 있음

요약: Response 객체 = 서버 응답 전체를 다루는 “랩(wrapper) 객체”


2️⃣ Response 객체 구조

  • 실제로 JS에서 Response 객체를 const Response = { ... }처럼 찍어볼 수 있는 건 아님
  • 하지만 구조를 이해하기 쉽게 이렇게 생각할 수 있어요:
 
const Response = {
  status: 200,              // HTTP 상태 코드
  statusText: "OK",         // 상태 메시지
  headers: new Headers(),   // HTTP 헤더
  body: '{"name":"Alice"}', // 서버가 보낸 데이터(JSON 문자열)
  json: function() {        // JSON 문자열 → JS 객체로 변환
    return JSON.parse(this.body);
  },
  text: function() {        // body를 문자열로 반환
    return this.body;
  }
};
  • 실제 구현브라우저 내부 네이티브 코드로 되어 있어서 보여주거나 수정할 수 없음
  • 우리가 보는 건 속성/메서드API 문서로 제공

3️⃣ Response 객체 사용 예시

 
fetch('https://example.com/users')
  .then(response => {
    console.log(response.status); // 200
    console.log(response.headers.get('Content-Type')); // application/json
    return response.json();       // JSON 문자열 → JS 객체
  })
  .then(data => console.log(data)); // 실제 데이터
  • status, headers 등 → Response 객체 속성
  • response.json() → 서버 JSON → JS 객체

💡 비유

  • Response 객체 = 택배 상자
    • status = 배송 상태
    • headers = 송장 정보
    • body = 포장지 속 내용물(JSON 문자열)
    • json() = 포장지 열어서 내용물(JS 객체) 꺼내는 방법

정리하면:

  1. 서버가 JSON 보내도 fetch()는 HTTP 응답 전체를 다루는 Response 객체를 반환
  2. Response 객체 안에서 **body(JSON 문자열)**를 json()으로 변환 → JS 객체로 사용

 

1️⃣ fetch()가 반환하는 건 Promise 객체

const promise = fetch('https://example.com/users');
  • fetch() 자체는 비동기 함수 → 즉시 Promise 객체 반환
  • Promise는 아직 서버에서 데이터가 도착하지 않았을 때도 “미래에 올 값을 약속”하는 객체

2️⃣ Promise가 resolve되면 Response 객체가 됨

 
fetch('https://example.com/users')
  .then(response => {
    console.log(response.status);  // HTTP 상태 코드
    console.log(response.headers); // 응답 헤더
    console.log(response.body);    // 서버가 보낸 JSON 문자열
  });
  • Response 객체 = 서버 응답 전체를 담은 “랩(wrapper) 객체”
    • body(JSON 문자열)
    • status
    • headers
    • json(), text() 같은 메서드

요약: Promise → Response 객체 → body(JSON 문자열) → json()으로 JS 객체


3️⃣ 데이터 흐름

 
서버 응답 (JSON 문자열 등)
        │
        ▼
fetch() → Promise 객체 (미래 응답 약속)
        │
        ▼ resolve
Response 객체
        │
        ├─ body (JSON 문자열)
        ├─ status, headers 등
        └─ json() → JS 객체
  • 즉, fetch()가 바로 JSON 데이터를 주는 게 아니라
    • 서버 데이터를 포함HTTP 응답 전체를 Response 객체로 감싸서 줌
    • 필요한 body(JSON 문자열)만 .json()으로 꺼내서 JS 객체로 사용

💡 비유

  • 서버 JSON = 택배 안 내용물
  • fetch() → Promise = “택배가 올 거라는 약속”
  • resolve된 Response 객체 = 실제 도착한 택배 상자(상태, 송장, 내용물 포함)
  • response.json() = 포장지 열어서 내용물(JS 객체) 꺼내기

즉, fetch() → Promise → Response 객체 → body(JSON) → JS 객체 흐름을 이해하면 완벽합니다.


2️⃣ response.json()이 필요한 이유

  • 서버에서 보내는 **데이터(body)**는 대부분 JSON 문자열
  • 문자열 형태를 그대로 쓰면 JS 코드에서 속성으로 접근할 수 없음:
console.log(response.body); // "[{"name":"Alice","age":23}]" ← 문자열
  • 그래서 response.json()을 호출해서 JSON 문자열 → JS 객체로 변환해야 함
response.json().then(data => console.log(data[0].name)); // Alice
  • 즉, response 객체는 “포장지”, 실제 JSON 데이터는 포장 안의 내용물

3️⃣ 요약

단계 타입 설명
fetch() 반환 Response 객체 서버 응답 전체 (상태, 헤더, body 포함)
response.json() Promise → JS 객체 JSON 문자열(body)을 실제 JS 객체로 변환
then(data) JS 객체 실제 코드에서 바로 사용 가능

💡 비유

  • Response 객체 = 택배 상자 (주소, 송장, 포장 포함)
  • response.json() = 포장지 개봉 → 실제 내용물 꺼내기
  • data = 내용물(JS 객체) → 바로 사용 가능

 

여기서 헷갈리는 포인트는 Response 객체 자체와 그 안의 body(JSON 문자열)의 차이입니다. 차근차근 풀어드릴게요.


1️⃣ Response 객체와 body의 차이

  • fetch() → Promise → Response 객체
  • Response 객체는 이미 JS 객체입니다.
    • 속성: status, headers 등
    • 메서드: .json(), .text(), .blob() 등
  • 하지만 Response 객체 안에 **실제 서버 데이터(body)**는 **문자열(JSON 문자열)**로 들어있습니다.
 
// 예시
fetch(url)
  .then(response => {
    console.log(typeof response);       // object
    console.log(response.status);       // 200
    console.log(response.headers);      // Headers 객체
    console.log(response.body);         // ReadableStream (문자열 데이터)
  });

핵심: Response 객체 자체는 JS 객체이지만, body 안 데이터는 JSON 문자열일 수 있음


2️⃣ 왜 response.json()을 쓰는가?

  • 서버가 보내는 데이터(body)가 JSON 문자열이므로, JS에서 속성처럼 사용하려면 파싱이 필요
  • .json() = Response 객체의 메서드 → body(JSON 문자열) → JS 객체 변환
fetch(url)
  .then(response => response.json())   // body(JSON 문자열) → JS 객체
  .then(data => console.log(data.name)) // 이제 속성 접근 가능
  • 여기서 response.body.json()처럼 안 되는 이유:
    • body는 문자열 또는 스트림
    • 문자열 자체에는 .json() 메서드 없음
    • .json()은 Response 객체가 body를 어떻게 처리할지 알고 있는 메서드

3️⃣ 요약

구분타입사용
구분 타입 사용
Response 객체 JS 객체 status, headers, json() 등 바로 사용 가능
Response.body JSON 문자열 또는 스트림 바로 JS 객체처럼 접근 불가
response.json() 메서드 body(JSON 문자열) → JS 객체

다시 말하면:

Response 자체는 JS 객체

JSON 문자열(body)을 JS 객체로 바꾸려면 .json()을 사용


💡 비유

  • Response 객체 = 택배 상자 (상태, 송장, 포장 포함) → 속성/메서드 바로 사용 가능
  • body = 포장지 속 JSON 문자열 → 바로 꺼내서 JS 객체로 쓰려면 .json()이라는 도구 필요

  • Response 객체에는 여러 속성(status, headers, body 등)과 메서드(json(), text(), ...)가 들어 있음
  • 그중 json() 메서드Response 객체 안에 있는 body(JSON 문자열)JS 객체로 변환(parse)해주는 전용 메서드

즉:

 
Response 객체
├─ status
├─ headers
├─ body (JSON 문자열)
└─ json() → body(JSON 문자열) → JS 객체
  • body 자체는 문자열 또는 스트림이므로 바로 JS 객체처럼 접근할 수 없음
  • 그래서 Response 객체의 .json() 메서드를 호출해서 JSON 문자열 → JS 객체 변환 후 사용

💡 한 줄 요약:

  • Response 객체 = 상자, body = 포장지 속 JSON 문자열, json() = 포장지 개봉해서 JS 객체로 꺼내는 도구

 

Q. 그럼 response.json()해서 서버가 응답해준 결과는 Response 객체 전체를 JS객체로 변환해준 게 아니라 Response 객체 속, body만 JS객체로 변환해서 응답해준 거지? 그래서 fetch('https://example.com/users') .then(response => response.json9)) .then(data => console.log(data)); 에서 결과물은 body에 들어있던 JSON 문자열을 JS 객체로 변환한 말 그대로 실제 데이터(내용물)인거지? Response 객체 안에 들었던 HTTP 응답 전체, 즉 status, headers, json() 이런 것들은 다 안 나오고?

더보기

맞아요! 😄 정확하게 이해하셨습니다.


1️⃣ response.json()의 범위

  • response.json()은 Response 객체 전체를 -> JS 객체로 변환하는 게 아님
  • 오직 Response 객체 속 body(JSON 문자열)만 -> JS 객체로 변환
  • 그래서 .then(data => …)에서 받는 data는 서버가 보낸 실제 데이터(내용물)

2️⃣ Response 객체 전체와 data의 차이

 
fetch('https://example.com/users')
  .then(response => {
    console.log(response.status);  // 200
    console.log(response.headers); // 응답 헤더
    return response.json();
  })
  .then(data => console.log(data)); // body(JSON 문자열) → JS 객체
  • response → Response 객체 (HTTP 응답 전체)
    • 속성: status, headers, body
    • 메서드: json(), text()
  • response.json() → body(JSON 문자열) 파싱 → JS 객체 반환
    • status, headers, json() 등 Response 객체 나머지 정보는 data에 포함되지 않음

3️⃣ 요약

구분 내용
Response 객체 HTTP 응답 전체를 담고 있는 JS 객체
response.json() Response 객체 속 body(JSON 문자열) → JS 객체 변환
data 서버가 보낸 실제 데이터(JS 객체), status/headers는 포함되지 않음

💡 비유

  • Response 객체 = 택배 상자 전체
  • body = 포장지 속 내용물
  • response.json() = 포장지 개봉 → 내용물(JS 객체) 꺼내기
  • data = 꺼낸 내용물 → 바로 사용 가능

 

728x90
반응형