Compartir objetos DTO entre microservicios

15

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?

Aerith
fuente
@DaiKaixian: Seguramente no estás sugiriendo que el OP vaya con un objeto de Dios, ¿verdad? Eso se considera rutinariamente un antipatrón.
Makoto
Estoy de acuerdo con la respuesta de @javaguy.
Y también quiero decir que puedes considerar el patrón de visitante. en.wikipedia.org/wiki/Visitor_pattern . Haga todo el campo y setter / getter en un POJO, y compártalo entre microservicios. Si desea realizar alguna operación en el POJO en diferentes microservicios, escriba un VisitorClass.
Gracias. Mi duda con tener esta 'biblioteca común' es que crecerá. Y habrá objetos allí que solo interesan a los servicios 1 y 3, o 2 y 4, o todos, o cualquier combinación de los mismos. Un tipo de paquete de biblioteca DTO general que tiene todos los DTO, ya sea que use un patrón de visita o un DTO POJO simple o no. ¿Es aceptable incluir todos estos objetos pero tratar de mantenerlo lo mejor posible? Al menos los objetos se proporcionan a cualquiera que los necesite SI desean usarlos ...

Respuestas:

5

¿Cuál es el mejor diseño?

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.

¿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?

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 .

desarrollador
fuente
Estoy de acuerdo en que la capa de presentación probablemente debería deserializar la carga útil entrante como un bean de presentación con diferentes atributos según sea necesario. Pero, en general, ¿está bien reutilizar los mismos objetos DTO en todos los servicios de fondo? Por lo general, trataríamos de separar estos paquetes DTO en paquetes más pequeños solo para los pocos servicios que los necesitan. Estoy cansado de tener un cajón de basura de un paquete de biblioteca DTO que tiene DTO para más de 75 microservicios de los que dependen todos los servicios. ¿A menos que esté bien, ya que solo los objetos DTO son opcionales en primer lugar?
Sí, obviamente puede reutilizar el mismo objeto DTO en todos los mismos tipos de servicios de back-end como el suyo PetServicespara evitar la duplicación. Pero mi punto es no acoplar estrechamente el backend y la interfaz, eso es todo.
desarrollador
4

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.

Jim Garrison
fuente
33
Compartir DTO entre microservicios es una pesadilla. "¿Esta versión ya tiene este campo? ¿Hm tal vez?" Terminarás con un verdadero desastre después de un tiempo. El código duplicado es bueno en este caso.
Mejmo
1

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.

kensai
fuente