프론트엔드 기초 다시 쌓기 챌린지 22일차.
Part 3 "네트워크 기초"의 두 번째 수업.
어제 HTTP 요청/응답 구조를 배웠다면,
오늘은 요청 라인에 들어가는 메서드가 각각 뭘 하는지,
그리고 이걸 체계적으로 쓰는 REST API 규칙을 배웠다.
"메뉴판 보여주세요" → 조회 (보기만)
"파스타 1개 주문할게요" → 생성 (새로 만들기)
"아까 주문한 거 사이즈 변경" → 수정 (바꾸기)
"아까 주문 취소할게요" → 삭제 (없애기)
HTTP 메서드가 바로 이 행동 종류다.
// 상품 목록 가져오기
fetch('/api/products')
// 특정 상품 가져오기
fetch('/api/products/123')
데이터를 가져올 때 사용. 서버 데이터를 바꾸지 않음. 본문 없음.
// 새 상품 등록
fetch('/api/products', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: '새 티셔츠',
price: 29000
})
})
새 데이터를 만들 때 사용. 본문에 데이터를 담아서 보냄.
// 123번 상품 수정
fetch('/api/products/123', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: '수정된 티셔츠',
price: 25000
})
})
기존 데이터를 수정할 때 사용. 전체 데이터를 보냄.
// 123번 상품 삭제
fetch('/api/products/123', {
method: 'DELETE'
})
데이터를 삭제할 때 사용. 보통 본문 없이 URL에 ID만.
| 메서드 | 행동 | 본문 | 예시 |
|---|---|---|---|
| GET | 조회 | 없음 | 상품 목록 보기 |
| POST | 생성 | 있음 | 새 상품 등록 |
| PUT | 수정 | 있음 | 상품 정보 변경 |
| DELETE | 삭제 | 없음 | 상품 삭제 |
외우는 법: CRUD
Create → POST (생성)
Read → GET (조회)
Update → PUT (수정)
Delete → DELETE (삭제)
거의 모든 웹 서비스가 이 4가지 동작으로 이루어져 있다.
실무에서 PATCH라는 메서드도 자주 보인다.
PUT: 전체를 교체한다
PATCH: 일부만 수정한다
// PUT: 전체 정보를 다 보내야 함
fetch('/api/products/123', {
method: 'PUT',
body: JSON.stringify({
name: '수정된 티셔츠',
price: 25000,
description: '면 100%',
category: '상의'
})
})
// PATCH: 바꿀 부분만 보내면 됨
fetch('/api/products/123', {
method: 'PATCH',
body: JSON.stringify({
price: 25000 // 가격만 변경!
})
})
실무에서는 PUT과 PATCH를 엄격하게 구분하지 않는 팀도 많다.
"둘 다 수정, PATCH가 부분 수정" 정도만 알면 된다.
REST API = HTTP 메서드 + URL을 체계적으로 설계하는 규칙
GET /getProducts
GET /getProductById?id=123
POST /createNewProduct
POST /updateProduct
GET /deleteProduct?id=123 ← CSRF 공격에 취약!
문제점: URL에 동사가 들어가고, 메서드를 제대로 안 쓰고, 일관성 없음.
GET /api/products → 상품 목록 조회
GET /api/products/123 → 123번 상품 조회
POST /api/products → 새 상품 등록
PUT /api/products/123 → 123번 상품 수정
DELETE /api/products/123 → 123번 상품 삭제
1. URL은 "명사"로 (무엇을) → /products, /users, /orders
2. 메서드는 "동사"로 (어떤 행동을) → GET, POST, PUT, DELETE
3. URL에 동사를 넣지 않는다
메서드가 이미 동사 역할을 하기 때문에 중복이다.
DELETE /api/products/123
DELETE = "삭제해" (동사)
/api/products/123 = "123번 상품을" (명사)
→ "123번 상품을 삭제해" — 완벽한 문장!
URL에 동사를 넣으면:
DELETE /api/products/delete/123
→ "123번 상품을 삭제를 삭제해" — 중복!
그리고 동사를 넣기 시작하면 일관성이 깨진다:
❌ 사람마다 다른 단어: delete? remove? destroy?
✅ REST: URL은 항상 같고, 메서드만 다름 → 깔끔!
// pages/api/products/index.js
export default function handler(req, res) {
if (req.method === 'GET') {
// 상품 목록 조회
res.json({ products: [...] });
}
if (req.method === 'POST') {
// 새 상품 등록
const newProduct = req.body;
res.status(201).json({ product: newProduct });
}
}
// pages/api/products/[id].js
export default function handler(req, res) {
const { id } = req.query;
if (req.method === 'GET') {
// 특정 상품 조회
}
if (req.method === 'PUT') {
// 상품 수정
}
if (req.method === 'DELETE') {
// 상품 삭제
}
}
하나의 URL에 메서드로 행동을 구분하는 것이 REST의 핵심이다.
REST를 지키면 자연스럽게 CSRF 방어가 된다.
❌ GET /api/products/delete?id=123
→ <img src="/api/products/delete?id=123"> 로 공격 가능!
✅ DELETE /api/products/123
→ <img> 태그로는 DELETE 요청을 못 보냄 → 안전!
[사용자 관련]
GET /api/users → 사용자 목록
GET /api/users/123 → 사용자 정보
POST /api/users → 회원가입
PUT /api/users/123 → 정보 수정
DELETE /api/users/123 → 회원 탈퇴
[주문 관련]
GET /api/orders → 주문 목록
POST /api/orders → 새 주문 생성
PATCH /api/orders/456 → 주문 상태 변경
DELETE /api/orders/456 → 주문 취소
[중첩 관계]
GET /api/users/123/orders → 123번 사용자의 주문 목록
GET /api/products/789/reviews → 789번 상품의 리뷰 목록
URL만 봐도 뭘 하는지 바로 이해할 수 있다. 이게 REST의 힘.
| 레스토랑 | 서버 |
|---|---|
| "메뉴판 보여주세요" | GET (조회) |
| "파스타 주문할게요" | POST (생성) |
| "전체 주문 변경이요" | PUT (전체 수정) |
| "파스타만 크림으로요" | PATCH (부분 수정) |
| "주문 취소요" | DELETE (삭제) |
| 행동과 대상을 분리한 주문서 | REST API |
| CRUD | Create(POST), Read(GET), Update(PUT), Delete(DELETE) |
Q1. REST 방식으로 상품 API를 설계하면?
→ 정답:
POST /api/products (등록),
PUT /api/products/123 (수정),
DELETE /api/products/123 (삭제)
URL에 create, edit, delete 같은 동사를 넣지 않는다!
Q2. URL에 동사를 넣으면 안 되는 이유는?
→ 정답: 메서드(GET/POST/PUT/DELETE)가 이미 동사 역할을 하고 있어서 중복이다. 또한 사람마다 다른 단어(delete/remove/destroy)를 써서 일관성이 깨진다.
Q3. GET과 POST가 같은 URL인데 서버가 구분하는 방법은?
→ 정답: HTTP 메서드(req.method)로 구분한다. URL이 같아도 메서드가 다르면 완전히 다른 동작.
fetch()를 쓸 때 method: 'POST'를 매번 적으면서도
이게 왜 POST인지, GET과 뭐가 다른지 깊이 생각해본 적이 없었다.
오늘 배우고 나니 CRUD(Create, Read, Update, Delete)가
웹 서비스의 거의 모든 동작이라는 게 와닿았다.
쇼핑몰이든, SNS든, 블로그든 결국 데이터를 만들고, 읽고, 수정하고, 삭제하는 것.
특히 REST API에서 "URL은 명사, 메서드는 동사"라는 규칙이 인상적이었다.
처음에 테스트 답변에서 /product/create, /product/delete라고 적었는데,
메서드가 이미 동사니까 URL에 또 동사를 넣으면 "삭제를 삭제해"가 된다는 설명이 확 와닿았다.
Day 19에서 배운 CSRF와도 연결된다.
REST를 지켜서 삭제를 DELETE로 만들면 img 태그로 공격이 안 된다.
규칙을 지키면 자연스럽게 보안이 좋아지는 것.
Day 23: HTTP 상태 코드 심화 (200, 301, 400, 401, 403, 404, 500)
서버가 "성공!", "못 찾겠어요", "권한 없어요"를 숫자로 말하는 법.
200은 알겠는데 301, 401, 403의 차이는?
#프론트엔드 #HTTP #REST #API #CRUD #네트워크 #2년차개발자 #기초다시쌓기