오늘 방문 /누적 방문 /완성한 레슨 소개 ↗
SECONDTEAM
웹·배포
🌐 레슨

HTTP — 요청과 응답의 대화

브라우저와 서버는 정해진 형식으로 편지를 주고받아요. 그 편지를 직접 보내봐요.

① 오늘의 미션
가게와 손님 사이의 편지 규칙
지난 레슨에서 주소창(URL)을 부위별로 해부했어요. 오늘은 그 주소로 실제 편지를 주고받습니다 — 손님(브라우저)이 우리 반찬가게 서버에 요청을 보내고, 서버가 응답으로 답하는 약속, 그게 HTTP예요.

오늘의 하이라이트: 터미널에서 curl 한 줄로 직접 요청을 보내 응답 원문을 눈으로 봅니다. 브라우저가 화면 뒤에서 매번 하던 일을, 이번엔 우리가 손으로 해요.

설명을 따라 진행하면, 여기서 직접 쳐보게 돼요 👇
~/my-shop
$ _
📚 「HTTP — 요청과 응답의 대화」 레슨 내용 전체 텍스트로 훑어보기
가게와 손님 사이의 편지 규칙
지난 레슨에서 주소창(URL)을 부위별로 해부했어요. 오늘은 그 주소로 실제 편지를 주고받습니다 — 손님(브라우저)이 우리 반찬가게 서버에 요청을 보내고, 서버가 응답으로 답하는 약속, 그게 HTTP예요.

오늘의 하이라이트: 터미널에서 curl 한 줄로 직접 요청을 보내 응답 원문을 눈으로 봅니다. 브라우저가 화면 뒤에서 매번 하던 일을, 이번엔 우리가 손으로 해요.

요청도 응답도, 정해진 양식의 편지예요
손님이 보내는 요청(request)엔 세 가지가 들어가요 — 무엇을 할지(메서드: GET/POST) · 어디로(주소) · 봉투에 적는 부가정보(헤더).
가게가 보내는 응답(response)엔 두 가지가 와요 — 맨 앞의 상태코드(됐어/안돼)와, 실제 내용이 담긴 본문(body).
한 줄로
HTTP는 "무엇을·어디로·어떻게" 묻고, "됐는지·내용은 뭔지" 답하는 편지 규칙이에요.
손님이 우리 가게 서버에 보내는 '요청' 한 통에 반드시 들어가는 것은?
맞아요. 요청은 메서드(무엇을) · 주소(어디로) · 헤더(부가정보)로 구성돼요. 상태코드는 응답 쪽에 오는 거라, 요청엔 안 들어가요. 손님이 보내고 → 가게가 상태코드로 답하는 순서예요.

이제 손으로 요청을 보내봐요. curl은 터미널에서 주소로 편지를 보내는 도구예요. 우리 반찬가게의 인기 메뉴 목록을 읽어와(GET) 봅시다. 주소만 적으면 기본이 GET이에요.

curl https://shop.example.com/menu — 메뉴 목록을 요청해요 (주소만 적으면 GET)
방금 본 그 글자 뭉치가 응답의 본문(body)이에요. 브라우저는 이걸 받아 예쁜 화면으로 그리지만, 알맹이는 이렇게 생겼어요. 우리가 그 알맹이를 직접 본 거예요.
응답은 숫자 한 마디로 시작해요
모든 응답은 상태코드로 시작해요. 본문을 읽기도 전에 "됐어/안됐어"를 알려주는 첫마디죠. 앞자리로 묶여요 — 2xx=성공 · 4xx=손님 잘못 · 5xx=가게(서버) 잘못.
  • 200 OK — 요청 성공, 본문에 데이터가 있어요
  • 404 Not Found — 그 주소(경로)가 없어요 (예: 없는 반찬 페이지)
  • 401 Unauthorized — 인증이 필요해요
  • 500 Internal Server Error — 가게 쪽 버그예요, 손님 탓 아님
앞자리만 봐도 누구 잘못인지 보여요 — 4로 시작하면 내 요청을 의심, 5로 시작하면 서버를 의심.

없는 주소로 요청하면 어떤 상태코드가 올까요? 예를 들어 우리 가게에 없는 /menu/없는반찬 페이지를 요청하면?

