백엔드 개발을 하다 보면 “클라이언트가 서버에 요청을 보낸다”라는 말을 매일 듣습니다.
그런데, 실제로 요청이 어떻게 전달되고, 서버는 어떤 과정을 거쳐 응답을 돌려주는지 알아보겠습니다.
이번 글에서는 제가 공부하면서 정리한
클라이언트 ↔ 서버 통신의 핵심 개념을 정리해봤습니다.
모든 서버 개발의 출발점은 요청(Request) 과 응답(Response) 입니다.
클라이언트(브라우저)가 서버에 요청을 보내면,
인터넷을 거쳐 서버가 응답을 돌려주는 구조죠.
하지만 단순히 "요청 → 응답"만 있는 게 아닙니다.
그 뒤에는 IP, TCP, DNS 등 수많은 통신 계층이 존재합니다.
IP는 인터넷 상의 주소 체계입니다.
사람에게는 주소가 있고, 컴퓨터에는 IP가 있습니다.
192.168.0.1단, IP만으로는 데이터가 제대로 도착했는지 보장할 수 없습니다.
그래서 TCP나 UDP 같은 상위 프로토콜이 등장합니다.
“정확하게” 데이터를 주고받는 연결형 프로토콜
TCP는 데이터 전송의 안정성을 보장합니다.
연결 전에는 다음과 같은 3-way handshake 과정을 거칩니다.
SYN (연결 요청) SYN + ACK (요청 수락) ACK (확인 응답)이제 연결이 완료되면 안전하게 데이터를 전송할 수 있습니다.
로그인, 결제, 파일 다운로드 같은 정확성이 중요한 요청에서 주로 사용됩니다.
빠르지만 “확실하지 않은” 비연결형 프로토콜
UDP는 TCP처럼 연결 과정을 거치지 않습니다.
그냥 “하얀 도화지에 던지는 느낌”으로 데이터를 전송하죠.
UDP는 데이터 전송 시 포트 번호 + 체크섬 정보만 포함합니다.
사람은 www.google.com처럼 이름을 기억하지만,
컴퓨터는 142.250.196.142 같은 IP 주소로 통신합니다.
이 둘을 연결해주는 시스템이 바로 DNS입니다.
예시 흐름:
클라이언트 → “google.com 요청”
DNS 서버 → “142.250.196.142” IP 응답
클라이언트 → 해당 IP로 실제 요청 전송
HTTP는 웹에서 데이터를 주고받는 프로토콜입니다.
거의 모든 서버 통신은 HTTP를 기반으로 동작합니다.
HTTP : Hyper Text Transfer Protocol HTTPS : HTTP + SSL/TLS 보안 계층 (암호화된 통신)즉, HTTPS는 보안이 강화된 HTTP라고 생각하면 됩니다.
요즘은 대부분 HTTPS를 기본으로 사용하죠.
서버가 클라이언트의 상태(로그인 등)를 기억하는 구조입니다.
예를 들어 로그인 후 "내 정보"를 조회할 때 같은 서버가 계속 나를 알아야 하죠.
HTTP는 기본적으로 무상태(Stateless) 프로토콜입니다.
즉, 서버는 클라이언트의 상태를 기억하지 않습니다.
👉 그래서 JWT 같은 토큰 기반 인증이 자주 쓰입니다.
HTTP 통신은 메시지(Message) 기반으로 이루어집니다.
# 요청 메시지 예시
GET /members HTTP/1.1
Host: example.com
User-Agent: Chrome/127.0.0.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 1,
"name": "정범"
}
| 상태 코드 | 의미 | 설명 |
|---|---|---|
| 1xx (Informational) | 정보 | 요청이 수신되어 처리 중임을 의미 |
| 2xx (Success) | 성공 | 클라이언트 요청이 성공적으로 수행됨 |
| 3xx (Redirection) | 리다이렉션 | 요청을 완료하기 위해 추가 작업(다른 URI 요청 등)이 필요함 |
| 4xx (Client Error) | 클라이언트 오류 | 잘못된 요청 (예: 잘못된 URL, 권한 없음 등) |
| 5xx (Server Error) | 서버 오류 | 서버에서 요청을 처리하지 못함 |
정상적으로 요청이 성공적으로 처리됨.
예시: GET /members 요청 시 회원 목록을 정상적으로 응답받았을 때.
요청이 성공적으로 처리되어 리소스가 생성됨.
예시: POST /members 요청 시 새로운 회원이 생성된 경우.
요청이 성공했지만, 응답 바디가 없음.
예시: DELETE /members/{id} 요청 시 정상 삭제 후 응답 바디가 없을 때.
요청한 리소스의 URI가 변경되었음을 의미.
브라우저는 이후 요청부터 새 URI로 자동 전환함.
임시로 다른 URI로 요청을 보낼 것을 지시.
보통 로그인 후 리다이렉트 등에서 사용됨.
클라이언트의 요청이 잘못됨.
예시: 필수 파라미터 누락, 잘못된 JSON 포맷 등.
인증이 필요함.
로그인이나 토큰이 필요한 API 요청 시 인증 누락 시 발생.
인증은 되었으나 접근 권한이 없음.
예시: 일반 사용자가 관리자 페이지에 접근하려는 경우.
요청한 리소스를 찾을 수 없음.
예시: 존재하지 않는 회원 ID 요청 시.
서버 내부 오류.
서버 로직, DB 문제 등 서버 측에서 발생한 예외 상황.
RESTful API를 설계할 때는 리소스 중심(Resource-Oriented) 으로 생각해야 합니다.
즉, “무엇을” 다루는지를 URI로 표현하고, “어떻게” 다루는지는 HTTP 메서드로 구분합니다.

