TL; DR: ¿está bien compartir una biblioteca POJO entre servicios?
En general, nos gusta mantener el intercambio entre servicios estrictamente limitado a ninguno si es posible. Se ha debatido si el servicio que comparte datos debería proporcionar una biblioteca de clientes para que los clientes la utilicen. El client-lib es generalmente opcional para que lo use un cliente del servicio y puede consumir la API como quiera, ya sea que use el client-lib, o use un lenguaje alternativo y use los aspectos generales de la biblioteca y demás.
En mi caso, considero un servicio que crea un objeto de datos. Asumamos que este objeto es un PET. NO es la entidad de la base de datos, sino estrictamente un POJO que representa implícitamente los datos subyacentes. Este POJO es lo que la API ha definido. Asumir: mascota: edad, peso, nombre, propietario, dirección, especie, etc.
Servicio 1 - PetKeeper: generará una mascota por cualquier motivo y retendrá todos los datos y debe hacer referencia a este servicio para obtener la mascota, o hacer modificaciones a la mascota, digamos que los cambios de nombre o cambio de dirección deben hacerse a través de un Llamada API a este servicio.
Servicio 2 - PetAccessor: este servicio reúne las mascotas y realiza comprobaciones de validación
Servicio 3,4 - Más llamadas de servicio intermedio
Servicio 5 - Interfaz de usuario
Estos son muy arbitrarios, pero el punto es simple. La interfaz de usuario o algún servicio orientado al usuario desea presentar de alguna manera este objeto "PET". Debe llamar a través de una API un servicio, que llama a un servicio, que llama a un servicio, etc., hasta que llegue al servicio que reúne la información requerida y comience la retransmisión. Finalmente, el servicio de IU tiene el objeto PET para mostrar.
Esto es bastante común, pero con nuestra mentalidad absoluta, duplicamos el objeto PET en cada servicio. El principio SECO (no repetir) solo se aplica al código DENTRO de un servicio y no se aplica a todos los servicios, pero el punto sigue ahí. ¿Qué pasa si agregamos un campo ... debemos modificar 5 servicios del POJO en cada uno?
O bien, podemos proporcionar una biblioteca de objetos de mascota que contenga algunos de los pojo de la API y cada servicio puede importar / depender de la biblioteca. No hay dependencia de los servicios en sí, sino solo de la biblioteca general. Me gusta esta idea para que cada servicio tenga el mismo tipo de objeto y las actualizaciones sean más fáciles. Pero me preocupan los Dios-Objetos.
¿Cuáles son las ventajas y desventajas? ¿Cuál es el mejor diseño? ¿Qué ha hecho para pasar datos entre servicios para minimizar la repetición de las mismas clases de POJO y al mismo tiempo permanecer desconectado?
fuente
Respuestas:
Puedes reutilizar lo mismo
Pet
objeto DTO entre los servicios de fondo (que procesan la lógica de negocios típica), pero cuando se trata del nivel de presentación (Interfaz de usuario), generalmente es una buena práctica usar un FormBean (un bean diferente con campos agregados) para la lógica de presentación) para que haya una clara separación entre la lógica de presentación y la lógica de negocios .Esto es necesario porque los servicios deben ser reutilizables y un único servicio puede ser expuesto / reutilizado por puntos finales múltiples / diferentes (como frontend o podría ser un servicio web diferente, etc.) y cada uno de esos puntos finales puede requerir campos adicionales que serán poblados por los respectivos controladores o capas (como adaptadores) sobre los servicios.
Si usa un solo bean entre negocios y niveles web, entonces está estrechamente acoplando la lógica de presentación con la lógica comercial, lo cual no es una buena práctica y terminará cambiando los servicios por un requisito en el Frontend (como, por ejemplo, un formato de fecha diferente para mostrar en la interfaz de usuario). Además, para realizar este proceso de poblar / copiar los datos a través de los beans (como DTO a FormBean o Viceversa), puede usar bibliotecas como Apache
BeanUtils.copyProperties()
o Dozer para evitar el código repetitivo .fuente
PetServices
para evitar la duplicación. Pero mi punto es no acoplar estrechamente el backend y la interfaz, eso es todo.Si el DTO representa la misma entidad comercial en todos los microservicios, solo debería haber una clase, compartida entre los servicios. (Casi) nunca es correcto tener un código duplicado para el mismo objeto.
fuente
La forma en que planeo hacerlo ahora es que cada servicio empaqueta solo DTO y los coloca en Nexus como jar lib. Cuando otro servicio los necesite, obtendrá esas bibliotecas DTO como dependencia en manve / gradle. Si se lanza una nueva versión de DTO en un servicio, está bien siempre que la versión anterior también sea compatible al mismo tiempo, así que no rompa la compatibilidad con versiones anteriores, versiones, etc., por lo que este es un área de back-end a back-end. Además, para evitar la dependencia circular, es mejor separar el servicio del paquete dto
Ahora mire el backend-to-frontend y viceversa , no estoy de acuerdo con los comentarios anteriores de que la interfaz de usuario como capa de presentación es diferente. ¡¡¡NO LO ES!!! La interfaz de usuario es solo otro microservicio para mí que también consume y produce eventos.
Dirección de backend a frontend Lo que hago es convertir POJO (dtos) a interfaces mecanografiadas y empaquetar en NPM y cargarlas también en Nexus. El proyecto basado en UI nodejs luego los consume y los usa. Esta es la forma de servicio a la interfaz de usuario.
Dirección de frontend a backend Para la interfaz de usuario a los eventos de capa de servicio, convierto las interfaces de Typecript y las convierto en POJO (dtos), las empaqueto como jar y las cargo en Nexus (o algún repositorio) en forma de jar para ser consumidas por los servicios de back-end.
Estos procesos son manejados fácilmente por los procesos de CI (Travis, Gitlab CI, etc.)
Cualquier comentario a este enfoque es bienvenido.
fuente