맞아요. 없는 경로는 404 Not Found예요. 4xx는 손님(요청) 쪽 문제 — 주소 오타거나 없는 페이지죠. 서버가 멈춘 게 아니라 "그런 거 없어요"라고 정중히 답한 거예요.

아까는 본문만 봤죠. 이번엔 -i 옵션으로 상태코드와 헤더(봉투에 적힌 부가정보)까지 통째로 봐요. 디버깅할 땐 이 봉투가 결정적 단서예요.

curl -i https://shop.example.com/menu — 상태코드+헤더까지 함께 받아요
맨 윗줄 HTTP/2 200상태코드, 그 아래 content-type헤더 — "본문은 JSON 형식이에요"라고 알려주는 봉투의 메모예요. 빈 줄 아래가 본문이고요.

헤더는 요청에도 붙일 수 있어요. curl에서 헤더 한 줄을 다는 옵션은 무엇일까요? 예를 들어 "본문은 JSON이에요"라고 알리려고 Content-Type 헤더를 붙이는 옵션입니다.

정답! -H(Header)예요. -H "키: 값" 형식으로 봉투에 메모를 붙여요. 여러 개 달고 싶으면 -H를 여러 번 쓰면 돼요. 인증이 필요한 가게라면 여기에 Authorization 헤더로 신분을 적어 보내요.
같은 가게라도 '메뉴를 조회'하는 것과 '주문을 접수'하는 건 다른 일이에요. HTTP는 이 둘을 메서드로 구분해요.
GET — 읽기 (메뉴 조회): 손님이 "인기 반찬 뭐 있어요?"라고 물어보는 것.
서버의 데이터를 가져오기만 하고 바꾸지 않아요.
보낼 내용물이 없어 주소만 적으면 돼요.
몇 번을 물어봐도 가게는 그대로예요.
POST — 보내기 (주문 접수): 손님이 "제육볶음 2개 주문이요"라고 내용을 보내는 것.
서버에 새 데이터(주문)를 만들어요.
보낼 내용물(주문 정보)을 본문에 담아 보내요.
두 번 보내면 주문이 두 건 생길 수 있어요.

이번엔 읽기가 아니라 보내기예요. 손님이 되어 제육볶음 2개를 주문해봅시다. -X POST로 메서드를 바꾸고, -d로 주문 내용(본문)을 담아요.

curl -X POST -H "Content-Type: application/json" -d '{"menu":"제육볶음","qty":2}' https://shop.example.com/orders — 주문을 POST로 보내요 (-d에 본문을 담아서)
상태코드가 200이 아니라 201 Created네요 — "새로 만들어졌다"는 2xx의 한 종류예요. 본문엔 방금 만들어진 주문번호가 돌아왔고요. 우리가 보낸 편지가 가게에 실제로 무언가를 만든 거예요.

curl은 주소만 적으면 GET이에요. 그럼 GET이 아니라 POST로 메서드를 바꾸는 옵션은 무엇일까요? 빈칸을 채워보세요.

정답! -X(reQuest method)로 메서드를 바꿔요. -X POST는 "이건 조회가 아니라 보내는 요청이야"라고 선언하는 거예요. -d로 담은 본문과 짝을 이뤄 주문이 완성돼요.

손님이 주문을 넣고 응답을 받기까지, HTTP 편지가 오가는 순서를 맞춰보세요. (↑↓로 정렬)

완벽해요! 요청 구성 → 본문 담아 보내기 → 상태코드로 답 → 본문으로 결과. 브라우저가 화면 뒤에서 매번 이 왕복을 하고 있었던 거예요.
한 줄로
HTTP는 요청(메서드+주소+헤더)응답(상태코드+본문)으로 오가는 편지 규칙이에요. 오늘 curlGET(읽기)POST(보내기)를 손으로 보냈고, 상태코드 앞자리만 봐도 누구 잘못인지 읽는 눈을 얻었어요.
다음 레슨에서
API란 — 폼이 DB와 말하는 법으로 이어가요. 손님이 우리 가게 신청서(폼)에 입력한 내용이, 오늘 배운 이 POST 요청을 타고 데이터베이스까지 어떻게 도착하는지 따라가 봅니다. ✉️