Tengo serias dudas sobre el diseño de mi aplicación web.
Quería separar la lógica de negocios de la interfaz, así que hice una API web que maneja todas las solicitudes a la base de datos.
Es una API web ASP.NET con Entity Framework y una unidad de trabajo y un patrón de repositorio genérico. Hasta ahora, todo está bien.
PROBLEMA
Donde necesito ayuda es que no puedo encontrar una manera eficiente de compartir objetos entre la API y la aplicación.
No quiero serializar directamente el objeto de entidad, pensé que sería una mala práctica porque si el modelo de entidad cambia, podría terminar serializando objetos grandes sin ningún motivo.
Cómo se implementa ahora
Debido a que mi interfaz es la aplicación web ASP.NET en C # y mi API está en C #, hice una biblioteca común con la definición de todas mis clases que quiero compartir entre ellas.
Sé que la solución no funcionará cuando desarrolle una aplicación de Android, tendré que crear mis clases nuevamente en Java, pero ese no es mi mayor problema.
El problema es que siento que siempre estoy convirtiendo mis objetos.
EJEMPLO
Aquí hay un ejemplo de mi flujo de trabajo:
Comienzo con un modelo con todos los objetos y las anotaciones de datos para mi formulario, luego el usuario PUBLICARÁ ese modelo en un controlador.
En el controlador, tengo que convertir este modelo a una clase en mi biblioteca común y luego enviar ese objeto a mi API.
Luego, un controlador en mi API captura la llamada y convierte ese objeto en un objeto de entidad para actualizar la base de datos.
Entonces tengo 3 clases
- El modelo para la vista con todas las anotaciones de datos para la validación (Cliente)
- Las clases de biblioteca comunes para compartir los objetos (DLL)
- Las clases de entidad (API)
Tengo la sensación de que hago algo realmente mal. ¿Hay algo más elegante? Me gustaría asegurarme de tener una buena solución para este problema antes de que el proyecto sea demasiado grande.
Respuestas:
Sé que puede parecer que está convirtiendo objetos de un lado a otro todo el tiempo entre sus objetos de base de datos, sus objetos de transferencia de datos, sus objetos de cliente con lógica de validación, etc., pero yo diría que no, que no está haciendo nada mal .
Cada uno de estos objetos puede representar la misma unidad de información, pero tienen responsabilidades muy diferentes. El objeto de la base de datos es su interfaz de comunicación con la base de datos y debe mantenerse en la capa de la base de datos, ya que puede tener o no diferentes anotaciones de metadatos de la base de datos y / o detalles innecesarios sobre la implementación de la base de datos.
Su objeto de transferencia de datos es la interfaz de comunicación con sus consumidores API. Deben ser lo más limpios posible para facilitar el consumo desde diferentes idiomas / plataformas. Esto podría imponer ciertas restricciones sobre cómo se ven y se comportan según los consumidores de API que desee admitir.
Sus objetos de cliente con lógica de validación realmente no son parte de su proyecto API, son parte de su proyecto de consumidor. En este caso, no pueden ser los mismos que los objetos de transferencia de datos, ya que está agregando lógica adicional específica del cliente (en este caso, atributos de validación) sobre los cuales el servidor no sabe nada (¡y no debería saber nada!). cuente estos objetos como parte de su API, porque realmente no lo son. Son altamente específicas para aplicaciones de consumo y algunas aplicaciones que consumen su API en realidad ni siquiera necesitan crear estos objetos y podrían sobrevivir solo con sus objetos de transferencia de datos. Por ejemplo, si no tuviera ninguna necesidad de validación, no necesitaría una capa adicional de objetos que sean completamente idénticos a sus objetos de transferencia de datos.
Para mí, parece que cada uno de los tres tipos de objetos se correlaciona muy bien con una única responsabilidad, que es la codificación limpia y las buenas prácticas. Lamentablemente, el código limpio y las buenas prácticas a veces significan que está escribiendo una gran cantidad de código adicional y saltando a través de aros adicionales "solo porque". Y mientras codifica, puede ser difícil apreciar el valor que esto le está dando, pero tan pronto como lance su aplicación y comience a admitirla o a agregar nuevas características para la próxima versión, probablemente comenzará a apreciar que se tomó el tiempo para separe estas preocupaciones adecuadamente en primer lugar. (Sin mencionar que tú '
También odio escribir código de conversión entre diferentes tipos de objetos como este, pero mi solución suele ser una de las siguientes:
fuente