RestTemplate e Media Types

Quando pensamos em integração via REST, geralmente, nos vem na cabeça que vamos trocar dados em XML ou JSON. E em geral, um desses dois, ou até os dois, é o caminho que vai ser seguido. O engraçado é que de vez em quando ficamos tão bitolados nesses formatos, que esquecemos que uma das principais características das integrações via REST é justamente a flexibilidade em relação ao formato dos dados que vão ser trocados.

Na última semana participei de um pequeno projeto aqui dentro da Caelum, o objetivo era que os instrutores pudessem notificar o setor administrativo sempre que alguma coisa faltasse dentro da sala de aula. Para fazer isso, tivemos que realizar uma integração entre esse sistema e um outro que já existe na Caelum, onde está os dados de cadastro de todos os instrutores. Para faciltiar a comunicação sobre o HTTP, usamos a classe RestTemplate, que já vem pronta dentro próprio Spring.

  restTemplate.postForObject("urlParaLogin",new LoginData(login,password), String.class);

Esse seria um jeito padrão de realizar a integração. Criaríamos um DTO que seria serializado como um JSON e enviado para o outro sistema. Só que na outra ponta, o sistema usa o VRaptor como framework e o mesmo usa o XStream como biblioteca de desserialização, enquanto que o Spring usa o Jackson. No mundo ideal não deveria dar problema, só que o XStream exige, pelo menos no modo default, que seja adicionado o nome da classe no inicio do JSON, que também é um formato válido.

 {
  "LoginData": {
   "login": "algumlogin",
   "password": "algumpassword"
  }
 }

Para a nossa infelicidade o Jackson não faz a mesma coisa, e aí o problema estava criado. Caso não seja passado o nome da classe o XStream não consegue transformar o JSON em um objeto do outro lado. Óbvio que podíamos montar o JSON na mão, customizar o XStream ou usar qualquer outra solução dessas. Além disso ainda teríamos que criar a mesma classe no outro sistema, para possibilitar a desserialização. Só que um jeito mais fácil era fazer um post usando o mesmo formato que os formulários nos navegadores usam por default, application/x-www-form-urlencoded.

     RequestEntity<String> request = RequestEntity
		.post(new   URI("urlLogin"))
		.contentType(MediaType.APPLICATION_FORM_URLENCODED)
		.body("login=" + usuarioForm.getLogin() + "&senha=" + usuarioForm.getSenha());
     try {
	 ResponseEntity<String> exchange = restTemplate.exchange(request, String.class);
         ....
     }catch (HttpClientErrorException e) {
	 ...
     }

Pronto, desse jeito não é necessário criar DTO nenhum e o método do controller do VRaptor pode receber os valores como se fosse um post vindo do formulário de um navegador. Você ainda poderia customizar mais e dizer o tipo de retorno que você aceita.

Pelo menos para mim, uma das características que nos fazem programadores melhores é tentar manter o código o mais simples possível. Por mais que o Spring te ofereça um mundo de possibilidades, lembre de primeiro procurar o simples :).

Advertisements

3 thoughts on “RestTemplate e Media Types

  1. Muito bom, Alberto!

    A solução mais simples tende sempre ser a melhor. E adotar form-urlencoded é muitas vez a mais simples quando trabalhamos com sistemas Web na qual temos controle das duas pontas, mas queremos por exemplo modificar somente uma delas; ou não temos controle do outro sistema e temos que simplificar a vida da outra equipe.

    Like

  2. Olá Alberto,

    Entendi o ponto, porém não me faz sentido levando em conta que se você tem uma API feita em VRaptor, por exemplo, ela tem seu contrato (que seja os parametros de in/output), partindo disto, o cliente é quem deveria conhecer e requisitar de acordo, na minha opinião nossa API deve suportar os media types necessários para o negócio, como expor sua API através de JSON, XML e também dados vindos de formulários.

    Like

  3. Oi Leo,

    Na verdade acho que concordamos :). Naquele momento o aplicação onde eu teria que logar os usuários suportava o media type form-url-encoded e, para não precisar mexer nisso, fiz o cliente usar esse media type. O ponto que eu quis levantar foi justamente esse, que ao invés de forçar uma integração via json ou xml, podíamos simplesmente aproveitar o formato de troca já suportado pelo servidor naquele momento.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s