Go te da libertad total. Puedes poner todo en un main.go, dividirlo en paquetes como quieras, usar cualquier estructura que se te ocurra. El compilador no se queja mientras el código funcione.
Eso es exactamente el problema.
Cuando un equipo pequeño empieza un proyecto en Go, la estructura inicial parece razonable. Seis meses después, hay handlers HTTP con lógica de negocio mezclada, acceso directo a la base de datos desde los controladores y un archivo utils.go que tiene 800 líneas de funciones sin relación entre sí.
No es culpa del equipo. Es culpa de la falta de guía.
Keel nació para resolver eso.
Lo que Go hace bien (y lo que no te dice)
Go es excelente para:
- Concurrencia con goroutines y channels
- Performance en sistemas de alta demanda
- Binarios pequeños y despliegue sencillo
- Código legible sin magia implícita
Lo que Go no te dice es cómo organizar tu código cuando el proyecto crece. No hay una convención estándar para APIs REST. No hay un framework “oficial”. Hay decenas de routers, cada equipo elige uno diferente y cada proyecto parece un lenguaje distinto.
El patrón que adoptamos
Después de construir varios proyectos en Go, encontramos que el patrón que mejor escala es este:
Módulo
└── Controlador ← recibe HTTP, valida entrada, delega
└── Servicio ← lógica de negocio pura
└── Repositorio ← acceso a datos
Cada capa tiene una responsabilidad única:
- El controlador no sabe nada de la base de datos
- El servicio no sabe nada de HTTP
- El repositorio no sabe nada de lógica de negocio
Esta separación parece obvia escrita así. Pero sin un framework que la refuerce, el equipo la rompe consistentemente bajo presión de tiempo.
Keel la hace parte de la estructura del proyecto.
Sin magia
Una decisión de diseño importante: Keel no usa reflexión, decoradores ni generación de código.
Todo es Go estándar. Builder patterns, interfaces, punteros. Si lees el código de Keel, entiendes exactamente qué está pasando. No hay “Framework Magic” que explique por qué algo funciona o no funciona.
// Registrar una ruta en Keel es explícito
module.AddController(
controllers.NewUserController(userService),
)
No hay anotaciones. No hay @Controller("/users"). No hay archivos de configuración XML o YAML escondidos. Solo código Go que puedes leer, depurar y entender.
OpenAPI automático
Una de las partes más dolorosas de construir APIs es mantener la documentación sincronizada con el código. En la práctica, nadie la actualiza y termina siendo mentira.
Keel genera la especificación OpenAPI en runtime a partir de las definiciones de rutas. La documentación siempre está actualizada porque es el código.
Para quién es Keel
Keel es para equipos que:
- Ya saben Go y quieren una forma consistente de estructurar proyectos
- Están cansados de empezar desde cero en cada nuevo servicio
- Quieren documentación OpenAPI sin esfuerzo manual
- Prefieren código explícito sobre frameworks “mágicos”
No es para proyectos de un solo archivo o scripts. Para eso, Go estándar es más que suficiente. Keel tiene sentido cuando el proyecto va a crecer, va a tener más de un desarrollador y va a vivir más de seis meses.
Estado actual
Keel está en producción activa y lo usamos en proyectos reales. La documentación está en keel-go.dev y el código en GitHub.
Los issues están abiertos. Si lo pruebas y encuentras algo que no funciona como esperas — o algo que podría funcionar mejor — queremos saberlo.
Este es el tipo de herramienta que se construye mejor con el feedback de quien la usa. 🔧