API
💡 API는 프로그램끼리 서로 대화하기 위한 인터페이스(약속)입니다.
↳ 쉽게 말하면 요청하면 결과를 돌려주는 창구입니다.
✔️ 예시
API = 메뉴판
클라이언트 -> 주문 (요청)
서버 -> 음식 제공(응답)
HTTP API
💡 HTTP API는 HTTP를 이용해서 데이터를 주고받는 API입니다.
*저희가 사용하는 웹사이트, 애플리케이션, 서버 통신 등 거의 다 HTTP API를 이용합니다.
✔️ 예시
GET/members/1 -> 1번 회원 정보 주세요
POST/members -> 회원 생성해 주세요
잘못된 API 설계
- 회원 목록 조회 /read-member-list
- 회원 조회 /read-member-by-id
- 회원 등록 /create-member
- 회원 수정 /update-member
- 회원 삭제 /delete-membe
실제로 많은 사람들이 위와 같이 URL에 행위를 직접 작성하는 방식으로 설계합니다.
얼핏 보면 직관적으로 보이지만 이 방식에는 몇 가지 문제가 있습니다.
단점
✔️ URL이 점점 길어지고 규칙이 없어 유지보수가 어려워짐.
↳ 기능이 추가될수록 URL도 늘어나고, 팀원마다 네이밍 방식이 달라질 수 있다
✔️ 행위(동사)가 URL에 포함됨
↳ read, create, update, delete처럼 무엇을 하는지 URL에 담겨 있는 것
설계할 때 가장 중요한 것은 리소스를 식별하는 것
리소스
✔️ "미네랄을 캐라"
↳ 미네랄 = 리소스, 캐라 = 행위
'✔️ 회원 조회
↳ 회원 = 리소스, 조회 = 행위
위와 같이 회원 API에서 리소스는 회원 그 자체입니다. 등록, 수정, 삭제 등은 리소스가 아닌 행위입니다.
따라서 URI에는 리소스만 담고, 행위는 URI 밖에서 표현해야 합니다. 그 역할을 하는 것이 바로 HTTP 메서드입니다.
올바른 URI 설계(리소스와 행위 분리)
GET /members → 회원 목록 조회
GET /members/{id} → 회원 조회
POST /members → 회원 등록
PATCH /members/{id} → 회원 수정
DELETE /members/{id} → 회원 삭제
리소스 중심으로 URI를 설계하면 URI는 members 하나로 통일 되고, 어떤 행위인지는 앞에 붙은 메서드가 구분해주어 훨씬 단순해집니다.
💡URI를 설계할 때 단수보다 복수 단어 사용을 권장하며 컬렉션 개념으로 표현하는 것이 일반적입니다.
↳ ex) member -> members
컬렉션 : 여러 개를 묶어놓은 것으로 리스트(members, 회원들의 집합)를 의미
리소스와 행위 분리 이유
핵심 원칙
| 구분 | 역할 | 예시 |
| URI | 리소스 식별(명사) | /members, /members/{id} |
| HTTP 메서드 | 행위 표현(동사) | GET, POST, PATCH, DELETE |
장점
💡 URI가 리소스만 담당하고 행위는 HTTP 메서드가 담당하면, URL이 짧고 일관성 있게 유지 가능
↳ 새로운 기능이 추가되어도, URI 구조는 그대로이고 메서드만 바뀌기 때문에 유지보수도 용이함
HTTP 메서드
💡HTTP 메서드는 클라이언트가 서버에 어떤 작업을 요청하는지 알려주는 수단이다.
↳ 쉽게 말하면 서버에 보내는 요청의 종류를 나타내는 것
| 주요 메서드 | 기능 |
| GET | 리소스 조회 |
| POST | 요청 데이터 처리, 주로 등록에 사용 |
| PUT | 리소스 대체, 해당 리소스가 없으면 생성 |
| PATCH | 리소스 부분 변경 |
| DELETE | 리소스 삭제 |
GET
💡GET은 리소스를 조회할 때 사용, 서버에 전달하고 싶은 데이터는 쿼리 파라미터(쿼리 스트링)를 통해 전달한다.
↳ 단순 조회이기 때문에 서버의 데이터를 변경하지 않으며, 덕분에 "캐싱"이 가능하다.
❗ 메시지 바디로도 데이터를 전달할 수 있지만, 지원하지 않는 서버가 많아 권장하지 않음
쿼리 스트링이라고 불리는 이유는 숫자도 문자열로 받기 때문
예시
✔️ 요청(클라이언트)
GET /members/100 HTTP/1.1
Host: localhost:8080
✔️ 응답(서버)
HTTP/1.1 200 OK
{
"username": "young",
"age": 20
}
POST
💡POST는 바디를 통해 서버에 데이터를 전달해서 요청 데이터를 처리할 때 사용한다.
↳ POST 요청을 받은 서버는 신규 리소스를 생성하고, 생성된 리소스의 위치를 헤더의 'Location'으로 돌려준다.
예시
✔️ 요청
POST /members HTTP/1.1
Content-Type: application/json
{
"username": "young",
"age": 20
}
✔️ 응답
HTTP/1.1 201 Created
Location: /members/100

