Controller 작성 가이드

Spring MVC 컨트롤러 작성 패턴 및 URL 설계 규칙

마지막 수정: 2026-05

Controller 작성 가이드

기본 원칙

  • @RestController, @RequiredArgsConstructor, @Slf4j 필수
  • @RequestMapping으로 기본 경로 설정
  • Request: @RequestBody Vo로 JSON Body 수신
  • Response: ResponseJson<Vo> 제네릭으로 반환
  • 컨트롤러는 HTTP 요청/응답만 담당 — 비즈니스 로직 금지

REST API 컨트롤러 기본 구조

@RestController
@RequiredArgsConstructor
@Slf4j
@RequestMapping("/api/user")
public class UserController {

    private final UserService userService;

    /**
     * 사용자 단건 조회
     */
    @PostMapping("/get")
    public ResponseJson<UserVo> get(@RequestBody UserVo vo) {
        UserVo result = userService.get(vo);
        return ResponseJson.success(result);
    }

    /**
     * 사용자 목록 조회
     */
    @PostMapping("/getList")
    public ResponseJson<List<UserVo>> getList(@RequestBody UserVo vo) {
        List<UserVo> list = userService.getList(vo);
        return ResponseJson.success(list);
    }

    /**
     * 사용자 등록
     */
    @PostMapping("/regist")
    public ResponseJson<Void> regist(@RequestBody UserVo vo) {
        userService.regist(vo);
        return ResponseJson.success();
    }

    /**
     * 사용자 수정
     */
    @PostMapping("/update")
    public ResponseJson<Void> update(@RequestBody UserVo vo) {
        userService.update(vo);
        return ResponseJson.success();
    }

    /**
     * 사용자 삭제
     */
    @PostMapping("/delete")
    public ResponseJson<Void> delete(@RequestBody UserVo vo) {
        userService.delete(vo);
        return ResponseJson.success();
    }
}

뷰 컨트롤러 패턴

뷰(HTML 페이지)를 반환하는 컨트롤러는 @Controller를 사용한다.

@Controller
@RequiredArgsConstructor
@Slf4j
public class GuideController {

    private final GuideMenuService guideMenuService;
    private final MarkdownService markdownService;

    @GetMapping("/guide/{section}/{page}")
    public String guidePage(
            @PathVariable String section,
            @PathVariable String page,
            Model model) {

        String slug = section + "/" + page;
        GuideDoc doc = markdownService.getDoc(slug);

        if (doc == null) {
            return "redirect:/guide";
        }

        model.addAttribute("doc", doc);
        model.addAttribute("menus", guideMenuService.getMenus());
        model.addAttribute("currentSlug", slug);

        return "guide/page";
    }
}

URL 설계 규칙

REST API URL은 소문자 케밥케이스를 사용하며, 액션명은 동사 기반으로 구성한다.

POST /api/{업무명}/get            → 단건 조회
POST /api/{업무명}/getList        → 목록 조회
POST /api/{업무명}/getTotalCount  → 전체 수 조회
POST /api/{업무명}/regist         → 등록
POST /api/{업무명}/update         → 수정
POST /api/{업무명}/delete         → 삭제
POST /api/{업무명}/save           → 저장 (등록+수정 통합)

ResponseJson 응답 형식

// 성공 응답 (데이터 있음)
return ResponseJson.success(result);

// 성공 응답 (데이터 없음)
return ResponseJson.success();

// 실패 응답
return ResponseJson.fail("에러 메시지");

응답 JSON 예시:

// 성공
{
    "success": true,
    "data": { ... }
}

// 실패
{
    "success": false,
    "message": "에러 메시지"
}

파라미터 바인딩

// JSON Body 수신 (REST API 기본)
@PostMapping("/get")
public ResponseJson<UserVo> get(@RequestBody UserVo vo) { ... }

// 경로 변수
@GetMapping("/guide/{section}/{page}")
public String page(@PathVariable String section, @PathVariable String page) { ... }

// 요청 파라미터 (기본값 포함)
@GetMapping("/list")
public String list(@RequestParam(defaultValue = "0") int page) { ... }

체크리스트

  • [ ] @RestController, @RequiredArgsConstructor, @Slf4j 선언
  • [ ] @RequestMapping으로 기본 경로 설정
  • [ ] Request: @RequestBody Vo 사용
  • [ ] Response: ResponseJson<Vo> 제네릭 반환
  • [ ] 컨트롤러에 비즈니스 로직 없음
  • [ ] URL이 소문자 케밥케이스