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 = 꺼낸 물건을 담는 바구니(사용자가 이름 정함)
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 객체) 꺼내는 방법
정리하면:
- 서버가 JSON 보내도 fetch()는 HTTP 응답 전체를 다루는 Response 객체를 반환
- 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 = 꺼낸 내용물 → 바로 사용 가능
'프로그래밍' 카테고리의 다른 글
| 인증, 권한 관리 (0) | 2025.10.10 |
|---|---|
| DB 설계 :: DBSM :: SQL -> Query :: CRUD (0) | 2025.10.10 |
| 백엔드 API 명세 설계 예시 (0) | 2025.10.09 |
| 백엔드 API 명세 설계 예시 (0) | 2025.10.09 |
| 엔드포인트 란? API 호출과의 연관성 (0) | 2025.10.08 |
| 이스케이프 문자 란? 이스케이프 문자 종류 \" \n \r\n (줄바꿈) ... (0) | 2025.10.08 |
| JS 객체 vs JSON 문법 규칙 차이 :: " " (0) | 2025.10.08 |
| 객체(Object) vs JSON (0) | 2025.10.08 |