Asumiendo que has leído mi post Empezando un Proyecto Go deberías tener el punto de partida para un servicio web go mínimo. Para tu primer proyecto es más fácil mantener todo tu código en una carpeta, en la base de tu proyecto, pero en algún momento querrás reestructurar las cosas, esto se hace por unas cuantas razones:
- Tener todo en una carpeta resulta en un montón de interdependencias en el código.
- La reutilización fuera del proyecto puede ser difícil ya que el código sólo está diseñado para ser utilizado en un paquete.
- Es imposible tener más de un binario, ya que sólo se puede tener un método
main
.
Este post proporcionará una visión general de la estructura que sigo en mis proyectos Go cuando construyo servicios web.
Nota: Si tu solo construyes una biblioteca para usar en tus servicios, o compartir con otros, está bien poner todo en la carpeta base de tu proyecto, un ejemplo de esto es mi biblioteca dynastore.
/cmd
Esta carpeta contiene los principales archivos de punto de entrada de la aplicación para el proyecto, con el nombre del directorio que coincide con el nombre para el binario. Así, por ejemplo, cmd/simple-service
significa que el binario que publiquemos será simple-service
.
/internal
Este paquete contiene el código de la biblioteca privada que se utiliza en su servicio, es específico para la función del servicio y no se comparte con otros servicios. Una cosa a tener en cuenta es que esta privacidad es impuesta por el propio compilador, ver las notas de la versión Go 1.4 para más detalles.
/pkg
Esta carpeta contiene el código que está bien para que otros servicios lo consuman, esto puede incluir clientes de la API, o funciones de utilidad que pueden ser útiles para otros proyectos, pero no justifican su propio proyecto. Personalmente prefiero usar esto sobre internal
, principalmente porque me gusta mantener las cosas abiertas para su reutilización en la mayoría de los proyectos.
Estructura del proyecto
A medida que construyes tu proyecto hay algunos objetivos muy importantes que debes considerar a la hora de estructurar tus paquetes:
- Mantener las cosas consistentes
- Mantener las cosas tan simples como sea posible, pero no más simples
- Acoplar libremente las secciones del servicio o de la aplicación
- Asegurarse de que es fácil de navegar alrededor
En general, cuando se empieza se debe experimentar un poco, probar algunas ideas diferentes cuando se construye la primera y obtener algunos comentarios sobre la base de los objetivos anteriores.
El objetivo número uno es que construyas un software fácil de mantener, consistente y fiable.
Ejemplo
Recomiendo echar un vistazo a exitus para ver cómo estructuro mis proyectos, la mayor parte del código está bajo la carpeta pkg
con cada subcarpeta teniendo uno o más archivos. Desde el nivel superior es bastante claro lo que cada paquete se refiere a, y aunque magra en las pruebas que tiene algunos ejemplos.
$ tree exitus/ exitus/├── cmd│ ├── authtest│└── main.go│ ├─── backend│└── main.go│ └─ client│ └─ main.go├─ dev│ ├─ add_migration.sh│ └─ docker-compose.yml├─ Dockerfile├─ go.mod├─ go.sum│ ├─ 20190721131113_extensions.down.sql│ ├─ 20190721131113_extensions.up.sql│ ├─ 20190723044115_customer_projects.down.sql│ ├─ 20190723044115_customer_projects.up.sql│ ├─ 20190726175158_issues.down.sql│ ├── 20190726175158_issues.up.sql│ ├─ 20190726201649_comments.down.sql│ ├─ 20190726201649_comments.up.sql│ ├─ bindata.go│ ├── migrations_test.go│ └─ README.md├── pkg│ ├─ api│ │ ├─ exitus.gen.go│ │ ├─ exitus.yml│ │ └─ gen.go│ ├─ auth│ │ ├─ scopes.go│ └─ user.go│ ├─ conf│ │ ├─ conf.go│ │ └─ conf_test.go│ ├── db│ │ ├─ db.go│ │ ├─ dbtesting.go│ │ ├── migrate.go│ │ ├── sqlhooks.go│ │ └─ transactions.go│ ├── env│ │ └─ env.go│ ├─ healthz│ │ ├─ healthz.go│ │ └── healthz_test.go│ ├── jwt│ │ └── jwt.go│ ├── metrics│ │ └── metrics.go│ ├── middleware│ │ └─ middleware.go│ ├─ oidc│ │ └── client.go│ ├── server│ ├─ reflect.go│ └─ server.go│ └─ store│ ├─ comments.go│ ├─ comments_test.go│ ├─ customers.go│ ├─ customers_test.go│ ├─ issues.go│ ├─ issues_test.go│ ├─ migrate_test.go│ ├─ projects.go│ ├─ projects_test.go│ └─ store.go└── README.md
El objetivo aquí es ilustrar cómo haces crecer tu proyecto desde un par de archivos, hasta un servicio web más grande. Te animo a que recorras los proyectos de github e indagues en cómo otros desarrolladores han estructurado los suyos y, sobre todo, ¡pruébalo tú mismo!
- GopherCon EU 2018: Peter Bourgon – Mejores prácticas para la programación industrial
- Diseño del proyecto Go estándar
- GopherCon 2018: Cat Seeing – ¿Cómo se estructuran sus Go Apps
Feedback
No dude en ponerse en contacto a través de:
- @ me en Twitter
- Envíame un correo electrónico
- Comenzando un proyecto Go
- Construyendo un coche burro WLToys A979
- ¿Comenzando con Cognito?
- ¿Por qué CDK?
- Trabajos de fondo sin servidor parte 2