Conteúdo


Desenvolva um aplicativo de rastreamento de despesa híbrido

Use StrongLoop para compor APIs REST e conectar-se a um banco de dados Cloudant no IBM Cloud

Comments

Ao construir um aplicativo REST, é possível aprimorar sua produtividade se você usar uma ferramenta para composição da API e conexão de dados. Desta maneira, é possível focar seus esforços mais na lógica de negócios do aplicativo e na experiência do usuário.

Neste tutorial, você cria um aplicativo de serviço para aprender como usar ferramentas de desenvolvimento da API a partir de StrongLoop (uma empresa IBM® ). Com a estrutura LoopBack de software livre (a qual é construída sobre o Node.js), é possível desenvolver facilmente APIs REST escaláveis visualmente e conectar-se aos dados necessários para o aplicativo. StrongLoop Arc, o qual complementa as ferramentas de linha de comandos slc do StrongLoop, inclui ferramentas para construção, criação de perfil e monitoramento de aplicativos Node.js.

Seu exercício é construir um aplicativo de rastreamento de despesa híbrido simples que consome APIs REST que você desenvolve com o StrongLoop. As APIs REST usam o serviço Cloudant NoSQL DB no IBM Cloud® para integração de dados. Você cria um aplicativo do servidor localmente para expor a API REST. Para desenvolver o lado do cliente do aplicativo híbrido, use o LoopBack Angular JavaScript SDK (um dos vários SDKs que LoopBack inclui) e a estrutura do Ionic . Como uma etapa final, implemente o código do lado do servidor do aplicativo no IBM Cloud.

Com o aplicativo ExpenseTracker, usuários registram suas despesas diárias por categorias. O cliente gera um relatório das despesas e apresenta o relatório em formato de gráfico. Você estende a API para que o cliente possa exibir gráficos que são baseados em uma categoria ou mês específico.

O que será necessário para desenvolver o aplicativo

Execute o aplicativo do servidorObtenha o código

Com a estrutura LoopBack de software livre, é possível desenvolver facilmente APIs REST escaláveis visualmente e conectar-se aos dados de que o aplicativo precisa.

Etapa 1. Crie um aplicativo IBM Cloud

  1. Efetue login no IBM Cloud.
  2. Clique em CRIAR APLICATIVO.
  3. Selecione WEB como o tipo de aplicativo.
  4. Selecione O tempo de execução do SDK para Node.js: Screenshot of the SDK for Node.js icon in the IBM Cloud catalog
  5. Clique em CONTINUAR.
  6. Insira ExpenseTracker com um identificador exclusivo (tal como seu nome de usuário ou a data) anexado a ele. (O IBM Cloud o informará se o nome que está tentando usar estiver indisponível.)
  7. Clique em CONCLUIR.

Ligue o serviço Cloudant NoSQL DB ao seu aplicativo

  1. Quando seu aplicativo concluir a preparação, retorne ao painel do IBM Cloud e clique no nome do aplicativo para acessar a página de visão geral do aplicativo.
  2. Clique no botão INCLUIR UM SERVIÇO OU API .
  3. Na seção Dados e Analytics do catálogo, selecione Cloudant NoSQL DB.
  4. Clique em CRIAR para incluir o serviço Cloudant no aplicativo.
  5. Remonte o aplicativo quando avisado.
  6. Retorne à página de visão geral do aplicativo para confirmar que o serviço Cloudant NoSQL DB agora está ligado ao aplicativo.

Crie o banco de dados para o aplicativo ExpenseTracker

  1. Na página de visão geral do aplicativo, clique no serviço Cloudant NoSQL DB para exibir os detalhes.
  2. Clique no botão ATIVAR para ativar o painel do Cloudant NoSQL Database.
  3. Clique no link Criar Banco de Dados na parte superior direita. Quando for solicitado um nome de banco de dados, insira expense-tracker e clique em Criar.

Etapa 2. Implemente o lado do servidor em seu ambiente de desenvolvimento local

Nesta etapa, você implementa um aplicativo do lado do servidor que usa a estrutura LoopBack para expor as APIs REST para incluir informações de despesa.

