Hola, ¿bienvenido a LCBO API?
Si te preguntas "¿qué es una API LCBO?", déjame explicarte. En Ontario, Canadá, todas las ventas de bebidas alcohólicas pasan a través de una corporación de propiedad gubernamental llamada Junta de Control de Licores de Ontario (LCBO), que se encarga de la venta minorista y la distribución de bebidas alcohólicas en toda la provincia. La LCBO tiene numerosas tiendas minoristas y un sitio web que alberga un catálogo de cada producto, tienda e incluso niveles de inventario. Publican un catálogo de temporada con recetas, editoriales y otro contenido llamado Comida y bebida. También aportan miles de millones de dólares de ingresos a nuestro sistema de salud pública anualmente. Es una situación fascinante si lo piensas, otros lugares tienen sistemas similares pero, que yo sepa, ninguno tiene la amplitud y profundidad de la LCBO. Ahora ya sabes lo que es, genial, ¿eh?
Esto podría resultarle interesante incluso si no vive en Ontario, Canadá, si:
Durante todo el transcurso de este proyecto he luchado muchísimo con la idea de aceptar apoyo financiero. Por un lado, LCBO API lo necesitaba y, por otro, estaba cansado de las complicaciones que causaría. Bueno, ¡ahora tengo LA solución PERFECTA para este problema!
Estoy en tratamiento por un cáncer de sangre en este momento, específicamente un linfoma difuso de células B grandes. Voy a escribir más sobre eso pronto en otro lugar, pero durante el año pasado personas de todas partes me apoyaron en todo lo que pudieron y eso me ha cambiado. ¡Quiero que hagamos algo grande para demostrar que a nosotros también nos importa!
Si alguna vez quiso apoyar este proyecto en el pasado, haga una donación a Hamilton Health Sciences en nombre de LCBO API, me están salvando la vida.
Donar a Hamilton Health Sciences
Estoy en tratamiento en el Centro Oncológico Juravinski, pero realmente puedes elegir cualquier opción o dejar la predeterminada. No importa si la cantidad es pequeña o grande, me avisarán cuando hagas la donación. Tabularé una lista para seguir el total, ¡veamos cuánto podemos recaudar!
Por último me gustaría hacer una mención especial a mi lugar de trabajo, Crowdmark. Han sido increíblemente amables y comprensivos durante todo esto y, literalmente, no habría podido hacer esto sin ellos. Trabajamos incansablemente para promover el status quo de la evaluación en la educación superior. Si le interesa la educación y el aprendizaje, le insto a que nos consulte.
En el otoño de 2008 yo era un desarrollador web recién formado con algunos años de experiencia en mi haber. Tenía hambre de un desafío y de algún reconocimiento. Las aplicaciones se estaban convirtiendo en una cosa en ese momento y tenía muchas ganas de crear una. Decidí que quería crear uno que requiriera que primero creara esta API. ¿Nunca construí esa aplicación?
Si analizas este código base con suficiente tiempo, es probable que encuentres momentos de frustración, callejones sin salida, asuntos confusos, etc. Realmente espero que no te concentres en eso ni en ninguna negatividad que puedas encontrar. Ya no soy esa persona y tampoco quiero que tú seas esa persona. ¡Soy un libro abierto sobre esto! Abre un tema y hazme una pregunta, seré lo más honesto y respetuoso posible, solo te pido que hagas lo mismo.
Estoy lanzando este proyecto bajo GNU GPLv3, creo que esta es la opción más justa y responsable para un proyecto como este. Si no siente lo mismo, abra un problema y podremos tener una discusión abierta al respecto. Sólo les pido, respetuosamente, que no reutilicen la marca y el diseño. Estoy de acuerdo con la reutilización de la documentación, pero el estilo, la identidad y la marca deben cambiarse si desea implementar su propia versión aislada de esta aplicación.
¿Qué pasaría si en lugar de una aplicación monolítica que intentara hacer todo con un solo estilo, en un solo lugar, pensáramos en algo más grande? ¿Qué pasaría si el rastreador volviera a ser un proyecto separado, responsable de recopilar y normalizar datos, otros pudieran crear nodos API en cualquier plataforma que quisieran, esos nodos se registrarían con el proveedor de datos y recibirían datos actualizados a medida que estuvieran disponibles y proporcionarían esos datos a usuarios de todo tipo.
En lugar de docenas de servidores API similares que intentan hacer lo mismo, luchando por los recursos de LCBO.com, podríamos centrar nuestros esfuerzos en generar valor a partir de estos datos en lugar de luchar por la propiedad de ellos. Podríamos involucrar a otras disciplinas para generar nuevo valor más allá de lo obvio, involucrar a las comunidades de cerveza y vino artesanales, aprovechar esto y hacerlo más grande que solo Ontario.
No sé qué tan factible sería algo así, pero sé que si otros están interesados, me encantaría tener estas discusiones.
Además, tal vez deberíamos considerar cobrar a los usuarios corporativos una tarifa razonable para acceder a los nodos API, ese dinero podría usarse para financiar los costos de alojamiento para mantener las cosas sostenibles, también podría usarse para financiar programas de apoyo para personas que no pueden beber. o que no quieren beber, o que quieren beber menos, para contribuir a nuestras comunidades y realmente marcar la diferencia.
Pero necesito que otros me ayuden a compartir la carga de mantener y administrar todo esto; mi salud y felicidad y la de mi familia son la prioridad número uno, seguida de mi carrera y luego mis amigos y mi comunidad. Este proyecto ya no puede ser mi principal fuente de tiempo, no es sostenible para mí y no es saludable para mí. Pero si este mensaje lo inspira, comuníquese conmigo, idealmente de manera abierta, pero al principio en privado también está bien.
¡Espero que esto te entusiasme!
No pude evitarlo, escribí más sobre mis ideas en esto: doc/lcboapi-proposed.md
Ahora, una vez aclarado esto, podemos empezar a analizar para quién realmente hice esto y qué me emocionó e inspiró para hacer esto en primer lugar: la oportunidad de aprender, crecer y ayudar a otros a hacer lo mismo. Para aquellos de ustedes que tengan curiosidad, veamos a dónde va esto.
Probablemente puedas ejecutar la aplicación directamente en tu entorno host, no requiere nada demasiado sofisticado en lo que respecta a las dependencias del sistema. Desarrollo en hardware de Apple; si usted también lo hace, es posible que tenga éxito utilizando Postgres.app y Homebrew para instalar Redis. De lo contrario, puedes utilizar Docker.
Si tiene experiencia con otra plataforma, haga un PR o un problema y podremos trabajar para agregar su plataforma al README.
Además, si lo que sigue aquí no tiene sentido para usted, abra un problema, tal vez podríamos hacer un screencast para demostrar el proceso, o tal vez alguien que sea bueno en eso se encargaría de eso.
Lo que describo a continuación es sólo una forma de configurar un entorno de desarrollo para ejecutar la API LCBO en su computadora. Si otros tienen mejoras (hay espacio para muchas, un script de punto de entrada para iniciar la base de datos de desarrollo, por ejemplo) o incluso enfoques diferentes, como usar Vagrant + VirtualBox, abrir un problema o un PR, estaré feliz de agregarlos.
Si quieres ayudar, quiero habilitarte.
config/secrets.yml
y .env
Primero, necesitarás establecer alguna configuración que no se proporciona en el repositorio público. La razón por la que se hace esto es para proteger datos privados como claves API y tokens secretos, pero también porque algunos desarrolladores pueden preferir configuraciones ligeramente diferentes para sus preferencias personales y cosas así.
Hay un par de archivos que necesitarás crear, config/secrets.yml
y .env
. Hay versiones de plantillas en el repositorio en config/secrets.yml.example
y .env.example
, puedes copiar esos archivos para comenzar:
cp config/secrets.yml.example config/secrets.yml
cp .env.example .env
Si solo desea iniciar la aplicación y acceder a ella localmente, debería estar listo en este punto. Si desea poder utilizar el rastreador y guardar una instantánea en Amazon S3, deberá agregar sus credenciales y depósito de AWS a config/secrets.yml
.
El resto de las configuraciones solo importan realmente en un entorno de producción, no se usan realmente o solo importan si no le gusta la preferencia predeterminada. Como siempre, si necesita una aclaración, ábrala y publíquela y estaré encantado de ayudarle.
Primero, necesitará instalar el cliente Docker para su sistema; puede obtener más información al respecto aquí. Una vez que haya instalado Docker, puede comenzar:
A continuación, necesitarás construir los contenedores:
docker-compose build
Una vez hecho esto, puede iniciar todo emitiendo:
docker-compose up
En este punto, no tiene ningún dato en la base de datos, por lo que si carga la aplicación, http://localhost:3000, no hará mucho, después de todo, proporciona datos y no hay datos en ella. Así que hagamos algo al respecto.
Continúe y cierre los contenedores:
Ctrl-C
Es decir, presione las teclas Control
+ C
simultáneamente.
Puede descargar un archivo del último volcado de la base de datos de producción desde mi cuenta personal de Amazon S3 aquí. Tenga en cuenta que hay tablas confidenciales (correos electrónicos, usuarios, claves) y que los datos se han excluido de este archivo.
Descargue y extraiga el archivo en el directorio tmp
de este proyecto:
cd tmp
curl -O https://heycarsten.s3.amazonaws.com/lcboapi-2019-01-21.tgz
tar xzf lcboapi-2019-01-21.tgz
cd ..
El archivo pesa aproximadamente 300MiB, por lo que la descarga puede tardar un poco dependiendo de la velocidad de su conexión (esto sucede en la línea que comienza con curl
).
Una vez que haya descargado y extraído el archivo de la base de datos, puede cargar los datos en la base de datos:
docker-compose run --rm app rake db:create
docker-compose run --rm app bash -c 'pv tmp/lcboapi-2019-01-21.sql | psql -q -h db -U $POSTGRES_USER $POSTGRES_DB > /dev/null'
La primera línea, que termina en rake db:create
, creará los esquemas de la base de datos en Postgres para desarrollo y prueba, la segunda línea cargará el volcado de la base de datos en la base de datos de desarrollo. La barra de progreso indica la cantidad de datos que se han canalizado a la base de datos; una vez que se complete, se crearán los índices. Esto puede llevar algún tiempo dependiendo de su máquina, es una buena cantidad de datos. Luego puedes iniciar la aplicación nuevamente:
docker-compose up
También puede eliminar de forma segura el archivo comprimido y el archivo SQL extraído de su directorio tmp
en este punto.
Si te resulta tedioso escribir
docker-compose
una y otra vez, busca los alias de shellPuede agregar una línea de alias a su perfil de shell como
alias dc=docker-compose
y luego puede simplemente escribirdc
en lugar de tener que escribirdocker-compose
cada vez. ✅¿Piensa en otros alias que podrías crear para mejorar esto aún más?
Ahora, navega a http://localhost:3000/products/438457
Auge. ¡Tienes la API LCBO ejecutándose en tu computadora! ? ? ?
Cuando haya terminado de trabajar en la aplicación, simplemente presione Ctrl+C
para cerrar todo. La próxima vez que quieras volver a trabajar en ello, ejecuta docker-compose up
y ¡listo!
Si agrega una nueva gema al Gemfile
, deberá reinstalar los paquetes y actualizar las dependencias. Docker es bastante bueno para hacer esto, puede saber cuándo cambia Gemfile
y sabe cómo reconstruir el contenedor app
por usted.
Para iniciar una consola Rails e inspeccionar objetos dentro de la aplicación:
docker-compose exec app rails c
Una vez que se esté ejecutando, puedes hacer cosas como:
Obtenga el primer producto en la base de datos:
Product.first
Encuentre la tienda minorista LCBO n.° 25 (mi tienda local):
Store.find(25)
Si cambias el código en la aplicación, ¡deberás emitir la reload!
comando en la consola para actualizar los cambios.
Dentro de la carpeta spec
, encontrará el conjunto de pruebas para la API LCBO. Lamentablemente no es completo, pero tampoco está tan mal. He luchado toda mi carrera para mantener conjuntos de pruebas con los que esté satisfecho. ¡Deberíamos mejorar estas pruebas!
Para ejecutar el conjunto de pruebas:
docker-compose exec app rspec
Verás un montón de puntos verdes .
, cada uno de ellos representa un caso de prueba aprobado. Eso es bueno. Si ocurre una falla, verás una F
roja, eso es malo... ¡SOLO ES BROMA! ¡En realidad es bueno! Las pruebas le brindan el poder de cambiar cosas en una base de código existente y ver si causa alguna regresión a la funcionalidad existente. Por supuesto nada es perfecto, pero te puedo decir sin lugar a dudas, por experiencia, que las pruebas son buenas.
A medida que las aplicaciones se vuelven cada vez más grandes y más complejas, no tener pruebas se convierte en una pesadilla literal, hace que cambiar su aplicación y agregar funciones sea un proceso extremadamente frágil. Cosas como el uso de lenguajes con sistemas de tipos y otros paradigmas de programación diferentes pueden ser de gran ayuda con esto también, pero soy de la opinión de que realmente no hay reemplazo para al menos un conjunto de pruebas de aceptación sólido.
Esta es la parte de la API LCBO que hace que todo sea posible. Los rastreadores de sitios web complicados son difíciles de crear y mantener. La primera versión de la API LCBO tenía un conjunto de pruebas completo para el rastreador, cuando todo cambió hace muchos años, abandoné ese código base y construí algo lo más rápido que pude en este.
La lógica del rastreador se encuentra en lib/crawler.rb
, desde allí verá todas las diversas tareas que suceden en sucesión para abarcar un rastreo completo de los sitios web de LCBO.
La lógica del analizador se encuentra en lib/lcbo.rb
y todos los archivos dentro de lib/lcbo/*
, esto incluye todas las diversas solicitudes que deben realizarse y el código responsable de convertir los datos de esas solicitudes en datos estructurados. que finalmente puede ir a la base de datos.
Diseñé el rastreador para realizar solicitudes en serie; este es un muy buen enfoque a seguir cuando se rastrea un sitio web. Es simple para uno, cuál es siempre la mejor ruta a tomar si es posible, y es educado. Podríamos ejecutar n trabajos de AWS Lambda y rastrear cada página en LCBO.com en unos pocos segundos, pero eso sería de mala educación y probablemente haríamos DDoS en su sitio web momentáneamente, lo cual no es bueno.
/manager
)Esto abarca una aplicación Ember, cuando te registras o ingresas a la API de LCBO y generas claves de API, esto es con lo que estás interactuando. Está bastante desactualizado, no he intentado construirlo. He estado usando Ember desde el día cero, así que si tienes alguna pregunta sobre esto, haz preguntas. De hecho, disfrutaría mucho discutir esta parte de la API de LCBO y trabajar con todos ustedes para mejorarla.
/static
) Este contiene un sitio de intermediarios; cuando visita lcboapi.com, esto es lo que está viendo. También contiene una aplicación React muy pequeña (también desactualizada) que es la cosa "Pruébalo" a la derecha de la página de inicio. Tiene su propio Gemfile y script de compilación static/generate
, cuando se ejecuta, crea el sitio y sincroniza los cambios en la carpeta public
. En las aplicaciones Rails, la carpeta public
se sirve como contenido estático.
Hay MUCHOS callejones sin salida en este código base, ramas que recorrieron el 40-60-80% del camino hacia una característica y luego se estancaron, experimentos, etc. Como siempre, si encuentras algo que te guste. simplemente presente un problema y le responderé tan pronto como pueda.
También sería genial si pudiéramos resolver algunos de los callejones sin salida aquí, estaría muy interesado en finalmente agregar JSON: API y GraphQL. ¡¡¡El diseño de respuesta API actual es de 2008 !!! En cierto modo me sorprende que nadie se queje nunca de ello.
La característica número uno, con mucho, más solicitada que nunca implementé fueron las categorías, está más o menos aquí, olvidé por qué nunca la envié, no recuerdo qué cosas finales tuvieron que encajar, pero tal vez esa sería una buena primera vez. ¿Qué hay que abordar? También están los Productores y los Orígenes que nunca terminaron del todo.
También tengo muchos otros repositorios y pequeños experimentos que hice a lo largo de los años. Siempre me fascinó la idea de la predicción del nivel de inventario. En algún lugar hay una herramienta de análisis de volcados de conjuntos de datos escrita en Go para analizar los volcados CSV de un inventario de productos en particular. durante un conjunto de tiempo. Estaría feliz de publicar esas cosas también si hay interés.
Lo dejaré aquí por ahora y esperaré a recibir noticias tuyas. Me encantaría seguir agregando a esta base de conocimientos en cualquier forma que la gente quiera ver (screencasts, entrevistas, documentación en línea, etc.). También quiero que usted haga lo mismo; si no está seguro, pregunte. ❤️