POST와 GET의 차이
✔️ GET이 데이터를 가져오는 것이라면, POST는 요청 데이터를 서버로 보내서 뭔가를 만들거나 처리하는 것이다.
✔️ GET은 클라이언트가 ''members/100'처럼 조회할 리소스 위치를 직접 지정하지만, POST는 서버가 신규 리소스 식별자를 생성해 준다. 즉, 클라이언트는 '/members'까지만 알면 되고, '100'이라는 ID는 서버가 알아서 만들어준다
POST 사용 예시

정리
🎈 POST는 이 URI로 데이터가 오면 어떻게 처리할지 서버가 정한다는 개념입니다. POST 하나로 거의 모든 것을 처리할 수 있지만, 서버끼리 GET이 오면 캐싱을 하겠다는 약속이 있어 목적에 맞는 메서드를 사용하는 것이 중요합니다.
PUT
💡PUT은 리소스를 완전히 대체(기존 리소스 삭제)할 때 사용합니다.
↳ ex) 프로필 수정 페이지에서 모든 항목 수정하고 저장 버튼 누르는 경우
예시
✔️ 요청
PUT /members/100 HTTP/1.1
Content-Type: application/json
{
"username": "hello",
"age": 20
}
✔️ '/members/100'가 없으면 신규 생성, 있으면 기존 리소스를 완전히 대체(기존 리소스 삭제)
PUT과 POST 차이
✔️ PUT은 클라이언트가 리소스의 정확한 위치를 알고 URI를 직접 지정한다
*POST는 /members 까지만 알아도 되지만, PUT은 /members/100처럼 어떤 리소스를 대체할지 정확히 알아야 한다.
정리
🎈 PUT은 수정이 아니라, 완전히 대체를 하는 것이기 때문에 일부 데이터만 변경할 때 PUT을 사용하면 나머지 필드가 사라질 수 있다. 일부 변경은 PATCH를 사용해야 한다.
PATCH
💡PATCH는 리소스를 부분적으로 변경할 때 사용한다.
예시
✔️요청
PATCH /members/100 HTTP/1.1
Content-Type: application/json
{ "age": 50 }
✔️ 결과
- 현재 서버에 저장된 데이터
{ "username": "young", "age": 20 }
- username은 그대로, age만 변경
{ "username": "young", "age": 50 }
정리
🎈 실제로는 회원 정보 수정 기능을 만들 때는 대부분 PATCH를 사용한다. PUT은 정말 리소스 전체를 교체해야 하는 상황에서만 사용하는 것이 안전하다.
DELETE
💡 DELETE는 리소스를 제거할 때 사용한다.
↳ 지정한 URI의 리소스를 한 번 삭제하든, 여러 번 삭제하든 결과는 동일하게 삭제된 상태이다.
HTTP 메서드 속성
안전 (Safe)
| 메서드 | 안전 여부 | 이유 |
| GET | O | 단순 조회(데이터 변경 x) |
| POST | X | 데이터 생성 |
| PUT | X | 데이터 대체 |
| PATCH | X | 데이터 수정 |
| DELETE | X | 데이터 삭제 |
🎈 안전은 해당 리소스 자체만 고려하고, 로그 적재 및 서버 부하 같은 외부 요인은 안전의 범주에 포함 x
↳ GET을 계속 호출해서 로그가 쌓여 서버 장애 발생 등
멱등 (Idempotent)
💡벽등이란, 같은 요청을 몇 번 반복해도 결과가 항상 동일한 것을 멱등하다고 한다.
↳ 수학적 표현 : f(f(x)) = f(x)
| 메서드 | 멱등 여부 | 이유 |
| GET | 멱등 | 몇 번 조회해도 같은 결과 |
| PUT | 멱등 | 기존 데이터를 완전히 대체하기 때문에 몇 번 해도 최종 결과 동일 |
| DELETE | 멱등 | 몇 번 삭제해도 삭제된 상태로 동일 |
| POST | 멱등 x | 호출할 때마다 새로운 데이터 생성 |
POST가 멱등하지 않은 이유
✔️ 결제 버튼 두 번 클릭
→ POST /orders 두 번 호출
→ 주문이 2개 생성
❗위와 같이 POST가 중복 호출되면 심각한 문제가 발생할 수 있다. 그래서 결제나 주문 같은 기능은 중복 호출을 막는 별도 처리가 필요하다.
멱등의 필요성
💡멱등의 핵심은 자동 복구 메커니즘으로, 아래 예시를 통해 알아보겠습니다.
✔️ DELETE 요청을 보냈는데 서버 응답이 없음
→ 잘 됐는지 안 됐는지 모름
→ 멱등하기 때문에 클라이언트가 자동으로 재시도 가능
→ 몇 번 호출해도 결과는 삭제된 상태로 동일하니까 안전
POST는 멱등하지 않기 때문에 응답이 없다고 자동으로 재시도하면 중복 처리 발생 우려
멱등의 한계
❗멱등은 외부 요인으로 리소스가 변경되는 것까지는 고려하지 않는다.
✔️ 예시
사용자 1: GET → { username: "A", age: 20 } 조회
사용자 2: PUT → { username: "A", age: 30 }으로 변경
사용자 1: GET → { username: "A", age: 30 } 조회 (결과가 달라짐!)
🎈벽등은 동일한 클라이언트가 동일한 요청을 반복할 때를 기준으로 하며, 다른 클라이언트가 중간에 리소스를 변경하는 상황은 고려하지 않는다.
캐시가능 (Cacheable)
💡캐시 가능(Cacheable)은 응답 결과를 캐시 해서 재사용해도 되는가에 대한 속성이다.
↳ 캐시 : 한 번 받아온 데이터를 로컬에 저장해 두고 재사용하는 것 -> 네트워크 요청을 줄이고 속도를 높이는데 핵심 역할
예시
✔️첫 번째 방문
→ 서버에서 이미지를 받아옴 (시간 걸림)
→ 브라우저가 이 이미지를 내 로컬 PC에 저장 (캐시)
✔️ 두 번째 방문
→ 서버에 요청할 필요 x
→ 저장된 이미지를 바로 사용(속도 향상)
캐시 가능 메서드
| 메서드 | 캐시 가능 여부 |
| GET | 사용 o |
| HEAD | 사용 o |
| POST | 사용x(이론상 가능) |
| PATCH | 사용x(이론상 가능) |
| PUT | 사용 x |
| DELETE | 사용 x |
POST와 PATCH가 캐싱이 어려운 이유
💡 캐시를 사용하려면 동일한 요청인지 구분하는 키(Key)가 필요하다.
✔️ GET은 URL만 보면 됨
- /members/100 → 항상 같은 리소스
- 캐시 키 = URL
✔️ POST, PATCH는 URL + 바디(본문)까지 봐야 함
→ 같은 URL이라도 바디 내용이 다르면 다른 요청
→ 캐시 키 = URL + 바디 내용(구현이 복잡)
메서드 최종 정리
| 메서드 | 안전 | 멱등 | 캐시 가능 |
| GET | O | O | O |
| POST | X | X | X |
| PUT | X | O | X |
| PATCH | X | X | X |
| DELETE | X | O | X |
'Network' 카테고리의 다른 글
| [Network] - HTTP 상태코드 정리 (0) | 2026.04.03 |
|---|---|
| [Network] - HTTP 메서드 활용과 API 설계 (0) | 2026.04.02 |
| [Network] - HTTP의 기초 이해 (0) | 2026.03.30 |
| [Network] - URI의 이해 (0) | 2026.03.27 |
| [Network] 인터넷 네트워크의 기초 이해 - IP와 TCP,UDP (0) | 2026.03.25 |