Crie um novo aplicativo do lado do servidor

  1. Em sua linha de comandos do S.O., a partir de um diretório no qual você deseja colocar o novo aplicativo, digite slc loopback e pressione Enter.
  2. Digite ExpenseTracker como o nome do aplicativo e pressione Enter.
  3. Pressione Enter para aceitar o nome padrão (ExpenseTracker) do diretório do projeto.

O código do lado do servidor é gerado na pasta ExpenseTracker/server.

Inclua o conector Cloudant no aplicativo

O aplicativo ExpenseTracker usa Cloudant NoSQL DB para armazenamento de dados. Como o Cloudant é um derivado de CouchDB, use o conector LoopBack CouchDB para o aplicativo:

  1. Na linha de comandos do S.O., mude para o diretório ExpenseTracker.
  2. Execute o comando a seguir para instalar o conector LoopBack Couch:

    npm install loopback-connector-couch

Inclua Cloudant como o banco de dados para o aplicativo

Configure o aplicativo ExpenseTracker para conectar-se ao serviço Cloudant NoSQL DB no IBM Cloud que você criou na Etapa 1:

  1. Na página de visão geral no IBM Cloud para seu aplicativo expense-tracker, clique em Mostrar Credenciais no serviço Cloudant NoSQL DB: Screenshot of Cloudant credentials
    Screenshot of Cloudant credentials
  2. Em um editor de texto, abra seu arquivo server/datasources.json do projeto local e inclua os detalhes para o banco de dados Cloudant:
    "cloudant": {
      "host": "yourhost-bluemix.cloudant.com",
      "port": 443,
      "url": "https://yourhost-bluemix.cloudant.com",
      "name": "cloudant",
      "connector": "couch",
      "db": "expense-tracker",
      "protocol": "https",
      "auth": {
        "admin": {
          "username": "cloudant-admin-username",
          "password": "cloudant-admin-password"
        },
        "reader": {
          "username": "cloudant-reader-username",
          "password": "cloudant-reader-password"
        },
        "writer": {
          "username": "cloudant-writer-username",
          "password": "cloudant-writer-password"
        }
      }
    }

Configure o modelo de dados do aplicativo

O aplicativo ExpenseTracker usa um modelo de dados simples. A configuração do modelo de dados na estrutura LoopBack também pode expor a API REST:

  1. Em sua linha de comandos do S.O., mude para o diretório ExpenseTracker e insira:

    slc loopback:model

  2. Forneça os detalhes a seguir em resposta ao prompt:
    • Nome do modelo: despesa
    • Origem de dados a ser anexada: cloudant
    • Classe base do modelo: PersistedModel
    • Expor como API REST: Sim
    • Formulário de plural: despesas
  3. Pressione Enter para sair do processo de criação de modelo.

Agora, configure as propriedades de modelo (category, item, price e expensedate):

  1. Para cada propriedade, execute o comando slc loopback:property e forneça os detalhes para essa propriedade nos prompts:
    PropriedadeModeloNome da propriedadeTipo de propriedadeObrigatório
    categorydespesacategorystringsim
    itemdespesaitemstringsim
    pricedespesapriceiOSsim
    expensedatedespesaexpensedatedatesim

Como alternativa, é possível usar o Arc Composer para incluir propriedades.

Interaja com os dados

A estrutura LoopBack gera automaticamente os terminais REST para todos os objetos de seu modelo de dados. Ela também gera a documentação da API Swagger adequadamente, fornecendo uma interface conveniente para seus dados.

  1. Em sua linha de comandos do S.O., mude para o diretório ExpenseTracker.
  2. Execute o comando node para iniciar o aplicativo ExpenseTracker.
  3. Em um navegador, acesse http://localhost:3000/explorer para abrir a documentação da API Swagger do aplicativo ExpenseTracker no StrongLoop API Explorer: Screenshot of the API Explorer
    Screenshot of the API Explorer
  4. Clique em Listar Operações para exibir todas as operações possíveis, as quais são expostas como métodos REST. Usando o API Explorer, é possível interagir com o modelo e testar os serviços.

Estenda a interação do modelo

É possível estender a implementação do modelo modificando o arquivo expense.js na pasta common/models do aplicativo. O conteúdo do arquivo padrão consiste em:

module.exports = function(Expense) {};

