Sí, una combinación de aplicaciones Rails y API puede compartir una base de datos. Esta es una mala idea común que he visto varias veces en los últimos años en clientes mayores / mayores. Si bien es un buen proyecto para un consultor como yo deshacer (largo pero no arriesgado = buena rentabilidad), es mejor no hacerlo en primer lugar.
El enfoque técnico es simple: configura database.yml
(o DATABASE_URL
en las variables de entorno) para apuntar a la misma base de datos. Voila! Estás compartiendo la base de datos entre dos aplicaciones.
Excepto: la única constante es el cambio, y ahora tienes que revisar dos bases de código sincronizadas. Veamos algunos problemas comunes y sus soluciones que causan problemas:
- ¿Qué es el software de wireframing? ¿Cómo se traza un sitio web?
- Después de aprender los conceptos básicos de JavaScript, ¿qué debo aprender a continuación?
- Cómo escribir un script de Python para abrir una página web e iniciar sesión en un sitio web en segundo plano automáticamente tan pronto como me conecte a LAN
- Cómo obtener una respuesta al pasar los parámetros en la URL asp.net c #
- ¿Por qué algunos sitios web implementan su enlace de cierre de sesión como una publicación de formulario a través de JavaScript frente a una solicitud GET antigua y simple?
Migraciones : ¿en qué aplicación viven? “Ambos” es la respuesta más común cuando las dos aplicaciones son mantenidas por diferentes equipos. Alguien que solo se preocupe por una aplicación debe recordar tener una copia de la otra y realizar migraciones o su desarrollo local misteriosamente no estará sincronizado con la producción.
schema.rb
: ¿Cuál es canónico? La respuesta es que ambos deben ser, lo que significa que deben estar sincronizados. Cada vez que la aplicación ejecuta una migración que la otra no, no están sincronizados. Esperemos que pueda limitar esto a solo unos segundos durante las implementaciones. Ahora, sé que los expertos en git dicen:
Git submodules / subtrees : puedo garantizar que no confirmará los submódulos y sus dependencias correctamente. Nadie puede, la interfaz de usuario de la línea de comando se entiende mejor como un templo de una película de Indiana Jones: tiene un tesoro brillante, pero cada pasillo de apariencia normal está lleno de trampas mortales. Los subárboles son más confiables, pero hará que los conflictos de fusión formen parte de su vida diaria. Tampoco conozco ninguna de las GUI de git bonitas, por lo que está buscando capacitación adicional en línea de comandos para todo su equipo. Oh, pero nos hemos perdido algo importante:
Modelos : deben estar sincronizados. O no debería. ¿Qué? Tienen que permanecer en perfecta sincronización en las validaciones porque Rails no tiene un buen soporte para las restricciones de la base de datos, por lo que cada vez que las dos tengan validaciones diferentes, una de las aplicaciones se sorprenderá y se desanimará al saber que Model.find(123).valid?
puede devolver false
. Si las dos aplicaciones tienen propósitos diferentes para los modelos, pueden (¡y deberían!) Tener un código diferente en los modelos, aunque los desarrolladores que trabajan en ambas tendrán dificultades para recordar que Order#finalize
solo envía confirmaciones por correo electrónico en la aplicación, pero no en la API porque la API es utilizada por dropshippers que manejan su propio compromiso con el cliente, etc. ActiveRecord viola el Principio de Responsabilidad Única, por lo que realmente lo que necesita hacer es comprender cada propósito de los modelos (desinfección de entrada del usuario, acceso a la base de datos, normalización de datos, lógica de dominio, basura de subtipo) cajón …) y mantenga exactamente el subconjunto correcto de ellos sincronizados.
Gemas : ¡Mueva las migraciones y modelos a una gema compartida! Sí, he visto esta estrategia. Ahora tiene un tercer repositorio git para mantener las sincronizaciones sincronizadas con … con la ventaja de que debe mantener manualmente la especificación de la versión del Gemfile
. Y su historia de implementación debe tener en cuenta el acceso de lectura a su repositorio de GitHub. Y ahora un montón de sus dependencias se cargan de forma transitiva desde la gemspec de la gema (por lo que cualquiera que toque la gema necesita saber cómo se usan en las aplicaciones) o se repite en la aplicación Gemfile
(se desviarán de la sincronización perfecta y usted tendrá algunos errores increíblemente sutiles y terribles cuando se cargan dos versiones a la vez). Pero todavía hay un último asidero para arañar mientras caemos de los acantilados de la desesperación:
Un repositorio para gobernarlos a todos : ¡calentarse! Coloque ambas aplicaciones en un repositorio de git y tenga un enlace simbólico que necesita del otro: schema.rb
, db/migrate
schema.rb
, app/models
, spec/models
, quizás partes de lib
. No puede hacer cosas diferentes en los modelos a menos que sea realmente poco entusiasta acerca de cómo usa los modelos AR, pero eso puede no ser una gran pérdida. No he tenido que soportar Windows profesionalmente durante unos años, pero creo que su compatibilidad con enlaces simbólicos aún no es excelente, esto puede ser un factor decisivo para usted. He visto funcionar este enfoque.
OK, Smartypants Mc Grizzled Veterano, ¿cuál es el enfoque correcto?
La respuesta a “Me duele cuando hago esto” es “Así que no hagas eso”. Sé de dos alternativas.
Primero, haga que su aplicación Rails sea un consumidor de su API. Use ActiveResource o una de las otras gemas de consumo de API para golpear la API. Puede revolver por separado, modelar datos por separado y no tiene que mantenerlos sincronizados. El costo de la compensación es que tiene una aplicación web más lenta con nuevos modos de falla como API inactiva / lenta, cambios importantes, etc. Pero está comiendo su propio alimento para perros en la API, lo cual es bueno para satisfacer a los clientes externos de API.
El mejor enfoque es desechar la idea de aplicaciones separadas. Haga que su aplicación Rails sirva a su API. Lo sé, los microservicios son geniales y quieres poder escalarlos por separado porque la API es mucho más delgada que la aplicación, pero de todos modos necesitas un plan de escala para tu aplicación, y vale la pena minimizar las partes móviles con un genérico ” servidor de aplicaciones “en el que pones el dial. Todo está estrechamente acoplado y mal delineado: esa es la forma de Rails.
Lamento que esto haya resultado un poco sarcástico, pero es algo que no es extraño y los enfoques tienen modos de falla no obvios porque el tema viola muchos supuestos no declarados de Rails como “Soy la única base de código que habla directamente con esta base de datos “que dificulta innecesariamente el crecimiento de aplicaciones grandes y confiables. Estoy buscando mi mejor código, si quieres unirte a mí en ese viaje.