Get / Post / Put / Delete Mapping
GET /board/list ← 목록
GET /board/view?num=3 ← 상세
GET /board/writeForm ← 작성 폼
POST /board/write ← 작성 처리
GET /board/editForm?num=3 ← 수정 폼
POST /board/update ← 수정 처리
POST /board/delete?num=3 ← 삭제 처리
규칙이 없습니다. URL 만 봐서는 무엇을 하는지 알기 어렵고 — 다른 시스템과 연동할 때 매번 「우리 사이트는 어떻게 짰는가」 설명서를 써야 합니다.
URL 은 「무엇」(boards) 만 표현하고, 「어떤 동작」(조회·생성·수정·삭제) 은 HTTP 메서드로 표현.
| 동작 | 옛 스타일 | RESTful |
|---|---|---|
| 목록 | GET /board/list | GET /api/boards |
| 상세 | GET /board/view?num=3 | GET /api/boards/3 |
| 작성 | POST /board/write | POST /api/boards |
| 수정 | POST /board/update?num=3 | PUT /api/boards/3 |
| 삭제 | POST /board/delete?num=3 | DELETE /api/boards/3 |
| 메서드 | 의미 | Spring 어노테이션 |
|---|---|---|
| GET | 조회 — 데이터 가져오기 | @GetMapping |
| POST | 생성 — 새 데이터 만들기 | @PostMapping |
| PUT | 수정 — 기존 데이터 변경 (전체) | @PutMapping |
| DELETE | 삭제 — 데이터 지우기 | @DeleteMapping |
| PATCH | 부분 수정 | @PatchMapping |
👉 본 과정은 4 개로 충분. PATCH 는 후속 과정.
@RestController
@RequestMapping("/api/boards")
public class BoardApiController {
@GetMapping("/{num}") // GET /api/boards/3
public Board view(@PathVariable int num) {
return service.selectOne(num);
}
@PutMapping("/{num}") // PUT /api/boards/3
public Board update(@PathVariable int num,
@RequestBody Board b) {
b.setNum(num);
return service.update(b);
}
@DeleteMapping("/{num}") // DELETE /api/boards/3
public void delete(@PathVariable int num) {
service.delete(num);
}
}
👉 같은 URL /api/boards/3 에서 메서드만 다르면 다른 처리.
| 메서드 | 안전한가? (데이터 변경 X) | 멱등? (여러 번 = 한 번) |
|---|---|---|
| GET | ✓ | ✓ |
| POST | ✗ | ✗ |
| PUT | ✗ | ✓ |
| DELETE | ✗ | ✓ |
👉 멱등 (idempotent) = 같은 요청을 여러 번 보내도 결과가 같음.
PUT 으로 같은 데이터를 100 번 전송 = 한 번 전송과 결과 같음.
POST 는 100 번 전송 = 글이 100 개 생성.
네트워크가 불안하면 클라이언트가 「응답이 안 와서」 같은 요청을 다시 보낼 수 있습니다.
그래서 「새 데이터 만들기」 만 POST 로 하고, 「특정 데이터 변경」 은 PUT 으로 합니다. 안전성의 차이.
✗ POST /api/createBoard
✓ POST /api/boards
✗ GET /api/getBoard?id=3
✓ GET /api/boards/3
✗ /api/board/3
✓ /api/boards/3 ← 「게시판들 중 3 번」
GET /api/boards/3/replies ← 3 번 글의 댓글들
POST /api/boards/3/replies ← 3 번 글에 댓글 추가
DELETE /api/boards/3/replies/7 ← 3 번 글의 7 번 댓글 삭제
| 메서드 | URL | 동작 |
|---|---|---|
| GET | /api/boards | 게시글 목록 |
| GET | /api/boards/3 | 3 번 게시글 |
| POST | /api/boards | 새 게시글 작성 |
| PUT | /api/boards/3 | 3 번 게시글 수정 |
| DELETE | /api/boards/3 | 3 번 게시글 삭제 |
| GET | /api/boards/3/replies | 3 번 글의 댓글들 |
| POST | /api/boards/3/replies | 3 번 글에 댓글 추가 |
| DELETE | /api/boards/3/replies/7 | 3 번 글의 7 번 댓글 삭제 |
둘 다 「변경」 같지만 용도가 다릅니다:
| POST | PUT |
|---|---|
| 새로 만들기 (id 모름) | 특정 id 의 데이터 변경 |
| /api/boards (id 없음) | /api/boards/3 (id 있음) |
| 서버가 id 부여 | 클라이언트가 id 지정 |
| 멱등 X | 멱등 ✓ |
| 메서드 | 성공 시 | 실패 시 |
|---|---|---|
| GET | 200 OK | 404 Not Found / 401 Unauthorized |
| POST | 201 Created (또는 200) | 400 Bad Request |
| PUT | 200 OK / 204 No Content | 404 / 400 |
| DELETE | 204 No Content | 404 / 403 |
👉 본 과정에서는 기본 200 으로 충분. 상세한 응답 상태 코드 디자인은 후속 과정.
URL: http://localhost:8080/.../api/boards/3
Method: PUT
Headers: Content-Type: application/json
Body: {"title": "수정된 제목", "content": "수정된 내용"}
👉 브라우저 주소창은 GET 만 가능. PUT/DELETE 는 Postman 또는 fetch.
// PUT — F12 Console 에서 실행
await fetch('/api/boards/3', {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({title: '새 제목', content: '새 내용'})
}).then(r => r.json());
// DELETE — F12 Console
await fetch('/api/boards/3', {
method: 'DELETE'
});
👉 Postman 없어도 F12 콘솔에서 즉시 테스트 가능.
HTML 의 <form> 태그는 method="get" 또는 method="post" 만 지원. PUT/DELETE 를 form 으로 직접 보낼 수 없음.
<form method="put"> ... </form> ← 무시되고 GET 으로 처리됨
PUT/DELETE 를 보내려면 — JS 의 fetch 사용. 이게 REST API 가 자연스럽게 비동기와 어울리는 이유.
| 증상 | 원인 |
|---|---|
| 405 Method Not Allowed | 매핑된 메서드와 요청 메서드 불일치 |
| 404 Not Found | URL 오타 / @PathVariable 이름 다름 |
| PUT 으로 보냈는데 처리 안 됨 | HTML form 으로 보냈을 가능성 (form 은 PUT 안 됨) |
| @RequestBody null | Content-Type: application/json 누락 |
| @PathVariable 못 찾음 | URL의 {num} 과 매개변수 이름 불일치 |
★ v8 차시에서 우리는 v6 의 BoardController 를 통째로 BoardApiController 로 옮깁니다. 그때 필요한 것이 오늘 배운:
@GetMapping, @PostMapping 정도만 안다. PUT/DELETE 는 들어본 정도.
RESTful URL 디자인 패턴을 안다. 4 가지 메서드의 멱등성·용도·매핑 어노테이션 모두.
다음: ★ v8 REST 컨트롤러로 변환 — v6 게시판을 통째로 REST 로.