Para tornar possível para o ExpenseTracker recuperar as despesas com base na categoria ou mês, customize o modelo incluindo um método e expondo esse modelo como uma API REST para o cliente consumir. Em um editor de texto, abra o arquivo common/models/expense.js e substitua seu conteúdo pelo código a seguir:

module.exports = function(Expense) {
//Method to get the category based expenses for the month.
Expense.getMonthlyCategoryBasedAnalysis = function(cb)
{
    ONE_MONTH = 30 * 24 * 60 * 60 * 1000;  // Month in milliseconds
    var lastDate = new Date(Date.now() - ONE_MONTH);
    var result = "";
    var jsonArr = [];
    Expense.find( { expensedate: {gt: lastDate} },
    function (err, instance)
    {
        var tempArr = [0, 0, 0, 0];
        for (var i=0;i<instance.length;i++)
        {
            if(instance[i].expensedate > lastDate)
            {
                if(instance[i].category == "Food")
                    tempArr[0] = tempArr[0] + instance[i].price;
                else if (instance[i].category == "Travel")
                    tempArr[1] = tempArr[1] + instance[i].price;
                else if (instance[i].category == "Education")
                    tempArr[2] = tempArr[2] + instance[i].price;
                else if (instance[i].category == "Miscellaneous")
                    tempArr[3] = tempArr[3] + instance[i].price;
            }
        }
        for (var i = 0; i < tempArr.length; i++) {
            var cat = "";
            if(i == 0) cat = "Food";
            if(i == 1) cat = "Travel";
            if(i == 2) cat = "Education";
            if(i == 3) cat = "Miscellaneous";
            //create the JSON for the client to consume
            jsonArr.push({
                "category": cat,
                      "period": "LastMonth",
                "price": tempArr[i]
            });
        }
        console.log("out is "+jsonArr);
        response = jsonArr ;

      cb(null, response);
    });
}
//Expose the method as a REST API
Expense.remoteMethod ('getMonthlyCategoryBasedAnalysis',{
      http: {path: '/getMonthlyCategoryBasedAnalysis', verb: 'get'},
      //accepts: {arg: 'categoryName', type: 'string', http: { source: 'query' } },
      returns: {arg: 'data', type: 'string'}
    }
);
};

O código precedente usa o método find para recuperar despesas baseadas em categoria para o mês anterior e, em seguida, organiza os dados por categorias. getMonthlyCategoryBasedAnalysis é exposto como um método remoto para o cliente.

Etapa 3. Implemente o lado do cliente em seu ambiente de desenvolvimento local

O aplicativo híbrido que você está construindo usa a estrutura Ionic e o AngularJS SDK da estrutura LoopBack para o frontend.

Crie o aplicativo Ionic

Crie o aplicativo do cliente como um aplicativo Ionic:

  1. Em sua linha de comandos do S.O., acesse o diretório ExpenseTracker e execute o comando a seguir para fazer download do modelo de aplicativo (deve-se estar conectado à Internet):

    ionic start client tabs

  2. Quando for solicitado sobrescrever a pasta, selecione sim.

Gere serviços Angular

A estrutura LoopBack suporta um AngularJS SDK. A estrutura Ionic usa a biblioteca do cliente Angular para chamar as APIs REST. Para gerar a biblioteca do cliente Angular para seu aplicativo LoopBack, use a ferramenta de linha de comando LoopBack Angular:

  1. Mude para o diretório ExpenseTracker/client.
  2. Execute o seguinte comando:

    lb-ng ../server/server.js www/js/lb-services.js

    No comando precedente, ../server/server.js é o caminho relativo ao script de servidor LoopBack principal e www/js/lb-services.js é o nome e caminho para o arquivo que a ferramenta gera.
  3. Abra o arquivo client/www/js/lb-services.js para visualizar o código que a ferramenta gerou. Modifique a variável urlBase existente para que ela possa chamar a implementação do lado do servidor (esta mudança é usada somente para teste local):
    var urlBase = "http://localhost:3000/api";

Inclua o módulo ng-resource no aplicativo

