En las últimas dos compañías que he estado en REST API existen para consultar datos a través de una aplicación web. es decir. en lugar de hacer que la aplicación web ejecute SQL directamente, llama a una API REST y eso hace el SQL y devuelve el resultado.
Mi pregunta es ... ¿por qué se hace esto?
Si iba a estar expuesto a terceros, podría entenderlo. Es mejor exponer una API REST limitada que la base de datos completa. Pero en ambas compañías ese no es el caso.
Me han sugerido que estas API REST facilitan el cambio entre DBMS. ¿Pero no es ese el punto de una capa de abstracción de base de datos (DBAL)? Tal vez use un ORM como su DBAL o tal vez podría simplemente escribir SQL sin procesar y hacer que su DBAL traduzca las cosas específicas de la base de datos si corresponde (por ejemplo, traducir LIMIT for MySQL to TOP for MSSQL).
De cualquier manera, me parece innecesario. Y creo que también dificulta el diagnóstico de problemas. Si un informe en la aplicación web está dando los números incorrectos, no puede simplemente deshacerse de la consulta SQL; debe volcar la URL REST y luego ir al proyecto que sirve como API REST y extraer el SQL de eso. Por lo tanto, es una capa adicional de indirección que ralentiza el proceso de diagnóstico.
fuente
Respuestas:
Si permite que un cliente acceda a la base de datos directamente, lo que haría, incluso con una capa de abstracción de la base de datos, entonces:
Es decir, no estoy tocando en absoluto la parte REST: aislar su base de datos detrás de una API es simplemente una opción más sensata si el equipo que mantiene la base de datos y los equipos que la usan no están sincronizados, ya que permite que estas partes evolucionar a su propio ritmo.
fuente
Tiene razón, no existe un beneficio claro al introducir una capa API REST entre una aplicación web y una base de datos, y tiene un costo en complejidad y sobrecarga de rendimiento.
La razón por la que obtiene respuestas contradictorias es la confusión sobre cuál es el "cliente" en su arquitectura.
En su arquitectura (si lo entiendo bien), tiene navegadores que interactúan con una sola aplicación web, que a su vez interactúa con la base de datos. La introducción de una capa API REST entre la aplicación web y la base de datos no tiene ningún beneficio. Todos los beneficios establecidos (almacenamiento en caché, aislamiento de la base de datos, etc.) se pueden lograr con las capas de acceso a datos en el código.
Pero hay algunas otras arquitecturas donde una API REST tiene sentido:
Si tiene varios clientes accediendo a la base de datos, es decir, no una sola aplicación web sino múltiples aplicaciones web independientes que acceden a la misma base de datos. Puede ser beneficioso crear una interfaz REST común para permitir compartir el modelo de datos, el almacenamiento en caché, etc. Seguro que puede obtener algunos de los beneficios al compartir las mismas bibliotecas DAL, pero eso no funcionará si las aplicaciones se desarrollan en diferentes idiomas y en diferentes plataformas Esto es común en los sistemas empresariales.
Si tiene varias aplicaciones de escritorio que acceden a la base de datos directamente. Esta es la arquitectura clásica de "dos niveles", que ha caído en desgracia en comparación con las aplicaciones web. La introducción de una capa REST le permite centralizar la lógica de acceso a datos y, especialmente, permite un control más estricto de la seguridad, ya que es arriesgado tener múltiples clientes distribuidos que acceden directamente a la misma base de datos.
Si tiene un código JavaScript que obtiene datos directamente del servidor, entonces necesita algo como una API REST en cualquier caso.
fuente
Advertencia: gran publicación, algunas opiniones, conclusión vaga de 'haz lo que mejor te funcione'
Generalmente, esto se hace como un medio de implementar 'arquitectura hexagonal' alrededor de su base de datos. Puede hacer que las aplicaciones web, las aplicaciones móviles, las aplicaciones de escritorio, los importadores masivos y el procesamiento en segundo plano consuman su base de datos de manera uniforme. Ciertamente, podría lograr lo mismo hasta cierto punto escribiendo una biblioteca rica para acceder a su base de datos y haciendo que todos sus procesos utilicen esa biblioteca. Y, de hecho, si estás en una tienda pequeña con un sistema muy simple, esa es probablemente una mejor ruta a seguir; Es un enfoque más simple y si no necesita las capacidades avanzadas de un sistema más complicado, ¿por qué pagar por la complejidad? Sin embargo, si está trabajando con un conjunto grande y sofisticado de sistemas que todos necesitan interactuar con su base de datos a escala, allí '
Independencia y mantenimiento de la plataforma.
Si tienes una base de datos y escribes una biblioteca de Python para interactuar con esa base de datos, y todos tiran de esa biblioteca para interactuar con la base de datos, eso es genial. Pero digamos que de repente necesitas escribir una aplicación móvil, y esa aplicación móvil ahora también necesita hablar con la base de datos. Y sus ingenieros de iOS no usan Python, y sus ingenieros de Android no usan Python. Quizás los chicos de iOS quieren usar los idiomas de Apple y los ingenieros de Android quieren usar Java. Entonces estaría atrapado escribiendo y manteniendo su biblioteca de acceso a datos en 3 idiomas diferentes. Tal vez los desarrolladores de iOS y Android decidan usar algo como Xamarin para maximizar el código que pueden compartir. Perfecto, excepto que probablemente todavía tendrá que portar su biblioteca de acceso a datos a .NET. Y luego su compañía acaba de comprar otra compañía que ' La aplicación web es un producto dispar pero relacionado, y la empresa desea integrar algunos de los datos de la plataforma de su empresa en la plataforma de la subsidiaria recién adquirida. Solo hay un problema: la subsidiaria era una empresa nueva y decidió escribir la mayor parte de su aplicación en Dart. Además, por cualquier motivo (razones probablemente fuera de su control), el equipo móvil que estaba pilotando Xamarin decidió que no era para ellos, y que preferirían usar las herramientas y los idiomas específicos de los dispositivos móviles para los que se desarrollarán. Pero mientras estaba en esa fase, su equipo ya había entregado una gran parte de su biblioteca de acceso a datos en .NET, y otro equipo de la compañía estaba escribiendo algunas cosas locas de integración de Salesforce y decidió hacer todo eso en .NET desde allí ya era una biblioteca de acceso a datos para.
Ahora, debido a un giro muy realista de los eventos, tiene su biblioteca de acceso a datos escrita en Python, .NET, Swift, Java y Dart. Tampoco son tan agradables como te gustaría que fueran. No podría usar un ORM tan eficazmente como le gustaría, porque cada idioma tiene diferentes herramientas ORM, por lo que ha tenido que escribir más código del que le hubiera gustado. Y no has podido dedicar tanto tiempo a cada encarnación como hubieras querido, porque hay 5 de ellos. Y la versión Dart de la biblioteca es especialmente complicada porque tenías que rodar tus propias transacciones para algunos porque las bibliotecas y el soporte simplemente no estaban realmente allí. Intentaste argumentar que debido a esto, la aplicación Dart solo debería haber tenido funcionalidad de solo lectura para tu base de datos, pero el negocio ya había tomado la decisión de que las características que planeaban valían la pena el esfuerzo adicional. Y resulta que hay un error en algunas de las lógicas de validación que existen en todas estas encarnaciones de su biblioteca de acceso a datos. Ahora tiene que escribir pruebas y código para corregir este error en todas estas bibliotecas, obtener revisiones de código para sus cambios en todas estas bibliotecas, obtener el control de calidad en todas estas bibliotecas y publicar sus cambios en todos los sistemas utilizando todos Estas bibliotecas. Mientras tanto, sus clientes están disgustados y han recurrido a Twitter, combinando combinaciones de vulgaridades que nunca hubiera imaginado que podrían concebirse, y mucho menos dirigidas al producto estrella de su empresa. Y el propietario del producto decide no comprender mucho la situación.
Por favor, comprenda que en algunos entornos, el ejemplo anterior es cualquier cosa menos artificial. También tenga en cuenta que esta secuencia de eventos puede desarrollarse en el transcurso de unos años. En general, cuando llegas al punto en que arquitectos y empresarios comienzan a hablar de conectar otros sistemas a tu base de datos, es cuando querrás "poner una API REST frente a la base de datos" en tu hoja de ruta. Considere si al principio, cuando estaba claro que esta base de datos iba a comenzar a ser compartida por algunos sistemas, que se colocó un servicio web / API REST. Arreglar su error de validación sería mucho más rápido y fácil porque lo está haciendo una vez en lugar de 5 veces. Y liberar la solución sería mucho más fácil de coordinar, porque '
TLDR; Es más fácil centralizar la lógica de acceso a datos y mantener clientes HTTP muy delgados que distribuir la lógica de acceso a datos a cada aplicación que necesita acceder a los datos. De hecho, su cliente HTTP puede incluso generarse a partir de metadatos. En sistemas grandes, la API REST le permite mantener menos código
Rendimiento y escalabilidad
Algunas personas pueden creer que hablar con la base de datos directamente en lugar de pasar por un servicio web primero es más rápido. Si solo tiene una aplicación, eso es cierto. Pero en sistemas más grandes, no estoy de acuerdo con el sentimiento. Eventualmente, en algún nivel de escala, será muy beneficioso colocar algún tipo de caché frente a la base de datos. Tal vez esté utilizando Hibernate y quiera instalar una grilla Infinispan como caché L2. Si tiene un grupo de 4 servidores robustos para alojar su servicio web por separado de sus aplicaciones, puede permitirse el lujo de tener una topología integrada con la replicación sincrónica activada. Si intenta colocar eso en un clúster de 30 servidores de aplicaciones, la sobrecarga de activar la replicación en esa configuración será demasiado, por lo que ' Tendré que ejecutar Infinispan en modo distribuido o en algún tipo de topología dedicada, y de repente Hibernate debe salir de la red para leer desde la caché. Además, Infinispan solo funciona en Java. Si tiene otros idiomas, necesitará otras soluciones de almacenamiento en caché. La sobrecarga de la red de tener que pasar de su aplicación a su servicio web antes de llegar a la base de datos se compensa rápidamente por la necesidad de usar soluciones de almacenamiento en caché mucho más complicadas que generalmente vienen con sobrecarga propia.
Además, esa capa HTTP de su API REST proporciona otro mecanismo valioso de almacenamiento en caché. Sus servidores para su API REST pueden colocar encabezados de almacenamiento en caché en sus respuestas, y estas respuestas pueden almacenarse en caché en la capa de red, que se escala excepcionalmente bien. En una configuración pequeña, con uno o dos servidores, su mejor opción es usar un caché en memoria en la aplicación cuando habla con la base de datos, pero en una plataforma grande con muchas aplicaciones que se ejecutan en muchos servidores, desea aprovechar red para manejar su almacenamiento en caché, porque cuando se configura correctamente, algo como calamar o barniz o nginx puede escalar a niveles locos en hardware relativamente pequeño. Cientos de miles o millones de solicitudes por segundo de rendimiento es mucho más barato desde un caché HTTP que desde un servidor de aplicaciones o una base de datos.
Además de eso, tener una tonelada de clientes apuntando a su base de datos, en lugar de hacer que todos apunten a unos pocos servidores que a su vez apuntan a la base de datos, puede hacer que el ajuste de la base de datos y la agrupación de conexiones sean mucho más difíciles. En general, la mayor parte de la carga de trabajo real en un servidor de aplicaciones es material de aplicación; esperar que los datos vuelvan de la base de datos suele llevar mucho tiempo, pero en general no es muy costoso desde el punto de vista informático. Es posible que necesite 40 servidores para manejar la carga de trabajo de su aplicación, pero probablemente no necesite 40 servidores para organizar la obtención de los datos de la base de datos. Si dedica esa tarea a un servicio web, el servicio web probablemente se ejecutará en muchos menos servidores que el resto de la aplicación, lo que significa que necesitará muchas menos conexiones a la base de datos. Lo cual es importante, porque las bases de datos generalmente no
TLDR; Es más fácil ajustar, escalar y almacenar en caché su acceso a datos cuando es algo que sucede dentro de un único servicio web dedicado que cuando es algo que sucede en muchas aplicaciones diferentes que utilizan diferentes idiomas y tecnologías.
Pensamientos finales
Por favor, no salgas de este pensamiento "Oh wow, siempre debería estar usando las API REST para obtener mis datos" o "Este idiota está tratando de decir que lo estamos haciendo mal porque nuestra aplicación web habla directamente con la base de datos, pero ¡nuestras cosas funcionan bien! " . El punto principal que estoy tratando de hacer es que diferentes sistemas y diferentes negocios tienen diferentes requisitos; En muchos casos, poner una API REST frente a su base de datos realmente no tiene sentido. Es una arquitectura más complicada que requiere justificar esa complejidad. Pero cuando se justifica la complejidad, hay muchos beneficios al tener la API REST. Ser capaz de sopesar las diferentes preocupaciones y elegir el enfoque correcto para su sistema es lo que lo convierte en un buen ingeniero.
Además, si la API REST se interpone en el proceso de depuración de cosas, es probable que haya algo mal o faltante en esa imagen. No creo que tener esa capa de abstracción añadida intrínsecamente dificulte la depuración. Cuando trabajo con sistemas grandes de n niveles, me gusta asegurarme de tener un contexto de registro distribuido. Quizás cuando un usuario inicia una solicitud, genere un GUID para esa solicitud y registre el nombre de usuario de ese usuario y la solicitud que realizó. Luego, pase ese GUID a medida que su aplicación se comunique con otros sistemas. Con la agregación de registros y la indexación adecuadas, puede consultar en toda su plataforma al usuario que informa el problema, y tener visibilidad de todas sus acciones y recorrer el sistema para identificar rápidamente dónde fallaron las cosas. De nuevo, es una arquitectura más complicada,
Fuentes: http://alistair.cockburn.us/Hexagonal+architecture https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing
fuente
Si entiendo correctamente qué es un DBAL , la respuesta es que una interfaz REST le permite usar cualquier idioma para sus clientes, mientras que un DBAL es una biblioteca que le permite usar un solo idioma para sus clientes.
Esto, a su vez, puede ser una ventaja para una empresa donde hay muchos equipos de desarrollo y no todos dominan el mismo idioma. Permitir que su software consulte directamente la base de datos sería equivalente en funcionalidad, pero como usted dice "mejor exponer una API REST limitada que la base de datos completa".
En términos más abstractos, usted mismo está respondiendo la pregunta:
... ya que existe este famoso aforismo que dice: "Todos los problemas en informática pueden resolverse mediante otro nivel de indirección". :)
fuente
El hecho de que esté dentro de la misma empresa no significa que deba exponer todo a todos. Las API REST son una forma de definir una relación limitada de consumidor / proveedor entre los equipos de una empresa, con un contrato claro. Amazon ha sido pionero en esta forma de organización.
Las API también proporcionan una capa de abstracción, lo que le permite usar un conjunto específico de expresiones idiomáticas: no necesariamente quiere hablar con sus consumidores en los mismos términos que se usan en su base de datos. Tampoco necesariamente quiere hablar con cada consumidor de la misma manera.
fuente
Está pensando que REST es para consultas de bases de datos y no lo es. REST representa el estado de algo en este momento. El uso de REST cambia o recupera una representación, pero eso es todo. Si ese estado está disponible por la base de datos, no importa y a nadie le importa porque la forma en que se produce esa representación no es parte de REST y tampoco lo son las consultas de la base de datos.
fuente