| 행위 | HTTP 메서드 | URI 예시 | 설명 |
|---|---|---|---|
| 조회 | GET | /members | 회원 목록 조회 |
| 단일 조회 | GET | /members/{id} | 특정 회원 조회 |
| 등록 | POST | /members | 회원 생성 |
| 수정(전체) | PUT | /members/{id} | 회원 정보 전체 수정 |
| 수정(부분) | PATCH | /members/{id} | 회원 정보 일부 수정 |
| 삭제 | DELETE | /members/{id} | 회원 삭제 |
RESTful 설계를 할 때 URI를 단순히 “주소”로만 보면 부족합니다.
리소스의 구조적 의미를 명확히 하기 위해 다음 네 가지 개념을 함께 이해해두면 좋습니다.
POST 요청으로 새로운 리소스를 생성)💡 TIP:
RESTful 설계에서는 기본적으로 “명사형 리소스”를 사용하지만,
명령형 프로세스가 필요한 경우엔 이렇게 컨트롤러 URI 형태로 확장합니다.
"같은 요청을 여러 번 보내더라도 결과가 동일해야 한다"
| 메서드 | 멱등성 | 설명 |
|---|---|---|
GET | ✅ | 여러 번 조회해도 결과 동일 |
PUT | ✅ | 동일한 데이터로 여러 번 수정해도 결과 동일 |
DELETE | ✅ | 이미 삭제된 리소스에 다시 요청해도 결과 동일 |
POST | ❌ | 호출할 때마다 새로운 리소스가 생성됨 |
💡 POST는 멱등하지 않음 — 같은 요청을 반복하면 중복된 데이터가 생길 수 있음.
Asynchronous JavaScript And XML 의 약자로, 페이지 전체를 새로고침하지 않고도 서버와 데이터를 주고받을 수 있게 해주는 기술입니다.
fetch('/members')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
• fetch() 함수는 비동기 통신을 수행합니다.
• 서버로부터 JSON 형식의 응답을 받으면 .then()으로 처리합니다.
• 에러 발생 시 .catch()에서 처리합니다.
✅ 장점: 페이지 새로고침 없이도 데이터 요청 및 갱신 가능
✅ 활용: 검색 자동완성, 댓글 등록, 좋아요 기능 등