Last Modified 2022.12.28

RESTful URL

REST는 https 환경에서 사용자 세션을 저장하지 않는다.
REST 프로그래밍의 요청 URL은 자원의 위치를 의미하도록 만들어야 한다.
REST 프로그램이 아니더라도, RESTful URL을 따르면 더 좋은 프로그램이 된다.
이 글은 SpringBbs 게시판 프로그램의 요청 URL을 RESTful URL로 바꾸는 방법을 설명한다.

RESTful URL 예: 주소록

주소록 애플리케이션의 RESTful URL은 다음과 같다.

목록:		GET /address
ID가 1인 주소:	GET /address/1 
등록:		POST /address
수정:		PUT /address/1
특정 필드 수정:	PATCH /address/1
삭제:		DELETE /address/1

다음은 현재 게시판의 요청 URL이다. --검색하지 않았다고 가정--

목록:		GET /list?boardCd=chat&page=1&searchWord=
내용보기:		GET /view?boardCd=chat&page=1&searchWord=
새글양식:		GET /write?boardCd=chat&page=1&searchWord=
새글:		POST /write?boardCd=chat&page=1
수정양식:		GET /modify?boardCd=chat&page=1&searchWord=
수정:		POST /modify?boardCd=chat&page=1&searchWord=
삭제:		POST /del?boardCd=chat&page=1&searchWord=

다음은 게시판 요청 URL을 RESTful URL에 부합하도록 수정한 결과다.

목록:		GET /chat?page=1&searchWord=
내용보기:		GET /chat/54?page=1&searchWord=
새글양식:		GET /chat/new?page=1&searchWord=
새글:		POST /chat?page=1
수정양식:		GET /chat/54/edit?page=1&searchWord=
수정:		PUT /chat/54?page=1&searchWord=
삭제:		DELETE /chat/54?page=1&searchWord=

새글양식과 수정양식 요청 URL은 RESTful URL이 아니다.
기존 게시판 프로그램 수정을 최소화하기 위해 이런 타협을 했다.

목록

'/chat?page=1&searchWord='에서 'chat'은 게시판 코드다.
페이지 번호도 URL에 포함해 '/chat/1?searchWord=' 도 된다고 생각할 수 있다.
하지만 페이지 번호를 URL에 포함하지 않아야 한다.
이유는 다음 두 가지다.

첫째, '/chat/1?searchWord=' 에서 1은, 클린 URL 관점에서 보면, 페이지 번호가 아니라 chat 게시판의 첫 번째 글이다. --클린 URL은 RESFful URL과 비슷한 개념이다--

둘째, 검색어가 없다면 '/chat?page=1&searchWord=' 대신 '/chat?page=1'로 요청할 수 있다.
seachWord는 선택적 파라미터다. 선택적 파라미터는 URL에 포함하지 않는다.
page는 searchWord에 따라 값이 바뀐다. 선택적 파라미터에 영향을 받는 파라미터도 URL에 포함하지 않는다.

변경된 요청 URL을 핸들링하도록 게시판 컨트롤러의 목록 메소드 선언을 아래를 참고해 수정한다. --아래 언급된 컨트롤러 메서드의 대부분이 메소드 바디에 수정이 필요하다. 수정이 어렵지 않기에 이에 관한 내용은 생략한다--

@GetMapping("{boardCd}")
public String list(..., @PathVariable String boardCd, ...)

@GetMapping("{boardCd}")에서 {boardCd}는 글자 그대로를 의미하지 않는다.
@PathVariable String boardCd로 선언된 매개변수가 있다면, '/chat?page=1&searchWord=' 요청에서 'chat'은 boardCd 매개변수에 할당된다.

내용보기

'/chat/54?page=1&searchWord=' 에서 54는 게시글의 고유번호다.

변경된 요청 URL을 핸들링하도록 게시판 컨트롤러에서 내용보기 메소드 선언을 아래를 참고해 수정한다.

@GetMapping("{boardCd}/{articleNo}")
public String view (..., @PathVariable String boardCd, @PathVariable Integer articleNo, ...)

'/chat/54?page=1&searchWord=' 요청이 오면, 'chat'은 매개변수 boardCd에 할당되고 54는 매개변수 articleNo에 할당된다.

새글양식

'/chat?page=1&searchWord=' 처럼 수정하면 RESTful URL이 된다.
이 URL을 사용하려면, 목록 페이지가 새글양식을 포함해야 한다.
목록 페이지가 새글양식을 포함하면, 이미 구현된 빈 검증 코드의 수정이 어려워진다.
그래서 새글양식 페이지를 그대로 사용하기로 했다.
RESTful URL이 아니지만, 새글양식 요청 URL을 다음과 같이 정했다.
/chat/new?page=1&searchWord=

@GetMapping("{boardCd}/new")
public String writeForm(@PathVariable String boardCd, ...)

새글

POST /chat?page=1

@PostMapping("{boardCd}")
public String write(..., @PathVariable String boardCd, ...)

수정양식

'/chat/54?page=1&searchWord='이 RESTful URL이다.
이 URL을 사용하려면, 내용보기 페이지가 수정양식을 포함해야 한다.
내용보기 화면에 수정양식이 있으면, 이미 구현한 빈 검증 코드 수정이 어려워진다.
그래서 수정양식 페이지를 그대로 사용하기로 했다.
RESTful URL이 아니지만, 수정양식 요청 URL을 아래와 같이 정했다.
/chat/54/edit?page=1&searchWord=

변경된 URL을 핸들링하도록 게시판 컨트롤러의 수정양식 메소드를 아래를 참고해 수정한다.

@GetMapping("{boardCd}/{articleNo}/edit")
public String modifyForm(..., @PathVariable String boardCd, ...)

수정

PUT /chat/54?page=1&searchWord=

@PutMapping("{boardCd}/{articleNo}")
public String modify(..., @PathVariable String boardCd, @PathVariable Integer articleNo, ...)

삭제

DELETE /chat/54?page=1&searchWord=

변경된 요청 URL을 핸들링하도록 게시판 컨트롤러의 삭제 메소드 선언을 아래를 참고해 수정한다.

@DeleteMapping("{boardCd}/{articleNo}")
public String deleteArticle(@PathVariable String boardCd, @PathVariable Integer articleNo, ...)

JSP 수정

대부분의 JSP에서 수정이 필요하다.
폼 엘리먼트에서 method의 값을 수정한다.
변경된 URL에 맞게 요청 문자열을 만드는 부분을 수정한다.
boardCd와 articleNo가 더는 요청 파라미터로 전달되지 않기에, 이를 고려해 페이지를 수정한다.

관련 글