웹 개발을 시작할 때 가장 먼저 이해해야 할 것은 바로 클라이언트와 서버가 어떻게 통신하는가에 대한 구조입니다.
이 통신을 담당하는 핵심 규약이 바로 HTTP(HyperText Transfer Protocol)입니다.
HTTP는 웹 브라우저(클라이언트)와 웹 서버 간에 데이터를 주고받는 통신 규약(프로토콜)입니다.
우리가 브라우저에서 주소를 입력하거나 버튼을 클릭할 때,
눈에 보이지 않지만 HTTP 요청이 서버로 전송되고, 서버는 이에 응답을 돌려주는 구조로 작동합니다.
쉽게 말해, "누가 어떤 자원을 어떻게 요청하고, 그 요청에 어떻게 응답할지를 정한 약속"입니다.
HTTP 통신은 크게 두 부분으로 나뉩니다.
이 구조를 통해 웹 페이지, 이미지, JSON 데이터, 파일 등을 전송할 수 있습니다.
요청은 다음과 같은 구성으로 이루어집니다.
| 구성 요소 | 설명 |
|---|---|
| 메서드(Method) | 동작의 목적: GET, POST, PUT, DELETE 등 |
| URL | 어떤 자원을 요청하는가 (예: /posts/1) |
| 헤더(Header) | 요청에 대한 부가 정보 (브라우저 정보, 인증, 데이터 형식 등) |
| 본문(Body) | 서버에 전달할 실제 데이터 (POST, PUT 등에서 사용됨) |
응답 역시 다음과 같은 구성으로 이루어집니다.
| 구성 요소 | 설명 |
|---|---|
| 상태 코드(Status Code) | 요청 처리 결과 (200, 404, 500 등) |
| 헤더(Header) | 응답에 대한 부가 정보 (콘텐츠 타입, 길이 등) |
| 본문(Body) | 실제 사용자에게 보여줄 데이터 (HTML, JSON, 이미지 등) |
웹 개발에서 가장 기본적인 동작은 클라이언트가 서버로 요청을 보내고, 서버가 응답을 돌려주는 것입니다.
그렇다면 클라이언트는 서버에 어떤 형식으로 요청을 보낼까요?
바로 HTTP 요청 메시지를 구성하여 서버로 전달합니다.
이 메시지는 크게 요청라인, 헤더, 본문(body)의 세 부분으로 나뉩니다.
아래는 실제 로그인 요청을 예로 든 구조입니다.
POST /login HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer abc123
{
"username": "user1",
"password": "pass123"
}
| 구분 | 설명 |
|---|---|
| 요청라인 (Request Line) | 어떤 동작을 어떤 방식으로 요청할 것인지 나타냄 |
| 헤더 (Headers) | 요청에 대한 부가 정보 (데이터 형식, 인증 정보 등) |
| 빈 줄 | 헤더와 바디를 구분 |
| 바디 (Body) | 실제 서버에 전달하고자 하는 데이터 (POST, PUT 등에서 사용) |
요청 메시지의 가장 첫 줄로, “이 요청이 어떤 자원에 어떤 방식으로 동작하길 원하는지”를 나타냅니다.
POST /login HTTP/1.1
| 항목 | 설명 |
|---|---|
| POST | 동작을 나타내는 HTTP 메서드 (데이터 생성 요청) |
| /login | 서버에 있는 자원의 경로 (URL) |
| HTTP/1.1 | 사용 중인 HTTP 버전 (프로토콜 버전) |
헤더는 요청 자체에 대한 부가적인 정보를 담는 곳입니다.
브라우저의 정보, 콘텐츠 타입, 인증 토큰 등 여러 메타데이터가 포함됩니다.
Host: example.com
Content-Type: application/json
Authorization: Bearer abc123
| 헤더 | 설명 |
|---|---|
| Host | 요청할 대상 서버의 도메인 또는 IP |
| Content-Type | 요청 본문의 데이터 형식 (예: application/json, text/html) |
| Authorization | 인증 정보 (예: JWT 토큰 등) |
요청 본문은 서버에 실제로 전달하고자 하는 데이터입니다.
POST, PUT, PATCH 같은 메서드에서 주로 사용되며, 로그인, 회원가입, 게시글 등록 등에 사용됩니다.
{
"username": "user1",
"password": "pass123"
}
서버가 클라이언트 요청을 처리한 후, 다음과 같은 메시지를 돌려줍니다.
이 응답 메시지는 브라우저 또는 클라이언트 앱이 결과를 해석하고 화면에 반영하는 기준이 됩니다.
아래는 실제 HTTP 응답 메시지의 예시입니다.
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 56
{
"message": "로그인 성공",
"userId": 123
}
| 구분 | 설명 |
|---|---|
| 상태라인 | 상태 코드와 메시지를 포함 |
| 헤더 | 응답에 대한 부가 정보 |
| 빈 줄 | 헤더와 바디 구분 |
| 바디 | 실제 전달할 데이터 (JSON, HTML 등) |
상태라인은 응답의 가장 첫 줄이며, 서버가 클라이언트의 요청을 어떻게 처리했는지를 알려줍니다.
HTTP/1.1 200 OK
| 항목 | 설명 |
|---|---|
| HTTP/1.1 | 응답 프로토콜 버전 |
| 200 | 상태 코드 (성공) |
| OK | 설명 메시지 |
응답 헤더는 본문을 해석하기 위한 부가 정보를 제공합니다.
Content-Type: application/json
Content-Length: 56
Set-Cookie: sessionId=abc123
| 헤더 | 설명 |
|---|---|
| Content-Type | 응답 데이터의 형식 (application/json, text/html 등) |
| Content-Length | 응답 바디의 길이 (바이트 기준) |
| Set-Cookie | 클라이언트에 저장할 쿠키 정보 |
| Cache-Control | 캐싱 정책 설정 |
응답 바디는 클라이언트가 실제로 화면에 표시하거나 사용하는 데이터입니다.
{
"message": "로그인 성공",
"userId": 123
}
HTTP 메서드는 클라이언트가 서버에 어떤 동작을 요청하는지를 나타내는 방법입니다.
RESTful API 설계에서 메서드는 매우 중요한 요소이며, 각 메서드는 특정한 목적에 따라 동작해야 합니다.
| 메서드 | 설명 | 동작 예시 | 특징 |
|---|---|---|---|
| GET | 데이터 조회 | 게시글 목록 조회, 특정 글 상세 보기 | 서버의 상태나 데이터를 읽기만 함 (데이터 변경 없음) |
| POST | 데이터 생성 | 회원가입, 게시글 등록 | 서버에 데이터를 추가함 (요청 바디에 데이터 포함) |
| PUT | 전체 수정 | 게시글 전체 수정, 사용자 정보 전체 수정 | 자원 전체를 새로 덮어쓰기 (멱등성, idempotent: 같은 요청 결과를 반복해도 결과 동일) |
| PATCH | 일부 수정 | 게시글 일부 내용 변경, 비밀번호만 변경, 닉네임만 변경 | 자원의 일부 속성만 수정, PUT 보다 효율적 |
| DELETE | 삭제 | 게시글 삭제 | 특정 자원을 삭제 요청 (데이터 제거) |
RESTful API 설계에서는 이 메서드들이 클라이언트의 의도를 명확히 전달하는 수단이 됩니다.
| 동작 | HTTP 메서드 | 경로 예시 |
|---|---|---|
| 게시글 목록 조회 | GET | /api/posts |
| 게시글 상세 조회 | GET | /api/posts/1 |
| 새 게시글 등록 | POST | /api/posts |
| 게시글 전체 수정 | PUT | /api/posts/1 |
| 게시글 일부 수정 | PATCH | /api/posts/1 |
| 게시글 삭제 | DELETE | /api/posts/1 |
| 구분 | PUT | PATCH |
|---|---|---|
| 목적 | 전체 자원 교체 | 자원의 일부분 수정 |
| 요청 데이터 | 전체 필드를 포함해야 함 | 수정할 필드만 포함 가능 |
| 사용 시기 | 폼 전체 수정 | 필드 일부만 바꿀 때 |
| 예시 | PUT api/user/1 {name, email, age} | PATCH api/user/1 {name} |
아래는 "게시글 등록"이라는 기능을 예로 들어 클라이언트와 서버 사이의 요청-응답 흐름을 구성한 예시입니다.
POST /boards HTTP/1.1
Content-Type: application/json
{
"title": "첫 번째 게시글",
"content": "내용입니다."
}
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": 1,
"message": "등록 완료"
}
서버는 요청 처리 결과를 상태 코드로 알려줍니다.
프론트엔드와 백엔드는 이 상태 코드를 기준으로 다음 행동을 결정합니다.
| 코드 | 의미 | 설명 |
|---|---|---|
| 200 OK | 성공 | 요청이 정상적으로 처리됨 |
| 201 Created | 생성됨 | POST 요청으로 자원이 새로 생성됨 |
| 400 Bad Request | 잘못된 요청 | 요청 형식이 잘못되었거나 누락된 데이터 존재 |
| 401 Unauthorized | 인증 실패 | 로그인 또는 토큰 인증이 되지 않음 |
| 403 Forbidden | 접근 거부 | 요청은 유효하지만 권한이 없음 |
| 404 Not Found | 자원 없음 | 요청한 URL이나 자원이 존재하지 않음 |
| 500 Internal Server Error | 서버 오류 | 서버 내부에서 예기치 않은 오류 발생 |
상태 코드는 프론트엔드/백엔드 모두가 요청 처리 결과를 빠르게 파악할 수 있게 해주는 중요한 소통 도구입니다.
Node.js에서 가장 널리 쓰이는 백엔드 프레임워크인 Express.js는 복잡한 HTTP 메시지를 다루기 쉽게 도와주는 도구입니다.
// GET 요청 처리
app.get("/users", (req, res) => {
res.send("회원 목록을 조회합니다.");
});
// POST 요청 처리
app.post("/users", (req, res) => {
res.send("회원 가입 요청을 처리합니다.");
});
| Express 메서드 | 의미 |
|---|---|
app.get() | GET 요청 처리 |
app.post() | POST 요청 처리 |
app.put() | PUT 요청 처리 (전체 수정 요청 처리) |
app.delete() | DELETE 요청 처리 (삭제 요청 처리) |
| 객체 | 설명 |
|---|---|
| req | 클라이언트로부터 들어온 요청 정보를 담고 있음 (경로, 헤더, 쿼리 바디 등) |
| res | 서버가 클라이언트에게 보낼 응답을 담고 조작하는 객체 (상태 코드, 본문 등) |
| 핵심 개념 | 설명 |
|---|---|
| HTTP란? | 클라이언트와 서버가 데이터를 주고받는 규약 |
| 요청 구조 | 메서드, URL, 헤더, 바디로 구성됨 |
| 응답 구조 | 상태 코드, 헤더, 바디로 구성됨 |
| 메서드 종류 | GET, POST, PUT, PATCH, DELETE 등 |
| 상태 코드 | 요청 처리 결과를 나타내는 숫자 코드 (200, 201, 400, 401, 404, 500 등) |
| Express.js | Node.js에서 HTTP 처리를 쉽게 해주는 백엔드 프레임워크 |