Descripción

Este es un diseño básico para proyectos de aplicaciones Go. No es un estándar oficialmente definido por el equipo central de desarrollo de Go; es un diseño de directorio comúnmente utilizado para proyectos de la comunidad Go.

Si estás aprendiendo Go o construyendo un concepto de prueba (PoC) o un proyecto personal simple, este diseño de proyecto es demasiado complicado. En su lugar, comienza con un diseño verdaderamente simple (solo un archivo main.go y go.mod son suficientes). A medida que tu proyecto evoluciona, asegúrate de que la estructura de tu código sea buena, de lo contrario terminarás con un código desordenado que contiene muchas dependencias ocultas y estado global. Cuando más personas se involucren en el proyecto, necesitarás una forma más estructurada. En este caso, es importante introducir una forma común de gestionar paquetes/bibliotecas. Cuando tienes un proyecto de código abierto o sabes que otros proyectos importan código de tu repositorio de proyectos, tener paquetes y código privados (también conocidos como internos) se vuelve importante. ¡Clona el repositorio, conserva las partes que necesitas y elimina todo lo demás! Solo porque exista no significa que tengas que usarlo todo. Ninguno de estos patrones se usan en cada proyecto. Incluso el patrón vendor no es universal.

Este diseño de proyecto está diseñado intencionalmente para ser muy general y no intenta imponer una estructura específica de paquetes Go.

Especificación del Directorio del Proyecto Go

A continuación se muestra la especificación recomendada del directorio del proyecto Go.

.
├── go.mod
├── api
├── assets
├── build
├── cmd
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── go.mod
├── init
├── internal
├── pkg
├── scripts
├── test
├── third_party
├── tools
├── vendor
├── web
└── website

A continuación se presentan los significados de cada directorio.

/cmd

Las aplicaciones principales del proyecto, es decir, el punto de entrada de los programas. Los archivos Go en este directorio generalmente generan archivos ejecutables. En un proyecto simple, un archivo como /test/main.go puede servir como punto de entrada.

El nombre del directorio para cada aplicación debe coincidir con el nombre del archivo ejecutable que desees (por ejemplo, /cmd/miaplicacion).

No coloques demasiado código en el directorio de la aplicación. Si crees que el código puede ser importado y utilizado en otros proyectos, colócalo en el directorio /pkg. Si el código no es reutilizable o no quieres que otros lo reutilicen, coloca el código en el directorio /internal. ¡Te sorprenderá el comportamiento de otras personas, así que expresa claramente tu intención!

Normalmente hay una pequeña función main que importa y llama código de los directorios /internal y /pkg, y nada más.

/internal

Código de aplicación y biblioteca privada. Este es el código que no deseas que otros importen en sus aplicaciones o bibliotecas. Ten en cuenta que este patrón de diseño está reforzado por el propio compilador Go. Para obtener información más detallada, consulta las notas de lanzamiento de Go 1.4. Ten en cuenta que no se limita al directorio internal de nivel superior. Puedes tener varios directorios internal en cualquier nivel del árbol del proyecto.

Puedes elegir añadir alguna estructura adicional para los paquetes internos para distinguir entre código interno compartido y no compartido. Esto no es necesario (especialmente para proyectos más pequeños), pero demostrar visualmente el uso previsto de los paquetes es una buena práctica. Tu código de aplicación real se puede colocar en el directorio /internal/app (por ejemplo, /internal/app/miaplicacion), y el código compartido para estas aplicaciones se puede colocar en el directorio /internal/pkg (por ejemplo, /internal/pkg/mibibliotecaprivada).

/pkg

Código de biblioteca que puede ser utilizado por aplicaciones externas (por ejemplo, /pkg/mibibliotecapublica). Otros proyectos importarán estas bibliotecas y esperarán que funcionen adecuadamente, ¡así que piénsalo bien antes de colocar contenido aquí :-) Ten en cuenta que el directorio internal es una forma mejor de asegurar que los paquetes privados no puedan ser importados, ya que es reforzado por Go mismo. El directorio /pkg sigue siendo una buena forma de transmitir explícitamente que el código en este directorio es seguro para que otros lo usen.

Si tu proyecto de aplicación es muy pequeño y el anidamiento de varios niveles no agrega mucho valor, también está bien no usarlo (a menos que realmente quieras usarlo :-)). Cuando el proyecto se haga lo suficientemente grande y el directorio raíz se vuelva muy ocupado, considera usarlo (especialmente si tienes muchos componentes de aplicaciones que no son de Go).

