Arquitetura de microsserviço - SOA prático

Neste capítulo, desenvolveremos um aplicativo baseado em CRUD com arquitetura SOA. Posteriormente, nos capítulos subsequentes, dividiremos esse serviço em microsserviço e aprenderemos a diferença básica entre SOA e a arquitetura de microsserviço.

Configuração e instalação do sistema

Nesta seção, construiremos um aplicativo CRUD de amostra, que retornará um objeto JSON como uma resposta sempre que chamarmos nosso serviço. Usaremos a estrutura de Jersey para desenvolver o mesmo. A seguir estão as etapas para configurar seu ambiente de sistema local.

Desenvolvendo um aplicativo CRUD

Step 1- Usaremos o NetBeans como IDE de desenvolvimento. Baixe e instale a versão mais recente disponível no site oficial do NetBeanshttps://netbeans.org/downloads/.

Step 2- Abra seu NetBeans IDE. Vá para “Arquivo -> Novo Projeto”. A seguinte imagem aparece. Escolha “Maven” como uma categoria e selecione “Projeto do ArchType” como um projeto e clique em Avançar.

Isso fará o download de todos os arquivos jar necessários para criar seu primeiro projeto Maven e serviço da Web RESTful.

Step 3- Ao clicar no botão Avançar na etapa anterior, a seguinte captura de tela aparece. Aqui, você terá que especificar o arquétipo Maven.

Na caixa de pesquisa, procure “Jersey-archType-Webapp (2.16)” e marque a caixa de seleção “Mostrar mais antigos”.

Step 4- Depois de selecionar o mesmo, você será redirecionado para a tela seguinte. Selecione o jar preferido na lista e clique em Avançar para continuar.

Step 5- Nesta etapa, você precisa fornecer o nome do seu projeto e seu ID de grupo, bem como os detalhes do pacote. Depois de fornecer todas essas informações, clique em Concluir para continuar.

Step 6- Você concluiu a configuração do seu espaço de trabalho. O diretório do projeto terá a seguinte aparência.

Verifique sua pasta “Dependências” e você verá que o Maven baixou automaticamente todos os arquivos jar necessários para este projeto.

Step 7- Seu espaço de trabalho está configurado e você pode começar com a codificação. Vá em frente e crie quatro classes e pacotes conforme mencionado na imagem a seguir. Você pode descobrir que MyResource.java já foi criado pelo Maven, pois o Maven é inteligente o suficiente para detectar que você irá construir seu próprio serviço web.

Step 8 - Depois de concluir a etapa acima, construiremos nossa classe POJO que é UserProfile.java da seguinte maneira.

package com.tutorialspoint.userprofile.Model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class UserProfile {
   private long ProId;
   private String FName;
   private String LName;
   private String Add;
   public UserProfile(){}
   
   public UserProfile(long Proid, String Fname, String Lname,String Add) {
      this.ProId = Proid;
      this.FName = Fname;
      this.LName = Lname;
      this.Add = Add;
   }
   public long getProId() {
      return ProId;
   }
   public void setProId(long ProId) {
      this.ProId = ProId;
   }
   public String getFName() {
      return FName;
   }
   public void setFName(String FName) {
      this.FName = FName;
   }
   public String getLName() {
      return LName;
   }
   public void setLName(String LName) {
      this.LName = LName;
   }
   public String getAdd() {
      return Add;
   }
   public void setAdd(String Add) {
      this.Add = Add;
   }
}

Step 9- Agora vamos criar nossa classe Database. Como isso faz parte do material de aprendizagem, não usaremos nenhum banco de dados como nosso banco de dados. Usaremos uma memória Java embutida para funcionar como nossa memória temporária. Como você pode ver no seguinte conjunto de código, usaremos o MAP como nosso banco de dados. Toda a operação do serviço web que realizarmos, trabalharemos neste MAP definido na aula.

package com.tutorialspoint.userprofile.DAO;

import com.tutorialspoint.userprofile.Model.UserProfile;

import java.util.HashMap;
import java.util.Map;

public class DatabaseClass {
   private static Map<Long,UserProfile> messages = new HashMap<Long,UserProfile>();
   public static Map<Long,UserProfile> getUsers() {
      return messages; 
      // Each time this method will return entire map as an instance of database
   }
}

Step 10- Agora vamos construir nossa classe de serviço. Vá em frente e copie e cole o seguinte conjunto de código na classe “ProfileService.java”. Esta é a classe em que declararemos todos os nossos métodos de serviço da web que serão expostos para o mundo exterior. Precisamos criar uma referência de nosso DatabaseClass de forma que nosso banco de dados temporário possa ser acessado nesta classe.

package com.tutorialspoint.userprofile.service;

