Arquitectura de microservicio: SOA práctico

En este capítulo, desarrollaremos una aplicación basada en CRUD con arquitectura SOA. Más adelante, en los capítulos siguientes, dividiremos este servicio en microservicio y aprenderemos la diferencia básica entre SOA y arquitectura de microservicio.

Configuración y configuración del sistema

En esta sección, crearemos una aplicación CRUD de muestra, que devolverá un objeto JSON como respuesta cada vez que llamemos a nuestro servicio. Usaremos el marco de Jersey para desarrollar el mismo. Los siguientes son los pasos para configurar su entorno de sistema local.

Desarrollo de una aplicación CRUD

Step 1- Usaremos NetBeans como IDE de desarrollo. Descargue e instale la última versión disponible en el sitio web oficial de NetBeanshttps://netbeans.org/downloads/.

Step 2- Abra su IDE de NetBeans. Vaya a "Archivo -> Nuevo proyecto". Aparece la siguiente captura de pantalla. Elija "Maven" como categoría y seleccione "Proyecto de ArchType" como proyecto y presione Siguiente.

Esto descargará todos los archivos jar necesarios para crear su primer proyecto Maven y el servicio web RESTful.

Step 3- Al presionar el botón Siguiente en el paso anterior, aparece la siguiente captura de pantalla. Aquí, deberá especificar el arquetipo de Maven.

En el cuadro de búsqueda, busque "Jersey-archType-Webapp (2.16)" y marque la casilla de verificación "Mostrar más antiguo".

Step 4- Una vez que haya seleccionado el mismo, será redirigido a la siguiente pantalla. Seleccione el frasco preferido de la lista y presione Siguiente para continuar.

Step 5- En este paso, debe proporcionar el nombre de su proyecto y su ID de grupo, así como los detalles del paquete. Después de proporcionar toda esta información, presione Finalizar para continuar.

Step 6- Ha terminado con la configuración de su espacio de trabajo. El directorio del proyecto tendrá el siguiente aspecto.

Consulte su carpeta "Dependencias" y encontrará que Maven ha descargado automáticamente todos los archivos jar necesarios para este proyecto.

Step 7- Su espacio de trabajo está configurado y puede comenzar con la codificación. Continúe y cree cuatro clases y paquetes como se menciona en la siguiente captura de pantalla. Puede encontrar que MyResource.java ya está creado por Maven, ya que Maven es lo suficientemente inteligente como para detectar que va a crear su propio servicio web.

Step 8 - Una vez hecho esto con el paso anterior, construiremos nuestra clase POJO que es UserProfile.java de la siguiente manera.

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- Ahora crearemos nuestra clase de Base de datos. Como esto es parte del material de aprendizaje, no usaremos ninguna base de datos como nuestra base de datos. Usaremos una memoria Java incorporada para que funcione como nuestra memoria temporal. Como puede ver en el siguiente conjunto de código, usaremos MAP como nuestra base de datos. Toda la operación del servicio web que realicemos, trabajaremos en este MAP definido en la clase.

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- Ahora construyamos nuestra clase de servicio. Continúe y copie y pegue el siguiente conjunto de código en la clase "ProfileService.java". Esta es la clase en la que declararemos todos nuestros métodos de servicio web que se expondrán para el mundo exterior. Necesitamos crear una referencia de nuestra DatabaseClass de modo que se pueda acceder a nuestra base de datos temporal en esta clase.

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 - En este paso, crearemos nuestra clase Resource que se vinculará con la URL y se llamará al servicio correspondiente.

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- Limpiar la construcción del proyecto y ejecutarlo. Si todo va bien, debería obtener el siguiente resultado en el navegador, mientras accedehttp://localhost:8080/UserProfile/webapi/Profile” URL.

Puede ver que las diferentes entradas se completan mediante la representación XML.

Se pueden probar diferentes métodos con Postman aplicando la URL del método adecuado.

@GET method - La siguiente captura de pantalla demuestra cómo podemos obtener el resultado deseado para la solicitud de obtención, que devuelve todos los detalles del usuario.

@POST- La siguiente solicitud se puede utilizar para probar nuestro método de publicación. Observe cómo el proId se ha generado automáticamente.

@PUT- Este método actualizará las entradas. La siguiente captura de pantalla demuestra cómo Jersey toma el proId de la URL de solicitud y actualiza la misma respuesta de perfil de usuario.

De la misma manera, puede verificar otros métodos disponibles en sus servicios web.

En la sección anterior, hemos desarrollado un servicio que expondrá la funcionalidad CRUD. Ahora, cada vez que intentamos implementar este servicio en nuestra aplicación, necesitamos crear un cliente de esta aplicación y adjuntarlo a nuestra aplicación. En este capítulo, aprenderemos cómo construir esta funcionalidad usando el concepto de Microservicio. A continuación se muestra una representación esquemática de nuestra aplicación construida siguiendo los pasos anteriores.

El actor debe ser el punto de entrada de nuestro servicio. En este caso, “ProfileResource.java” asume la responsabilidad de un actor. Esta clase llamará a diferentes métodos para realizar diferentes operaciones como agregar, actualizar y eliminar.

Descomposición de la aplicación CRUD

De acuerdo con el principio principal del microservicio, necesitamos tener solo una tarea comercial para cada uno de los módulos, por lo tanto, un actor no debería ser responsable de las cuatro funcionalidades CRUD. Considere el siguiente ejemplo en el que hemos introducido algunos roles nuevos de manera que le resultará conceptualmente claro que Microservice es una representación arquitectónica de SOA.

El "usuario principal" es el usuario que se comunica con el "controlador de la aplicación" para satisfacer sus necesidades. "Controlador de aplicaciones" es el que simplemente llama a diferentes "Administradores de recursos" según la solicitud del usuario final. “Resource Manager” hace el trabajo que se requiere. Echemos un vistazo rápido a los diferentes roles de las diferentes unidades de la aplicación.

  • End User/Main Users - Solicitudes de algunos recursos al controlador de aplicaciones.

  • Application - Recibe la solicitud y la reenvía a Resource Manager específico.

  • Resource Manager - Realiza el trabajo real de actualizar, eliminar y agregar usuarios.

Vea cómo la responsabilidad total de una clase se distribuye entre otras clases diferentes.