¿Por qué la gente hace API REST en lugar de DBAL?


32

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.


3
Parece que solo ha trabajado con aplicaciones que son básicamente CRUDAS: ¿algunos usuarios ingresan datos con formularios y otros usuarios leen los datos con los mismos formularios o con impresiones de informes? Si nunca ha trabajado con un sistema que necesita un modelo de dominio complejo y sofisticado, entonces puedo ver cómo tendría esa mentalidad particular. Muchas aplicaciones requieren esa capa adicional de indirección para hacer cosas.
RibaldEddie

1
He trabajado con API (no necesariamente REST) ​​que (entre otras cosas) realizó cálculos sobre los parámetros que se le pasaron. Tal vez se utilice un DBMS en esos cálculos, pero presumiblemente gran parte de la lógica no vive en el DB. Sin embargo, las API internas de las empresas en las que he trabajado no hacen esto. Simplemente consultan un DBMS y escupen los resultados de la consulta SQL al pie de la letra. Simplemente me parece que las API REST a menudo (no siempre, a menudo) se escriben para estar a la moda, no para ser prácticas.
neubert

1
Definitivamente, existen peculiaridades en el diseño de la API REST que dificultan el diseño de un dominio complejo; a la mayoría de los desarrolladores que he conocido a lo largo de los años no les importa el diseño. Quieren producir código lo más rápido posible para que sus jefes los amen y piensen que son estrellas de rock. Cuando combinas ese hecho con una tendencia como REST, obtienes API de espagueti moderna pero poco práctica. No tiene nada que ver con REST en sí.
RibaldEddie

3
¿Alguna vez se preguntó cómo algunas compañías web informan que un pirata informático robó sus registros de usuario completos? ¿Alguna vez se preguntó cómo lo hizo el hacker? Cuando crees que un servidor web tiene una conexión directa a la base de datos, te das cuenta de que una vez que el servidor web ha sido pirateado, el atacante tiene acceso completo y sin restricciones para seleccionar cualquier cosa de la base de datos que le guste. Pegarlo detrás de un nivel medio y el atacante solo puede llamar a métodos en el nivel medio. No diré que es seguridad instantánea, pero es significativamente mejor.
gbjbaanb

1
@gbjbaanb: Mi punto es que el servidor web puede acceder a los datos a través del servidor de descanso, por lo que si el servidor web es pirateado, el atacante también puede acceder a los datos a través del servidor de descanso sin tener que hackear el servidor de descanso.
JacquesB

Respuestas:


28

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:

  • Obtiene un acoplamiento entre su código y el suyo, particularmente, hay un acoplamiento muy fuerte entre la estructura de su base de datos y su código;
  • Su cliente puede hacer algunas cosas bastante indeseables en su base de datos, ya sea actualizando datos que no deberían, escribiendo una consulta que lleva demasiado tiempo, bloqueando algo porque no adquieren bloqueos limpiamente ...
  • Si ha hecho una elección menos que óptima en la estructura de su base de datos, salir de esa opción puede ser muy difícil, especialmente si no tiene una buena manera de hacer que sus clientes migren a nuevas estructuras.

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.


24

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.


1
Me gustó su respuesta, pero tengo algunas consultas más que vienen con ella. ¿Qué tal la pérdida de rendimiento con la introducción de otra capa de abstracción? Además, ¿no se trata de un solo punto de falla (si esto se cae, todo lo demás se cae) y un posible cuello de botella (cada aplicación espera la conexión de la base de datos del grupo)?
Sactiw

@satich: No entiendo exactamente lo que estás preguntando, ¿puedes ser más específico? ¿Está preguntando sobre un solo punto de falla con o sin un nivel REST?
JacquesB

La capa adicional puede ser útil si tiene más de una aplicación comunicándose con ella
Ewan

@Ewan: Sí, esto es lo que digo en el primer punto.
JacquesB

1
@JacquesB Suponga que varias aplicaciones web comparten la misma base de datos pero no los mismos datos, es decir, cada una realiza operaciones CRUD en un conjunto de datos separado dentro de esa base de datos, básicamente no hay intercambio de datos en sentido verdadero. Entonces, ¿tiene sentido poner aplicaciones detrás de un marco de persistencia relajante (también se supone que DB proporciona un buen nivel de concurrencia en las consultas)? Además, ¿ese marco no será un cuello de botella y un punto único de falla para tantas aplicaciones web que interactúan a través de él?
Sactiw

12

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


Muy buena respuesta, vale la pena leer. ¡Gracias por tomarse el tiempo de escribir esta gran respuesta!
Dominic

6

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:

Entonces, es una capa adicional de indirección que ralentiza el proceso de diagnóstico

... ya que existe este famoso aforismo que dice: "Todos los problemas en informática pueden resolverse mediante otro nivel de indirección". :)


6

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.


3

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.


No estoy sugiriendo que las consultas de la base de datos == REST. Ciertamente, REST es capaz de ser mucho más que una capa de abstracción de base de datos, pero en las últimas dos empresas para las que he trabajado eso es esencialmente todo lo que es: una capa de abstracción de base de datos. No hace nada más que traducir solicitudes HTTP a consultas DB. Y si eso es todo lo que estás haciendo, me parece que DBAL te servirá mejor. De hecho, me parece que la única razón por la que algunas personas usan REST en estos días es porque está de moda, no porque sea la mejor solución para la tarea en cuestión.
Neubert

@neubert ¿DBAL funciona directamente a través de Internet como lo hace REST?
Rob

Seguro. Puede decirle a MySQL que use una dirección IP / nombre de dominio / puerto que pertenezca a otra computadora en Internet. Puede usar el túnel SSH, así como (creo) la autenticación SSL también. Presumiblemente, otros DBMS funcionan de manera similar.
Neubert

@neubert: en ese caso, la API REST es un DBAL, ¿no?
RemcoGerlich

2
@RemcoGerlich: claro, pero el uso de REST API como su DBAL puede agregar una capa intermedia que es innecesaria y dificulta el diagnóstico de problemas. Quiero decir, si vas a usar una definición suficientemente amplia de DBAL, entonces podrías considerar que los SERP de Google son DBAL. Solo tiene que analizar HTML para obtener los datos paginados de los servidores de Google ...
neubert
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.