9osari.log
← 목록으로

[DevBid - HTTP] Form 환경에서 RESTful 설계

2025년 10월 19일 · #devbid#web#http#refactor#myproject

리팩터링 계기

개인 프로젝트를 만들면서 URL을 대충 /products_main, /product/new 이런 식으로 만들었는데, 김영한 선생님의 HTTP 강의를 들으면서 “아, 내 URL 설계가 엉망이구나”를 깨닳았다.

특히 RESTful 원칙을 배우면서

내 코드를 다시 보니… 리소스도 뒤죽박죽, 메서드도 일관성이 없었다.

REST => 자원을 이름으로 구분하여 해당 자원의 상태를 주고받는 모든 것을 의미

REST 구성 요소

기존 코드의 문제점

상품 컨트롤러

@GetMapping("/productMain")
public String productMain() { ... }

@GetMapping("/product/new")
public String newProduct(...) { ... }

@PostMapping("/product/new")
public String createProduct(...) { ... }

@PutMapping("/product/{id}")
public String updateProduct(...) { ... }

@DeleteMapping("/product/{id}")
public String deleteProduct(...) { ... }

문제점:

사용자 컨트롤러

@GetMapping("/users/new")
public String register(...) { ... }

@PostMapping("/users")
public String registerUser(...) { ... }

@PutMapping("/users/{id}")
public String updateUser(...) { ... }

@DeleteMapping("/users/{id}")
public String deleteUser(...) { ... }

문제점:

리팩토링 원칙


리팩토링 결과

상품 컨트롤러

// 목록 조회
@GetMapping("/products")
public String productList(Model model) {
    model.addAttribute("products", productService.findAllWithImages());
    return "products/productList";
}

// 등록 폼
@GetMapping("/products/new")
public String newProduct(@AuthenticationPrincipal AuthUser authUser, Model model) {
    return "products/new";
}

// 등록 처리
@PostMapping("/products")
public String createProduct(ProductRegistrationRequest request, ...) {
    return "redirect:/products/success";
}

// 수정 폼
@GetMapping("/products/{id}/edit")
public String editProduct(@PathVariable Long id, Model model) {
    return "products/edit";
}

// 수정 처리
@PostMapping("/products/{id}/edit")
public String updateProduct(@PathVariable Long id, ...) {
    return "redirect:/products/my";
}

// 삭제 처리
@PostMapping("/products/{id}/delete")
public String deleteProduct(@PathVariable Long id, ...) {
    return "redirect:/products/my";
}

사용자 컨트롤러

// 사용자 목록
@GetMapping("/users")
public String userList(Model model) {
    model.addAttribute("users", userService.findAllUsers());
    return "users/userList";
}

// 등록 폼
@GetMapping("/users/new")
public String register(Model model) {
    return "users/new";
}

// 등록 처리
@PostMapping("/users/new")
public String registerUser(@Valid @ModelAttribute("user") UserRegistrationRequest request, ...) {
    userService.registerUser(request);
    return "redirect:/userSuccess";
}

// 수정 폼
@GetMapping("/users/{id}/edit")
public String userUpdate(@PathVariable Long id, Model model) {
    return "users/edit";
}

// 수정 처리
@PostMapping("/users/{id}/edit")
public String userUpdateProc(@PathVariable Long id, ...) {
    userService.updateUser(id, request);
    return "redirect:/users";
}

// 삭제 처리
@PostMapping("/users/{id}/delete")
public String userDelete(@PathVariable Long id, ...) {
    userService.deleteUser(id);
    return "redirect:/";
}

주요 개선 사항

1. URL 복수형 통일

2. HTML Form 제약 대응

3. 뷰 경로 구조 정리

4. 의미 중심 URL 설계


배운 점

작은 개선이지만 프로젝트의 유지보수성과 가독성이 크게 향상되었습니다. 좋은 설계 원칙을 배우고 적용해보는 것의 중요성을 다시 한번 느꼈습니다.


참고

···
← PREV [JPA] JPQL과 페치 조인 NEXT → [DevBid - JPA] 카테고리 트리 N+1 최적화