Tuesday, January 6, 2015

Construindo um CRUD com Spring, REST e Mongo DB parte 2

Passo 2 – Integração entre serviços e interface web

O objetivo do segundo passo é de consumir os serviços criados utilizando AngularJS, um framework Javascript que melhora o HTML estático adicionando atributos e ligando o modelo de dados com as atualizações do servidor. Escolhi AngularJS por ser leve, direto e rápido. Não é tão trivial no início, mas depois de um começo, seu uso se torna intuitivo.

Anteriormente, havia criado alguns serviços que foram chamados pela barra de endereços do browser. Tive que encapsular seus retornos para que formassem um objeto JSON. Isso facilitou a minha camada de visão quando foi chamado pelo AngularJS.

As listagens abaixo mostram os retornos dos serviços em formato JSON:

(1)
Serviço:
/crudpeople/testservice/test

Retorno:
{
 result: "testing"
}


(2)
Serviço:
/crudpeople/testservice/echo/{message}

Retorno:
{
 result: "message"
}

(3)
Serviço:
/crudpeople/testservice/api

Retorno:
{
 result: [
   "/crudpeople/testservice/test",
   "/crudpeople/testservice/echo/{message}",
   "/crudpeople/testservice/api"
 ]
}


Esses serviços vão ser manipulados pelo framework AngularJS, utilizando a linguagem Javascript.

Primeiramente, para começar a utilizar o Angular devemos referenciar o script que está publicado na internet. A tag script referencia a URL https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js para o uso do angular. Depois devemos nosso próprio arquivo de controlador para podermos usar nossa aplicação. Novamente utilizo a tag script, agora para referenciar o meu script services.js.

Meu script, possui alguns elementos referentes ao AngularJS. A primeira linha indica que meu script é um módulo do angular com o nome de serviceTestApp. A listagem abaixo da primeira linha ilustra exatamente isso:

var serviceTestApp = angular.module('serviceTestApp', []);

Agora referencio meu módulo na página, utilizando a notação ng-app na tag html da minha página. O trecho abaixo mostra essa transformação.

html ng-app=”serviceTestApp”

O passo seguinte é construir um controlador para minha aplicação. Construo o controlador chamado TesteController a partir de módulo AngularJS serviceTestApp.

serviceTestApp.controller('TesteController', 
       ['$scope','$http', function($scope, $http) {
    // Insira código aqui
}]);


O trecho acima mostra que criei um controlador chamado TesteController. Ele possui duas variáveis do AngularJS que serão injetadas em sua criação: $scope e $http. $scope conversa com a minha página, transmitindo objetos JSON, Strings e variáveis. Por essa variável, existe uma conversa bidirecional com o meu negócio. Qualquer atualização na página detectada, o $scope é atualizado. $http é meu objeto para comunicação com meus serviços. Posso utilizar os métodos GET, POST, JSONP, por exemplo, para consumir os serviços criados.

Voltando à minha pagina, na tag body, defino que tenho um controlador chamado TesteController e que toda a tramitação de dados será controlada a partir desse escopo. Posso ter um controlador que vai servir a um escopo somente em um div ou span, mas isso seria restringir ao máximo o uso do AngularJS. O trecho abaixo mostra a ligação do controlador com a tag body.

body ng-controller=”TesteController”

Desse modo, o AngularJS está pronto para ser utilizado, ou seja, pronto para ligar a interface gráfica aos serviços implementados.

Do lado do cliente, os serviços são chamados utilizando uma rotina bem parecida. A listagem a seguir mostra esse algoritmo:

    $scope.defaultUrl = "http://localhost:8080/crudpeople/testservice/";

    $scope.test = function() {
        console.log('Calling URL: ' + $scope.defaultUrl + 'test');

        $http.get($scope.defaultUrl + 'test')
            .success(function(data, status) {
                console.log('[OK]');
                $scope.testReturn = {'message' : data.result, 'status': status };
            })
            .error(function(data, status) {
                console.log('[FAIL]');
                $scope.testReturn = {'message' : data, 'status': status };
            });
    };

A rotina define uma variável do controller chamada defaultUrl que contém o caminho padrão para todos os serviços. Desse jeito, basta acrescentar qual o serviço que se deseja acessar.

O método get do objeto $http define duas funções de callback: success que é executado quando tudo ocorre bem e error, quando existe algum problema. Existem outros parâmetros para esses métodos, mas decidi usar somente os dois mais significativos.

Do lado do servidor, quase nada mudou. Agora os métodos retornam um objeto que encapsula as mensagens. No entanto, uma coisa se faz necessária antes de subir o servidor: transformar o retorno em JSON. Os objetos devem possuir uma anotação do framework Jackson que é a @JsonInclude(JsonInclude.Include.NON_NULL). Essa anotação permite que o objeto anotado como @ResponseBody no controller seja transformado em JSON quase que magicamente. O parâmetro JsonInclude.Include.NON_NULL informa ao Jackson que os campos nulos deverão ser ignorados.

A seguir são mostradas as telas de teste dos serviços com os respectivos resultados:




Para acessar o código do projeto no branch do Passo 2, basta baixar o zip no endereço https://github.com/ortolanph/CRUDPeople/tree/passo02.

No comments:

Post a Comment

Let me know your opinion