Full fuel API DDD, TS
Fullfuel API expone los contenidos consumidos por la APP Fullfuel. Esta API obtiene datos desde https://sedeaplicaciones.minetur.gob.es/ServiciosRESTCarburantes/PreciosCarburantes/help, los procesa y los expone de una manera más amigable. Además de esto, expone una serie de endpoints adicionales necesarios para el correcto funcionamiento de la aplicación. Más adelante se explican en detalle cada uno de los endpoints disponibles en esta API.
Esta API ha sido desarrollada haciendo uso de NodeJS y TypeScript, por lo que es necesario disponer del runtime de NodeJS instalado. Además de esto, es recomendable disponer de Docker para poder ejecutar el entorno de desarrollo.
Comenzaremos clonando la rama master de este repositorio a nuestro equipo. hecho esto y antes de proseguir, instalaremos las dependencias del proyecto ejecutando el siguiente comando en la raíz del proyecto:
npm install
Tras esto, deberemos crear el fichero de conficguración con las variables de entorno necesarias para poder ejecutar el proyecto. Es posible trabajar con un entorno de desarrollo local, pero recomendable utilizar Docker y Docker compose. Para ello:
/src/config
./logs
. Si elegimos console, los log serán pintados en la consola.docker-compose up -d
.
{
"timestamp": "2021-02-04T23:56:39.199Z",
"status": "OK",
"statusCode": 200,
"response": "Fullfuel app UP and running!"
}
/db/schema.sql
. Para poder ejecurarlo en el contenedor y crear el esquema ejecuteraremos el siguiente comando en la ruta raíz del proyecto:
docker exec -i api_db mysql -uMYSQL_USER -pMYSQL_PASSWORD fullfuel < db/schema.sql
Con el proyecto configurado y el esquema creado, podemos proseguir con los pasos necesarios para cargar contenido en nuestra aplicación.
Esta aplicación dispone de una serie de comandos para poder descargar datos desde los servidores de Minetur y almacenarlos procesados en nuestra base de datos y caché para que estos estén disponibles para consumir desde nuestra API. A continuación se muestran los pasos necesarios para poder realizar una carga inicial de contenidos en nuestro proyecto:
npm run build
npm run ccaaJob
Al ejecutar el comando en nuestro proyecto, podríamos encontrarnos el siguiente error:
UnhandledPromiseRejectionWarning: Error: Error on persisting CCAAs. Error: SequelizeAccessDeniedError: Access denied for user ‘’@’172.18.0.1’ (using password: NO)
Esto es debido a que, al ejecutar el comando de npm, no se están teniendo en cuenta las variables de entorno que hemos configurado previante en nuestro proyecto. Para solucionarlo, deberemos realizar el siguiente ajuste en la setencia asociada al comando en el fichero package.json
.
Agregaremos antes de la palabra node lo siguiente:
env-cmd -f ./src/config/docker.env
De modo que el comando debería quedar de la siguiente manera:env-cmd -f ./src/config/docker.env node build/apps/scheduledTasks/jobs/CCAAJob.js
Es importante que este cambio no lo subamos al repositorio de código, por lo que podemos mantenerlo en un stash local. Deberemos aplicar los mismos cambios al resto de comando que queramos ejecutar.
Cuando ejecutes este comando, es posible que te encuentres un mensaje como el siguiente Current hour is XX and job should not be running. Esta es una validación que previene ejecutar el comando por error en entornos productivos cuando no debe ejecutarse. Esta validación podemos inhabilitarla en nuestro entorno local de la siguiente manera:
npm run fuelStationsJob
/apps/shceduledTasks/jobs/FuelStationsJob
. Deberemos comentar los métodos validateJobExecutionTime()
y validateIfJobExecuted()
.npm run fuelStationsJob
Estos son los dos comandos principales y necesarios para hacer funcionar este proyecto. Existen otros comandos disponibles en el fichero package.json
, pero estos no son necesarios para comenzar a trabajar en el proyecto, por lo que de momento no serán documentados.
Tras haber configurado el proyecto y haber realizado nuestra primera carga de datos, ya podemos utilizar la API en nuestro entorno local 🎉🎉🎉
A continuación se muestran los endpoints disponibles para poder consultar en nuestra API. Esta documentación pretende migrarse a Swagger próximamente, pero de momento por algo hay que empezar 😉
http://localhost:SERVER_PORT
El resto de endpoints disponibles en esta API requiren un token para poder ser usados. Este token es el que habremos configurado en nuestro archivo .env con el identificador API_TOKEN.
La manera de usarlo es tan sencilla como indicar en la cabecera el parámetro Authorization y asignarle el valor bearer API_TOKEN. Teniendo esto en cuenta, podemos continuar.
Estaciones de servicio: Las estaciones de servicio pueden ser consultadas usando diferentes peticiones. Es importante recordar que en todas ellas debemos usar el parámetro de autorización en la cabecera.
Listado de estaciones de servicio por geoposición: Esta petición debe rebicir obligatoriamente los parametros latitud, longitud y radio de búsqueda. Podríamos enviar un cuarto parámetro opcional que consistiría en un valor booleano (true/false) que indicaría si queremos recibir únicamente las estaciones de servicio que se encuentren abiertas al momento de realizar la consulta:
GET http://localhost:SERVER_PORT/v1/fuelstations/list/geo/{latitud}/{longitud}/{radio}/{soloEstacionesAbiertas(opcional)}
.
Listado de estaciones de servicio por ID de estación de servicio: Similar a la petición anterior, pero en lugar de listar las estaciones de servicio próximas a un radio, esta petición lista las estaciones de servicio que nosotros solicitemos por sus Ids. Los parametros obligatorios son latitud, longitud y el listado de ids separados por comas (ejemplo: 1,2,3):
GET http://localhost:SERVER_PORT/v1/fuelstations/list/id/{latitud}/{longitud}/{ids}
.
Detalle de una estación de servicio: Mediante este endpoint podremos consultar el detalle completo de una estación de servicio particular. Para obtener esta respuesta debemos mandar obligatoriamente los parámetros latidud, longitud e ID de estación de servicio:
GET http://localhost:SERVER_PORT/v1/fuelstations/detail/{latitud}/{longitud}/{id}
Subscripciones: Las subscripciones son la manera de saber si disponemos de usuarios interesados en las actualizaciones sobre el precio del combustible de una estación de servicio particular. Al ser una aplicación totalmente anónima, solo almacenamos el número de subsccriptores activos para saber si debemos notificar o no al tópico específico:
Agregar un nuevo subscriptor: Agregaremos un nuevo subscriptor al computo total. Los parámetros necesarios son el ID de la estación de servicio y el identificador del combustible:
PUT http://localhost:SERVER_PORT/v1/subscriptions/add/{idEstacionServicio}/{idCombustible}
Eliminar un subscriptor: Restaremos un subscriptor al computo total. Los parámetros necesarios son el ID de la estación de servicio y el identificador del combustible:
PUT http://localhost:SERVER_PORT/v1/subscriptions/remove/{idEstacionServicio}/{idCombustible}
De momento estos son los endpoints disponibles en esta API.
Gran parte del código fuente de la lógica de la aplicación ha sido testeado con tests unitarios y funcionales. Estos tests se encuentran disponibles en /tests/contexts
. Los tests han sido realizados usando Jest. Para poder ejecutarlos utilizaremos el siguiente comando:
npm run test
Esta aplicación utiliza la convención Conventional Commits 1.0.0 para el estilo de los mensajes de los commits. Es importante que se respete esta convención para poder realizar commits sobre la aplicación, ya que existe un preHook que se encarga de validarlo.