{"id":28328662,"url":"https://github.com/byron-villegas/go-gin","last_synced_at":"2026-05-03T15:33:15.913Z","repository":{"id":295322027,"uuid":"989761659","full_name":"byron-villegas/go-gin","owner":"byron-villegas","description":"Go + Gin","archived":false,"fork":false,"pushed_at":"2025-08-14T01:43:02.000Z","size":55,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-14T03:26:16.940Z","etag":null,"topics":["gin","go","godog","swagger","swaggo","vegeta"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/byron-villegas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-24T19:17:14.000Z","updated_at":"2025-08-14T01:43:06.000Z","dependencies_parsed_at":"2025-05-24T22:59:01.129Z","dependency_job_id":"f0d01233-792b-4ef6-b514-6cd8e0ec4d64","html_url":"https://github.com/byron-villegas/go-gin","commit_stats":null,"previous_names":["byron-villegas/go-gin"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/byron-villegas/go-gin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byron-villegas%2Fgo-gin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byron-villegas%2Fgo-gin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byron-villegas%2Fgo-gin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byron-villegas%2Fgo-gin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/byron-villegas","download_url":"https://codeload.github.com/byron-villegas/go-gin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byron-villegas%2Fgo-gin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32575109,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gin","go","godog","swagger","swaggo","vegeta"],"created_at":"2025-05-26T08:16:11.679Z","updated_at":"2026-05-03T15:33:15.902Z","avatar_url":"https://github.com/byron-villegas.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Go Gin\n\nProyecto base para aplicaciones Gin con ejemplos de configuración, testing y buenas prácticas.\n\n## Tabla de Contenidos\n\n- [Instalación](#instalación)\n- [Variables de Entorno](#variables-de-entorno)\n- [Ejecutar Aplicación](#ejecutar-aplicación)\n- [Testing](#testing)\n- [Tests de Aceptación](#tests-de-aceptación)\n- [Tests de Rendimiento](#tests-de-rendimiento)\n- [Swagger](#swagger)\n- [Links de Referencia](#links-de-referencia)\n\n## Instalación\n### Instalar Go\nPara instalar go debemos bajarlo e instalarlo de la siguiente pagina https://go.dev/doc/install\n\n### Instalar Paquetes\nPara instalar los paquetes debemos ejecutar el siguiente comando\n\n```shell\ngo mod tidy\n```\n\n## Variables de Entorno\nEste proyecto utiliza dotenv por lo que podemos crear el archivo **.env** con las siguientes variables\n\n```text\nSECRET_KEY=sdadasffadf\nJWT_SECRET_KEY=dsaadfdass\nCORS_ORIGIN=*\n```\n\nEstas variables son las llaves secretas que se obtienen por variable de entorno, tambien tenemos el cors origin por si queremos dejarlo especifico para un dominio en particular\n\n\n## Ejecutar Aplicación\nSe debe ejecutar el siguiente comando\n\n```shell\ngo run main.go\n```\n\n### Docker\nA continuacion dejo los comandos a utilizar para generar la imagen y posteriormente ejecutarla\n\n#### Imagen\nPara generar la imagen debemos utilizar el siguiente comando\n\n```shell\ndocker build -t go-gin .\n```\n\n#### Ejecutar\nPara ejecutar la imagen debemos utilizar el siguiente comando\n\n```shell\ndocker run -p 8080:8080 go-gin\n```\n\n## Testing\n\n### Ejecutar\nSe debe ejecutar el siguiente comando\n\n```shell\ngo test ./repository ./client ./service ./controller ./routes ./config\n```\n\n### Ejecutar con Cobertura\nSe debe ejecutar el siguiente comando\n\n```shell\ngo test -cover ./repository ./client ./service ./controller ./routes ./config\n```\n\n### Generar Reporte Cobertura Formato Consola\nSe deben ejecutar los siguientes comandos\n\n```shell\ngo test -coverprofile=\"coverage.out\" ./repository ./client ./service ./controller ./routes ./config\ngo tool cover -func=\"coverage.out\"\n```\n\n### Generar Reporte Cobertura Formato HTML\nSe deben ejecutar los siguientes comandos\n\n```shell\ngo test -coverprofile=\"coverage.out\" ./repository ./client ./service ./controller ./routes ./config\ngo tool cover -html=\"coverage.out\" -o coverage.html\n```\n\n## Tests de Aceptación\n### Configuración\nSe debe crear un archivo **acceptance-test/main_test.go** con el siguiente contenido\n\n```go\npackage main\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/cucumber/godog\"\n)\n\nfunc TestFeatures(t *testing.T) {\n\tvar outputFile *os.File\n\tvar err error\n\toutputFile, err = os.Create(\"godog-report.json\")\n\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create report file: %v\", err)\n\t}\n\n\topts := godog.Options{\n\t\tFormat:   \"cucumber\",\n\t\tPaths:    []string{\".\"},\n\t\tOutput:   outputFile,\n\t\tTestingT: t,\n\t\tStrict:   true,\n\t}\n\tgodog.TestSuite{\n\t\tName:                \"acceptance\",\n\t\tScenarioInitializer: InitializeScenario,\n\t\tOptions:             \u0026opts,\n\t}.Run()\n}\n```\n\nEsto nos permite definir la ruta de los features, el archivo y formato de salida de reporte de los tests de aceptación\n\n### Ejecución\nSe debe ejecutar el siguiente comando\n\n```shell\ngo test ./acceptance-test\n```\n\nAl finalizar generara un reporte **godog-report.json**\n\n## Tests de Rendimiento\n### Configuración\nSe debe crear un archivo **performance-test/vegeta/main_test.go** con el siguiente contenido\n\n```go\npackage performance\n\nimport (\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\tvegeta \"github.com/tsenart/vegeta/v12/lib\"\n)\n\nvar apiHost string = \"http://localhost:8080/api\"\n\nfunc init() {\n\tif os.Getenv(\"API_HOST\") != \"\" {\n\t\tapiHost = os.Getenv(\"API_HOST\")\n\t}\n}\n\nfunc TestProductEndpointPerformance(t *testing.T) {\n\trate := vegeta.Rate{Freq: 10, Per: time.Second} // 10 requests por segundo\n\tduration := 5 * time.Second\n\n\tendpoint := \"products\"\n\n\ttargeter := vegeta.NewStaticTargeter(vegeta.Target{\n\t\tMethod: \"GET\",\n\t\tURL:    apiHost + \"/products\",\n\t})\n\n\tattacker := vegeta.NewAttacker()\n\n\tvar metrics vegeta.Metrics\n\tfor res := range attacker.Attack(targeter, rate, duration, \"GET /products\") {\n\t\tmetrics.Add(res)\n\t}\n\tmetrics.Close()\n\n\t// Reporte en formato texto\n\ttextFile, err := os.Create(\"vegeta-\" + endpoint + \"-report.txt\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create text report file: %v\", err)\n\t}\n\tdefer textFile.Close()\n\n\ttextReporter := vegeta.NewTextReporter(\u0026metrics)\n\tif err := textReporter.Report(textFile); err != nil {\n\t\tt.Errorf(\"failed to write vegeta text report: %v\", err)\n\t}\n\n\t// Reporte en formato JSON\n\tjsonFile, err := os.Create(\"vegeta-\" + endpoint + \"-report.json\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create JSON report file: %v\", err)\n\t}\n\tdefer jsonFile.Close()\n\n\tjsonReporter := vegeta.NewJSONReporter(\u0026metrics)\n\tif err := jsonReporter.Report(jsonFile); err != nil {\n\t\tt.Errorf(\"failed to write vegeta JSON report: %v\", err)\n\t}\n\n\tif metrics.Success \u003c 0.95 {\n\t\tt.Errorf(\"success rate too low: %.2f%%\", metrics.Success*100)\n\t}\n\tt.Logf(\"99th percentile latency: %s\", metrics.Latencies.P99)\n}\n\n```\n\nTenemos que crear una funcion (test) por endpoint a validar\n\n### Ejecución\nSe debe ejecutar el siguiente comando\n\n```shell\ngo test -v ./performance-test/vegeta\n```\n\nAl finalizar generara dos reportes **vegeta-product-report.json** y **vegeta-product-report.txt**\n\n## Swagger\n### Instalación\nDebemos instalar swaggo/swag con el siguiente comando\n\n```shell\ngo install github.com/swaggo/swag/cmd/swag@latest\n```\n\n### Agregar Dependencias\nDebemos agregar las siguientes dependencias\n\n```shell\ngo get github.com/swaggo/gin-swagger\ngo get github.com/swaggo/files\n```\n\n### Documentar Endpoints\nDebemos documentar los endpoints con comentarios ejemplo\n\n```go\n// GetProducts godoc\n// @Summary      Lista todos los productos\n// @Description  Obtiene todos los productos disponibles\n// @Tags         products\n// @Produce      json\n// @Success      200  {array}  models.Product\n// @Router       /products [get]\nfunc (ec *ProductController) GetProducts(c *gin.Context) {\n    // ...\n}\n```\n\nSwag generará la documentacion de swagger en base a esos comentarios\n\n\n### Generar Archivo Swagger\nPara generar el archivo swagger simplemente ejecutamos el siguiente comando\n\n```shell\nswag init\n```\n\nEsto nos generará los archivos de swagger en la carpeta **/docs** con la siguiente estructura\n\n/docs\n├── docs.go\n├── swagger.json\n└── swagger.yml\n\n### Configurar Swagger UI\nPara configurar Swagger UI simplemente agregamos el siguiente codigo al archivo **main.go**\n\n```go\nimport (\n    \"github.com/swaggo/gin-swagger\"\n    \"github.com/swaggo/files\"\n    _ \"go-gin/docs\"\n)\n\nr.GET(\"/swagger/*any\", ginSwagger.WrapHandler(swaggerFiles.Handler))\n```\n\nQuedando así\n\n```go\npackage main\n\nimport (\n\t\"go-gin/config\"\n\t\"go-gin/routes\"\n\n\t_ \"go-gin/docs\" // docs generated by Swag\n\n\t\"github.com/gin-contrib/cors\"\n\t\"github.com/gin-gonic/gin\"\n\tswaggerFiles \"github.com/swaggo/files\"\n\tginSwagger \"github.com/swaggo/gin-swagger\"\n)\n\nfunc main() {\n\t// Show banner with application information\n\tconfig.ShowBanner()\n\n\t// Create a server instance\n\tr := gin.Default()\n\n\t// Config CORS\n\tr.Use(cors.New(cors.Config{\n\t\tAllowOrigins:     []string{config.AppConfig.CORSOrigin},\n\t\tAllowMethods:     []string{\"GET\", \"POST\", \"PUT\", \"DELETE\"},\n\t\tAllowHeaders:     []string{config.AppConfig.CORSHeaders},\n\t\tAllowCredentials: true,\n\t}))\n\n\tr.GET(\"/swagger/*any\", ginSwagger.WrapHandler(swaggerFiles.Handler))\n\n\t// Config server path\n\trouterGroup := r.Group(config.AppConfig.ServerPath)\n\n\t// Config routes for the server\n\troutes.SetupRoutes(routerGroup)\n\n\t// Start server with port\n\tr.Run(\":\" + config.AppConfig.ServerPort)\n}\n```\n\nCuando ejecutemos a la aplicacion debemos entrar a la pagina /swagger/index.html\n\n## Links de Referencia\nA continuación dejo links utilizados para realizar este proyecto\n\n[Gin](https://go.dev/doc/tutorial/web-service-gin)\n\n[Swagger](https://github.com/swaggo/swag)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyron-villegas%2Fgo-gin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbyron-villegas%2Fgo-gin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyron-villegas%2Fgo-gin/lists"}