diff --git a/README.md b/README.md index 6f415d1..5216266 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,67 @@ por el puesto de programador Go. - NATS CLI - Make, si prefieres la comodidad de usar Makefile +## Comandos + +### Registrar un sensor + +- Campos obligatorios: `sensor_id` y `sensor_type`. +- Campos opcionales: `sampling`, `thresholdabove` y `thresholdbelow`. + +`nats req sensors.register '{ + "sensor_id": "sensor-001", + "sensor_type": "temperature", + "sampling": 3600, + "thresoldabove": 50.0, + "thresoldbelow": -10.0 + }'` + +### Actualizar configuración sensor + +- Campo obligatorio: `sensor_id` y la presencia de al menos un parámetro. + +`nats req sensors.update '{ + "sensor_id": "sensor-001", + "sensor_type": "temperature", + "sampling": 10, + "thresoldabove": 100.0, + "thresoldbelow": -15.0 +}'` + +### Obtener información de un sensor + +- Campo obligatorio: `sensor_id`. + +`nats req sensors.get '{ + "sensor_id": "sensor-001" +}'` + +### Obtener valores de un sensor + +- Campo obligatorio: `sensor_id`. +- Campos opcionales: `from` y `to` en formato RFC3339. Si no se especifican, se toman los últimos 7 días. + +`nats req sensors.values.get '{ + "sensor_id": "sensor-001", + "from": "2025-10-03T00:00:00Z", + "to": "2025-10-10T23:59:59Z" +}'` + +### Obtener listado de sensores + +No hay _payload_, pero hay que poner comillas dobles o si no se queda esperando +una entrada de datos. + +`nats req sensors.list ""` + +### Suscribirse a un sensor + +`nats sub sensors.data.sensor-001` + +### Suscribirse a todos los sensores + +`nats sub sensors.data.*` + ## Consideraciones Hay partes de códigos que son _snippets_ extraídos de una librería de autoría @@ -16,6 +77,8 @@ propia. [Repositorio GitHub](https://github.com/zepyrshut/gopher-toolbox). De las cuales son: - El _logger_ usando la _stdlib log/slog_. +- La conexión con la base de datos, usando el controlador [pgx](https://github.com/jackc/pgx). + ## Bitácora @@ -57,3 +120,60 @@ Para el registro de valores y mantener ambos se ha usado el patrón decorador qu bajo un mismo _struct_ se incluye las dos implementaciones y se llama a ambas funciones. Desde la capa servicios sólo tiene que llamar al decorador sin saber los detalles de la implementación. + +### Continuamos con los servicios + +Con el repositorio sin implementar, se puede realizar los servicios. En ese +proyecto ha quedado muy básico, sirviendo solamente de enlace entre los +controladores y el repositorio. + +Cuando se creó el _broker_ de NATS, inicialmente fue para crear una interfaz de +mensajería donde se pudiese manejar _websockets_, _SSE_ y otras mensajerías pero +se consideró que había otras prioridades. Así se quedó. + +### Y finalmente los controladores + +Ahí tuve muchas dudas con el entendimiento de NATS, estaba muy arraigado en el +patrón REST, y cambiar la mentalidad costó un poco, al final mirando un poco la +documentación me quedé con los conceptos clave: + +1. Está basado en asuntos, los canales se crean de forma jerárquica. +2. Cuando se hace un _subscribe_, se suma a un canal del asunto dado. +3. Para escribir en el canal, hay que hacer el _publish_. +4. Finalmente para solicitar un recurso, está el _request_. + +Esto es todo, entonces los controladores de la entidad _sensors_ están +constituidos por una serie de _endpoints_ haciendo las acciones que se solicita. + +## LLMS + +He usado Claude para la toma de decisiones y ayuda con el _boilerplate_, que no +es poca cosa, además también se ha usado para la generación de las pruebas +unitarias, además de resolución de algunos problemas complejos. + +## Generadores de código + +Existen generadores de código para Golang, de hecho, se fomenta su desarrollo, +hay un artículo interesante de Rob Pike [hablando sobre ello](https://go.dev/blog/generate). +Muchas de las herramientas son muy interesantes usarlas ya que acelera mucho la +generación de código repetitivo. Da mas confianza usar esas herramientas que la +IA. + +Para las consultas SQL con seguridad de tipos, existe la herramienta [sqlc](https://sqlc.dev/). + +Para ese proyecto sólo se ha usado [GoMock](https://github.com/uber-go/mock), +mantenida por Uber y sirve para usar la interfaz `Repository` sin usar una +base de datos real. + +Por otro lado, hubiese sido interesante incorporar [ginkgo](https://onsi.github.io/ginkgo/), +es un marco de trabajo de pruebas unitarias usando un lenguaje de dominio +específico (DSL). + +> En lugar de escribir una prueba así: `Test_Validate(t *testing.T) { ... }` +> se puede hacer de la siguiente manera: `var _ Describe("Models", func () { ... })`, +> y dentro del cuerpo se describen las pruebas a realizar. + +No se ha incorporado porque hay que instalar la herramienta que ejecutan las +pruebas, y no quería correr el riesgo de que no funcionase en otro equipo o no +diesen los resultados esperados. Que se podría haber usado un contenedor Docker, +sí, pero la prueba no consiste en eso. \ No newline at end of file