import com.tutorialspoint.userprofile.DAO.DatabaseClass;
import com.tutorialspoint.userprofile.Model.UserProfile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ProfileService {
   private Map<Long,UserProfile> Userprofiles = DatabaseClass.getUsers();
   
   // Creating some predefine profile and populating the same in the map
   public ProfileService() {
      UserProfile m1 = new UserProfile(1L,"Tutorials1","Point1","TutorialsPoint.com");
      UserProfile m2 = new UserProfile(2L,"Tutorials2","Point2","TutorialsPoint.com2");
      UserProfile m3 = new UserProfile(3L,"Tutorials3","Point3","TutorialsPoint.com3");
      UserProfile m4 = new UserProfile(4L,"Tutorials4","Point4","TutorialsPoint.com4");
      
      Userprofiles.put(1L, m1);
      Userprofiles.put(2L, m2);
      Userprofiles.put(1L, m3);
      Userprofiles.put(2L, m4);
   }
   
   //Method to fetch all profile
   public List<UserProfile> getAllProfile() {
      List<UserProfile> list = new ArrayList<UserProfile>(Userprofiles.values());
      return list;
   }  // Method to fetch only one profile depending on the ID provided
   
   public UserProfile getProfile(long id) {
      return Userprofiles.get(id);
   }  //Method to add profile
   
   public UserProfile addProfile(UserProfile UserProfile) {
      UserProfile.setProId(Userprofiles.size()+1);
      Userprofiles.put(UserProfile.getProId(), UserProfile);
      return UserProfile;
   }  //method to update Profile

   public UserProfile UpdateProfile(UserProfile UserProfile) {
      if(UserProfile.getProId()<=0) { 
         return null;
      } else { 
         Userprofiles.put(UserProfile.getProId(), UserProfile);
         return UserProfile;
      }
   } //method to delete profile
   
   public void RemoveProfile(long Id) {
      Userprofiles.remove(Id);
   }
}

Step 11 - Nesta etapa, criaremos nossa classe Resource que será vinculada à URL e o serviço correspondente será chamado.

package com.tutorialspoint.userprofile.Resource;

import com.tutorialspoint.userprofile.Model.UserProfile;
import com.tutorialspoint.userprofile.service.ProfileService;

import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/Profile")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)

public class ProfileResource {
   ProfileService messageService = new ProfileService();
   
   @GET
   public List<UserProfile> getProfile() {
      return messageService.getAllProfile();
   }

   @GET
   @Path("/{ProID}")
   public UserProfile getProfile(@PathParam("ProID")long Id) {
      return messageService.getProfile(Id);
   }

   @POST
   public UserProfile addProfile(UserProfile profile) {
      return messageService.addProfile(profile);
   }

   @PUT
   @Path("/{proID}")
   public UserProfile UpdateProfile(@PathParam("proID")long Id,UserProfile UserProfile) {
      UserProfile.setProId(Id);
      return messageService.UpdateProfile(UserProfile);
   }
   
   @DELETE
   @Path("/{ProID}")
   public void deleteProfile(@PathParam("ProID")long Id) {
      messageService.RemoveProfile(Id);
   }
}

Step 12- Limpe a compilação do projeto e execute-o. Se tudo correr bem, você deve obter a seguinte saída no navegador, ao acessarhttp://localhost:8080/UserProfile/webapi/Profile” URL.

Você pode ver que diferentes entradas são preenchidas usando representação XML.

Métodos diferentes podem ser testados usando o Postman aplicando o URL do método adequado.

@GET method - A captura de tela a seguir demonstra como podemos obter o resultado desejado para a solicitação get, que retorna todos os detalhes do usuário.

@POST- A seguinte solicitação pode ser usada para testar nosso método Post. Observe como o proId foi gerado automaticamente.

@PUT- Este método atualizará as entradas. A captura de tela a seguir demonstra como Jersey obtém o perfil do URL de solicitação e atualiza a mesma resposta do perfil do usuário.

Da mesma forma, você pode verificar outros métodos disponíveis em seus serviços da web.

Na seção anterior, desenvolvemos um serviço que irá expor a funcionalidade CRUD. Agora, sempre que tentamos implementar este serviço em nosso aplicativo, precisamos criar um cliente deste aplicativo e anexá-lo ao nosso aplicativo. Neste capítulo, aprenderemos como construir essa funcionalidade usando o conceito de microsserviço. A seguir está uma representação esquemática de nosso aplicativo construído usando as etapas acima.

O ator deve ser a porta de entrada do nosso serviço. Neste caso, “ProfileResource.java” assume a responsabilidade de um ator. Esta classe irá chamar diferentes métodos para realizar diferentes operações, como adicionar, atualizar e excluir.

Decomposição do aplicativo CRUD

De acordo com o princípio básico do microsserviço, precisamos ter apenas uma tarefa de negócios para cada um dos módulos, portanto, um ator não deve ser responsável por todas as quatro funcionalidades do CRUD. Considere o exemplo a seguir, onde introduzimos algumas novas funções de forma que fique conceitualmente claro para você que Microservice é uma representação arquitetônica de SOA.

“Usuário principal” é o usuário que se comunica com o “Controlador de aplicativo” para atender às suas necessidades. “Application Controller” é aquele que apenas chama diferentes “Resource Managers” dependendo da solicitação do usuário final. “Resource Manager” faz o trabalho que deve ser feito. Vamos dar uma olhada rápida nas diferentes funções das diferentes unidades do aplicativo.

  • End User/Main Users - Solicitações de alguns recursos ao Controlador de Aplicativos.

  • Application - Recebe a solicitação e a encaminha para o Gerente de Recursos específico.

  • Resource Manager - Realiza o trabalho real de atualização, exclusão e adição de usuários.

Veja como a responsabilidade total de uma classe é distribuída entre as diferentes outras classes.