[Rails] wrap_parameters

개발을 하다보면 클라이언트에서 요청을 보낼 때 파라미터를 특정 엘리먼트로 래핑해서 보내야하는 경우가 있다(Nested Parameter). 예를 들어 Devise를 사용해서 User모델을 생성했다면, 모든 요청의 파라미터들을 user로 감싸서 보내야한다.

input 태그의 name이 user로 래핑되어있다.

Rails로 서버 개발을 해보면 대부분 Nested parameter로 받는 것이 편하기는 하지만 클라이언트 입장에서 조금 더 번거로워지는 것은 사실이다. 특히 모바일에서 사용할 API를 개발할 땐 특히 더 그렇다.

// Nested parameter
{
"user": {
"email": "example@gmail.com",
"name": "홍길동"
}
}
// Not nested parameter
{
"email": "example@gmail.com",
"name": "홍길동"
}

이런 경우에 wrap_parameters를 사용할 수 있다. wrap_parameters는 클라이언트의 요청이 서버에 전달되기전에 클라이언트와 서버 중간에서 파라미터를 특정 엘리먼트로 래핑해준다. 즉 클라이언트와 서버 모두 각자 편한 방법으로 파라미터를 처리할 수 있다.


컨트롤러 상단에 작성할 수 있으며 어떤 엘리먼트로 감쌀지, 어떤 포맷의 요청에 처리할지 등을 지정할 수 있다.

class RegistrationsController < Devise::RegistrationsController
wrap_parameters :user, format: [:url_encoded_form, :multipart_form, :json]
  ...
end

위 코드는 Devise의 회원가입 컨트롤러이며 클라이언트에서

{"email": "example@gmail.com", "password": "12341234"}

이렇게 요청을 보내면 서버에서는

{"user": {"email": "example@gmail.com", "password": "12341234"}}

Devise에서 요구하는 user로 래핑된 파라미터를 받을 수 있다.


wrap_parameter는 몇 가지 옵션을 제공하는데, 특정 포맷의 요청에만 적용되도록 할 수 있다. 다음은 가장 많이 사용되는 포맷이다.

url_encoded_form : Content-Type: Application/x-www-form-urlencode
multipart_form : Content-Type: multipart/formed-data
json : Content-Type: Application/json

어떤 파라미터를 래핑할 것인지 혹은 어떤 파라미터는 래핑하지 않을 것인지에 대한 옵션도 제공한다.

# whitelist
wrap_parameters :user, format: [:json], include: [:email, :password]
# blacklist
wrap_parameters :user, format: [:json], exclude: [:password_confirmation]

wrap_parameter 메서드는 Devise 뿐만 아니라 다른 곳에도 유용하게 사용할 수 있을 것같다.

공식 문서: http://api.rubyonrails.org/classes/ActionController/ParamsWrapper.html