/vendor

Dependencias de la aplicación (administradas manualmente o utilizando su herramienta de gestión de dependencias preferida, como la función integrada de Go Modules). El comando go mod vendor creará el directorio /vendor para usted. Tenga en cuenta que si no está utilizando la versión Go 1.14 habilitada de forma predeterminada, es posible que necesite agregar la bandera -mod=vendor al comando go build.

Si está construyendo una biblioteca, por favor no incluya las dependencias de su aplicación.

Directorios de Aplicaciones de Servicio

/api

Especificaciones OpenAPI/Swagger, archivos de esquema JSON, archivos de definición de protocolo y directorios de protocolo de API.

Directorios de Aplicaciones Web

/web

Componentes específicos para aplicaciones web: activos de sitios web estáticos, plantillas del lado del servidor y aplicaciones de una sola página (SPAs).

Directorios de Aplicaciones Generales

/configs

Plantillas de archivos de configuración o configuraciones predeterminadas.

Coloque sus archivos de plantilla confd o consul-template aquí.

/init

Inicialización del sistema (systemd, upstart, sysv) y configuraciones de administrador de procesos / demonios (runit, supervisord).

/scripts

Scripts para diversas tareas de compilación, instalación, análisis y otras operaciones.

/build

Empaquetado e integración continua.

Coloque las configuraciones y scripts de empaquetado en la nube (AMI), contenedor (Docker), sistema operativo (deb, rpm, pkg) en el directorio /build/package.

Coloque las configuraciones y scripts de integración continua (travis, circle, drone) en el directorio /build/ci. Tenga en cuenta que ciertas herramientas de integración continua (como Travis CI) son muy específicas sobre la ubicación de sus archivos de configuración. Trate de colocar los archivos de configuración en el directorio /build/ci y use enlaces para conectarlos a la ubicación esperada por las herramientas de integración continua (si es posible).

/deployments

Configuraciones de implementación y plantillas para IaaS, PaaS, sistema y orquestación de contenedores (docker-compose, kubernetes/helm, terraform). Tenga en cuenta que en algunos repositorios (especialmente para aplicaciones implementadas usando Kubernetes), este directorio se llama /deploy.

/test

Otras aplicaciones de prueba externas y datos de prueba. Siéntase libre de organizar el directorio /test de la forma que mejor le convenga. Para proyectos más grandes, tiene sentido organizar los datos en subdirectorios. Por ejemplo, puede crear los directorios /test/data o /test/testdata dentro de /test para que Go ignore su contenido. Tenga en cuenta que Go también ignora directorios o archivos que comienzan con "." o "_", lo que ofrece una mayor flexibilidad al nombrar directorios de datos de prueba.

Otros Directorios

/docs

Documentación de diseño y usuario (distinta a los documentos godoc que genera).

/tools

Herramientas de soporte para este proyecto. Tenga en cuenta que estas herramientas pueden importar código de los directorios /pkg y /internal.

/examples

Ejemplos de aplicaciones y/o bibliotecas públicas.

/third_party

Herramientas auxiliares externas, código bifurcado y otras herramientas de utilidad de terceros (por ejemplo, Swagger UI).

/githooks

Hooks de Git.

/assets

Activos adicionales (imágenes, logotipos, etc.) proporcionados con el repositorio.

/website

Ubicación para almacenar los datos del sitio web del proyecto si no está utilizando GitHub Pages.

/src

Algunos proyectos de Go pueden tener una carpeta src, pero esto suele ser debido a desarrolladores que vienen del mundo Java, donde es un patrón común. Si es posible, intente evitar adoptar este patrón similar a Java. Realmente no desea que su código o proyecto de Go se parezca a Java :-)

No confunda el directorio /src a nivel de proyecto con el directorio /src utilizado para el espacio de trabajo de Go, descrito en Cómo Escribir Código en Go. La variable de entorno $GOPATH apunta a su espacio de trabajo (actual) (por defecto, en sistemas que no son Windows apunta al directorio $HOME/go). Este espacio de trabajo incluye los directorios /pkg, /bin y /src en el nivel superior. Su proyecto real será un subdirectorio bajo el directorio /src, por lo que si su proyecto tiene un directorio /src, la ruta del proyecto se verá así: /alguna/ruta/al/espacio/de/trabajo/src/su_proyecto/src/su_codigo.go. Tenga en cuenta que a partir de Go 1.11, su proyecto puede estar ubicado fuera del GOPATH, pero eso no significa que usar este patrón de diseño sea una buena idea.