2010년 6월 21일 월요일

RESTful 서비스의 파라미터 바인딩

RESTful 클라이언트로부터 요청을 받게 될 경우 서버측 엔드포인트에서는 클라이언트가 전달한 파라미터에 대한 값을 파싱해야 한다.

RESTful에서 사용할 수 있는 파라미터 javax.ws.rs 패키지 내에 정의되어 있으며 아래와 같다.
- CookieParam (쿠키 값의 name=value)
- FormParam (Form의 name=value)
- HeaderParam (Http Header의 name=value)
- MatrixParam (뭥미?)
- PathParam (URI의 토큰 eg. getUser/{uid})
- QueryParam (Request Query의 name=value eg. getUser?uid=1234)

또한 웹서비스에서 정의되어 있는 파라미터도 있다.
- javax.jws.WebParam (Http Request Body에 XML 또는 json 등으로 객체에 대한 데이터를 전달)

위의 파라미터 중에 WebParam을 제외하고는 모두 name=value 형태로 데이터가 전달되어 진다.
따라서 신규 데이터 추가나 변경등과 같이 다수의 파라미터가 전달되는 경우에는 각 파라미터의 name, value pair를 전달하려면 메서드의 파라미터가 많아지기 때문에 편의상의 이유로 WebParam으로 전달받도록 서비스를 개발하는데, 이로 인해 클라이언트에서 대상 객체에 대한 메시지 포맷을 생성한 후 서비스를 요청해야 하는 부담이 있다. 예를 들면 사용자 추가 서비스를 호출하기 위해서 아래와 같이 HTTP Request Body를 구성해야 한다.
<user>
<userId>xxx</userId>
<userName>Kim</userName>
<password>zzz</password>
...
</user>

이는 서비스 Consumer 입장에서는 적지 않은 부담일 뿐만 아니라 content type 변경(xml에서 json으로 또는 vice versa)하기로 결정했다면 또다시 xml을 json구문으로 변경해야 할 경우도 발생한다.

따라서 RESTful로 서비스를 개발할 경우에 클라이언트 부담도 줄이고, 서비스 메서드의 파라미터도 간단하게 개발할 수 있는 방법이 있다면 굳이 WebParam을 사용할 필요는 없다.

아래의 내용은 QueryParam, PathParam, FormParam(CookieParam, HeaderParam도 가능함)을 이용해서 객체로 바인딩하는 방법을 기술해 놓은 것이다. 파라미터 처리 방식은 유사하기 때문에 POST방식의 FormParam으로 샘플코드를 작성한다.

1. WebParam을 이용하는 경우
- WebParam으로 전달되는 객체는 XmlRootElement 어노테이션으로 정의가 되어 있어야 한다.

@POST
@Path("/insertUser")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
boolean insertUser(@WebParam("user") User user) throws Exception;


2. FormParam을 이용하는 경우
- User 객체에 포함되어야 하는 모든 파라미터를 FormParam으로 전달되어야 한다.
@POST
@Path("/insertUser")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
boolean insertUser(@FormParam("userId") String userId, @FormParam("password") String password) throws Exception;

3. FormParam의 바인딩을 이용하는 경우
- User 객체의 프로퍼티가 Form Param으로 전달되는 파라미터와 동일한 이름인 경우에는 바인딩된다.
- XmlRootElement 어노테이션을 사용할 필요가 없다(XmlBinding을 사용하지 않기 때문에 jaxb 어노테이션은 필요치 않다.)
- FormParam의 이름을 빈문자열 ("")으로 설정해 주어야 한다.
@POST
@Path("/insertUser")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
boolean insertUser(@FormParam("") User user) throws Exception;

위의 방법 중에서 3번 FormParam의 바인딩을 이용하는 것이 RESTful 서비스의 클라이언트와 서버 모두에게 가장 편리한 개발 방법을 제공하므로 RESTful에서는 WebParam을 사용하지 않도록 서비스를 설계해야 한다.

댓글 없음:

댓글 쓰기