Inclua o módulo ng-resource em seu aplicativo cliente para que o aplicativo possa chamar a API REST:

  1. A partir do diretório cliente de seu aplicativo, execute:

    bower install angular-resource

    Se solicitado, selecione a versão mais recente. Este comando inclui a biblioteca necessária na pasta client/www/lib. (Como alternativa, é possível fazer download da biblioteca a partir de uma das versões de AngularJS.
  2. Inclua o JavaScript relacionado a angular-resource no arquivo client/www/index.html, na seção <head> :

    <script src="lib/angular-resource/angular-resource.js"></script>

Implemente a entrada de despesas

O aplicativo requer entrada baseada em formulário que chama a API REST, de forma que os usuários possam inserir despesas. Faça as mudanças a seguir nos modelos controller.js, app.js e index.html:

  1. Modifique a declaração do módulo em client/www/js/app.js para incluir o arquivo lbservices.js, mudando a linha que diz:
    angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])

    para:
    angular.module('starter', ['lbServices','ionic', 'starter.controllers'])
  2. Em client/www/js/app.js, mude o bloco que inicia com .config(function($stateProvider, $urlRouterProvider) para:
    .config(function($stateProvider, $urlRouterProvider) {
      $stateProvider
        .state('tab', {
        url: '/tab',
        abstract: true,
        templateUrl: 'templates/tabs.html'
      })
      .state('tab.addexpense', {
        url: '/addexpense',
        views: {
          'tab-addexpense': {
            templateUrl: 'templates/tab-addexpense.html',
            controller: 'ExpenseController'
          }
        }
      })
    //This is required for the below step to display charts
      .state('tab.charts', {
        url: '/charts',
        views: {
          'tab-charts': {
            templateUrl: 'templates/tab-charts.html',
            controller: 'ExpenseController'
          }
    
        }
      });
    
      // if none of the above states are matched, use this as the fallback
      $urlRouterProvider.otherwise('/tab/addexpense');
    });
  3. Abra o arquivo client/www/templates/tabs.html e modifique <ion-tab> para a guia Painel para que seja:
    <!-- Add Expense Tab--><ion-tab title="Add Expense" icon-off="ion-ios-plus-outline"
    icon-on="ion-ios-plus" href="#/tab/addexpense">
    <ion-nav-view name="tab-addexpense"></ion-nav-view> </ion-tab>
  4. Mude o nome do arquivo client/www/templates/tab-dash.html para tab-addexpense.html. Substitua o conteúdo do arquivo pelo código a seguir:
    <ion-view view-title="Add Expense">
      <ion-content padding="true" class="has-header" scroll="false" overflow-scroll="false">
        <div>
          <br>
          <form name="expensesForm" ng-submit="addExpense()">
          <div class="list">
            <label class="item item-input">
              <span class="input-label">Category</span>
              <select class="form-control focus"
                  name="category" required ng-model="newExpense.category">
                  <option name="Food" id="Food">Food</option>
                  <option name="Travel" id="Travel">Travel</option>
                  <option name="Miscellaneous" id="Cosmetics">Miscellaneous</option>
                  <option name="Education" id="Education">Education</option>
                </select>
            </label>
            <label class="item item-input">
              <span class="input-label">Item</span>
                  <input type="text" class="form-control" name="item" placeholder="Expense Item Name"
                      autocomplete="off" required ng-model="newExpense.item">
            </label>
            <label class="item item-input">
              <span class="input-label">Price</span>
                  <input type="text" class="form-control" name="price" placeholder="Expense Price"
                      autocomplete="off" required ng-model="newExpense.price">
                   <input type="hidden" class="form-control" name="date" placeholder="Date" 
                       autocomplete="off" required ng-model="newExpense.expensedate">
           </label>
         </div>
               <br>
           <button class="btn btn-default" ng-disabled="expensesForm.$invalid">Add Expense</button>
         </form>
       </div>
     </ion-content>
    </ion-view>
  5. Inclua a chamada de API REST Incluir Despesa no arquivo client/www/js/controllers.js. Inclua também as tags ExpenseController no controlador:
    .controller('ExpenseController',
             [ '$scope','$rootScope', 'Expense', function($scope, $rootScope, Expense) {
        $scope.newExpense = {};
        $scope.newExpense.category = 'Food';
        $scope.newExpense.expensedate = new Date();
        //Method call to create the expense record
        $scope.addExpense = function()
        {
            Expense.create($scope.newExpense).$promise.then(function(expense)
            {
                $scope.newExpense = {};
                $scope.newExpense.category = 'Food';
    
            });
        };
    }])

Inclua a API REST customizada em lb-services.js

Para o aplicativo consumir a API REST customizada que você incluiu na Etapa 2, deve-se modificar o arquivo lb-services.js:

  1. Abra client/www/js/lb-services.js.
  2. Procure a declaração do método findOne , a qual está sob a declaração de modelo Despesa .
  3. Imediatamente após o método findOne , inclua o código a seguir para o método customizado que você declarou no arquivo expense.js na Etapa 2:
    "getMonthlyCategoryBasedAnalysis": {
         url: urlBase + "/expenses/getMonthlyCategoryBasedAnalysis",
         method: "GET"
       },

Inclua o módulo angular-chart no aplicativo

Para exibir o gráfico no aplicativo para a despesa mensal baseada em categoria, inclua o módulo angular-chart :

  1. Em sua linha de comandos do S.O., mude para o diretório do cliente.
  2. Para incluir a biblioteca necessária na pasta client/www/lib, execute:

    bower install angular-chart.js

    Como alternativa, é possível fazer download da biblioteca a partir do site do projeto.
  3. Inclua o Angular SDK no arquivo client/www/index.html, na seção <head> :
    <script src="js/lb-services.js"></script>
  4. Inclua o terminal angular-chart JavaScript relacionado ao arquivo client/www/index.html, no <head> :
    <script src="lib/Chart.js/Chart.min.js"></script>
    <script src="lib/angular-chart.js/dist/angular-chart.js"></script>
  5. Inclua o código CSS relacionado ao angular-chart no arquivo index.html, na seção <head> :
    <link rel="stylesheet" href="lib/angular-chart.js/dist/angular-chart.css">
  6. Inclua o módulo chart no aplicativo incluindo chart.js na declaração do módulo:
    angular.module('starter', ['lbServices','ionic', 'chart.js','starter.controllers'])
  7. Inclua chart.js na primeira linha de controllers.js:
    angular.module('starter.controllers', ['chart.js'])

Inclua um gráfico baseado em categoria mensal

Para recuperar as despesas baseadas em categoria mensais, deve-se chamar o método getMonthlyCategoryBasedAnalysis :

  1. Abra o arquivo client/www/templates/tabs.html e mude <ion-tab> para a guia Bate-papos para:
     <!-- Charts Tab -->
     <ion-tab title="Charts" icon-off="ion-load-d" icon-on="ion-load-b" href="#/tab/charts">
        <ion-nav-view name="tab-charts"></ion-nav-view>
     </ion-tab>
  2. Remova ou comente a guia Conta no arquivo client/www/templates/tabs.html.
  3. Renomeie o client/www/templates/tab-chats.html para tab-charts.html.
  4. Inclua o código a seguir no arquivo tab-charts.html:
    <ion-view view-title="Charts" ng-init="drawCategoryMonthlyChart()">
      <ion-content>
            <canvas id="bar" class="chart chart-bar" chart-data="data" chart-series="series"
                chart-labels="labels" responsive="false" height="100" chart-legend="true"
                chart-options="{datasetFill: false, scaleBeginAtZero : false}">
            </canvas>
      </ion-content>
    </ion-view>
  5. Inclua o código a seguir no arquivo client/www/js/controllers.js, como parte do controlador ExpenseController :
    //Method call to draw the chart. Calls the REST API & forms the angular chart based variables.
      $scope.drawCategoryMonthlyChart = function()
        {
            Expense.getMonthlyCategoryBasedAnalysis().$promise.then(function(results)
            {
                      expenseData = results.data;
                var foodPrice = 0, travelPrice = 0, eduPrice = 0, miscPrice = 0;
                for(i=0;i<4;i++)
                {
                     if(expenseData[i].category == "Food")
                         foodPrice = expenseData[i].price;
                                 if(expenseData[i].category == "Travel")
                        travelPrice = expenseData[i].price;
                                 if(expenseData[i].category == "Education")
                        eduPrice = expenseData[i].price;
                                if(expenseData[i].category == "Miscellaneous")
                        miscPrice = expenseData[i].price;
                }
    
    
            $rootScope.labels = ['Food','Travel','Education','Miscellaneous'];
            $rootScope.series = ['ThisMonth'];
               $rootScope.data = [
                  [foodPrice, travelPrice, eduPrice, miscPrice]
                   ];
              })
        };

Etapa 4. Realize o push do aplicativo no IBM Cloud

Realize o push do aplicativo do servidor no IBM Cloud para que o cliente possa chamar as APIs REST:

  1. Opcional: Para reduzir a quantidade de código que você transfere por upload ao IBM Cloud, mova a pasta cliente para um local diferente e (quando chegar à Etapa 5) execute seu aplicativo cliente a partir desse novo local.
  2. Em sua linha de comandos do S.O., acesse o diretório ExpenseTracker e execute:

    cf push ExpenseTracker -c "node server/server.js"

  3. Acesse http://app-name.mybluemix.net/explorer (em que app-name é o nome do aplicativo expense-tracker do Node.js que você criou no IBM Cloud na Etapa 1) para verificar se as APIs REST estão em execução.

Etapa 5. Execute o aplicativo híbrido cliente

Como o aplicativo cliente é um aplicativo híbrido, ele pode ser executado em um navegador, um emulador ou um dispositivo móvel. Esta seção mostra como executá-lo em um navegador ou um dispositivo iOS.

Teste o aplicativo em um navegador

  1. No arquivo client/www/js/lb-services.js, mude urlBase para apontar para a rota do IBM Cloud: http://app-name.mybluemix.net/api.
  2. Em sua linha de comandos do S.O., mude para o diretório ExpenseTracker/client e execute:

    ionic serve

  3. Em seu navegador, acesse http://localhost:8100/. Clique em Incluir Despesa para testar o formulário para incluir despesas: Screenshot of the Add Expense web UI
    Screenshot of the Add Expense web UI
  4. Clique em Gráficos para visualizar relatórios de despesas: Screenshot of the Charts web UI
    Screenshot of the Charts web UI

Teste o aplicativo em um dispositivo iOS (opcional)

  1. Em sua linha de comandos do S.O., acesse a pasta cliente do aplicativo e execute:

    ionic platform add ios

    Este comando inclui suporte à plataforma iOS no aplicativo cliente. (De modo semelhante, ionic platform add android incluiria suporte à plataforma para Android no aplicativo cliente).
  2. Execute ionic build ios para construir o projeto para dispositivos iOS.
  3. Os comandos precedentes criam uma pasta denominada client/platforms/ios que contém um projeto Xcode. Abra este projeto em sua ferramenta Xcode. Conecte seu dispositivo via USB e selecione seu dispositivo para executar o projeto: Screenshot of device selection in the XCode tool
    Screenshot of device selection in the XCode tool
  4. Teste a interface do aplicativo para incluir despesas e visualizar gráficos de despesas: Screnshot of the Add Expense mobile UI
    Screnshot of the Add Expense mobile UI
    Screenshot of the Charts mobile UI
    Screenshot of the Charts mobile UI

Nota: Seu aplicativo requer acesso ao transporte HTTP porque ele chama APIs REST. Você pode obter a mensagem Segurança de Transporte do Aplicativo bloqueou um carregamento de recurso HTTP de texto não criptografado (http://) pois ele é inseguro. É possível configurar exceções provisórias por meio do arquivo client/platforms/ios/client/Info.plist de seu aplicativo, incluindo o código a seguir:

<key>NSAppTransportSecurity</key>
  <dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>  </dict>

Conclusão

Desenvolvendo o aplicativo de amostra com a estrutura StrongLoop LoopBack e a estrutura Ionic, agora você sabe o quão fácil pode ser — com as ferramentas corretas — expor APIs REST e consumi-las em um aplicativo híbrido. É possível estender o que você aprendeu neste tutorial definindo relações entre modelos para criar aplicativos de qualidade corporativa prontos para produção.


Recursos para download


Temas relacionados


Comentários

Acesse ou registre-se para adicionar e acompanhar os comentários.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Desenvolvimento móvel, Cloud computing
ArticleID=1030618
ArticleTitle=Desenvolva um aplicativo de rastreamento de despesa híbrido
publish-date=04262016