{"id":15095900,"url":"https://github.com/yakuter/ugin","last_synced_at":"2025-04-10T02:24:21.667Z","repository":{"id":40633352,"uuid":"174875619","full_name":"yakuter/ugin","owner":"yakuter","description":"UGin is an API boilerplate written in Go (Golang) with Gin Framework.","archived":false,"fork":false,"pushed_at":"2021-11-21T13:10:45.000Z","size":390,"stargazers_count":228,"open_issues_count":1,"forks_count":36,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-04-03T00:05:20.005Z","etag":null,"topics":["api","boilerplate","example","gin","gin-gonic","gorm","mysql","postgres","sqlite","viper"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yakuter.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-10T20:14:40.000Z","updated_at":"2025-02-12T23:37:26.000Z","dependencies_parsed_at":"2022-07-14T04:20:29.249Z","dependency_job_id":null,"html_url":"https://github.com/yakuter/ugin","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yakuter%2Fugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yakuter%2Fugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yakuter%2Fugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yakuter%2Fugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yakuter","download_url":"https://codeload.github.com/yakuter/ugin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248143502,"owners_count":21054791,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["api","boilerplate","example","gin","gin-gonic","gorm","mysql","postgres","sqlite","viper"],"created_at":"2024-09-25T15:43:33.003Z","updated_at":"2025-04-10T02:24:21.643Z","avatar_url":"https://github.com/yakuter.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# UGin - Ultimate Gin API\nUGin is an API boilerplate written in Go (Golang) with Gin Framework. https://github.com/gin-gonic/gin\n\n## Database Support\nUGin uses **gorm** as an ORM. So **Sqlite3**, **MySQL** and **PostgreSQL** is supported. You just need to edit **config.yml** file according to your setup. \n\n**config.yml** content:\n```\ndatabase:\n  driver: \"postgres\"\n  dbname: \"ugin\"\n  username: \"user\"\n  password: \"password\"\n  host: \"localhost\"\n  port: \"5432\"\n```\n\n## Default Models\n**UGin** has two models (Post and Tag) as boilerplate to show relational database usage.\n\n**/model/post-model.go** content:\n```\ntype Post struct {\n\tgorm.Model\n\tName        string `json:\"Name\" gorm:\"type:varchar(255)\"`\n\tDescription string `json:\"Description\"  gorm:\"type:text\"`\n\tTags        []Tag  // One-To-Many relationship (has many - use Tag's UserID as foreign key)\n}\n\ntype Tag struct {\n\tgorm.Model\n\tPostID      uint   `gorm:\"index\"` // Foreign key (belongs to)\n\tName        string `json:\"Name\" gorm:\"type:varchar(255)\"`\n\tDescription string `json:\"Description\" gorm:\"type:text\"`\n}\n```\n\n## Filtering, Search and Pagination\n**UGin** has it's own filtering, search and pagination system. You just need to use these parameters.\n\n**Query parameters:**\n```\n/posts/?Limit=2\n/posts/?Offset=0\n/posts/?Sort=ID\n/posts/?Order=DESC\n/posts/?Search=hello\n```\n\nFull: **http://localhost:8081/posts/?Limit=25\u0026Offset=0\u0026Sort=ID\u0026Order=DESC\u0026Search=hello**\n\n## Running\n\nTo run UGin with Docker, firstly build an image:\n```\nmake build-image\n```\n\nTo run Ugin with MySQL:\n```\nmake run-app-mysql\n```\n\nTo run Ugin with PostgreSQL:\n```\nmake run-app-postgres\n```\n\nApplication will be served at \":8081\"\n\n## Logging\n**UGin** has a very powerful logging logic. There is **application log (ugin.log)**, **database log (ugin.db.log)** and **access log (ugin.access.log)**\n\n### ugin.log:\n```\nINFO 2021-09-19T00:33:32+03:00 Server is starting at 127.0.0.1:8081\nERROR 2021-09-19T00:39:19+03:00 Failed to open log file ugin.log\n```\n### ugin.db.log:\n```\n2021/09/19 00:33:32 /home/user/projects/ugin/pkg/database/database.go:76\n[0.023ms] [rows:-] SELECT * FROM `posts` LIMIT 1\n\n2021/09/19 00:33:32 /home/user/go/pkg/mod/gorm.io/driver/sqlite@v1.1.5/migrator.go:261\n[0.015ms] [rows:-] SELECT count(*) FROM sqlite_master WHERE type = \"index\" AND tbl_name = \"posts\" AND name = \"idx_posts_deleted_at\"\n\n2021/09/19 00:33:32 /home/user/go/pkg/mod/gorm.io/driver/sqlite@v1.1.5/migrator.go:32\n[0.010ms] [rows:-] SELECT count(*) FROM sqlite_master WHERE type='table' AND name=\"tags\"\n\n2021/09/19 00:33:32 /home/user/projects/ugin/pkg/database/database.go:76\n[0.011ms] [rows:-] SELECT * FROM `tags` LIMIT 1\n```\n### ugin.access.log:\n```\n[GIN] 2021/09/19 - 00:33:43 | 200 |    9.255625ms |       127.0.0.1 | GET      \"/posts/\"\n[GIN] 2021/09/19 - 00:41:51 | 200 |     6.41675ms |       127.0.0.1 | GET      \"/posts/4\"\n```\n\n## Routes\nDefault **UGin** routes are listed below. \n\n| METHOD  | ROUTE            | FUNCTION                                                      |\n|---------|------------------|---------------------------------------------------------------|\n| GET     | /posts/          | github.com/yakuter/ugin/controller.(*Controller).GetPosts     |\n| GET     | /posts/:id       | github.com/yakuter/ugin/controller.(*Controller).GetPost      |\n| POST    | /posts/          | github.com/yakuter/ugin/controller.(*Controller).CreatePost   |\n| PUT     | /posts/:id       | github.com/yakuter/ugin/controller.(*Controller).UpdatePost   |\n| DELETE  | /posts/:id       | github.com/yakuter/ugin/controller.(*Controller).DeletePost   |\n| GET     | /postsjwt/       | github.com/yakuter/ugin/controller.(*Controller).GetPosts     |\n| GET     | /postsjwt/:id    | github.com/yakuter/ugin/controller.(*Controller).GetPost      |\n| POST    | /postsjwt/       | github.com/yakuter/ugin/controller.(*Controller).CreatePost   |\n| PUT     | /postsjwt/:id    | github.com/yakuter/ugin/controller.(*Controller).UpdatePost   |\n| DELETE  | /postsjwt/:id    | github.com/yakuter/ugin/controller.(*Controller).DeletePost   |\n| POST    | /auth/signup     | github.com/yakuter/ugin/controller.(*Controller).Signup       |\n| POST    | /auth/signin     | github.com/yakuter/ugin/controller.(*Controller).Signin       |\n| POST    | /auth/refresh    | github.com/yakuter/ugin/controller.(*Controller).RefreshToken |\n| POST    | /auth/check      | github.com/yakuter/ugin/controller.(*Controller).CheckToken   |\n| GET     | /admin/dashboard | github.com/yakuter/ugin/controller.Dashboard                  |\n\n## Gin Running Mode\nGin framework listens **GIN_MODE** environment variable to set running mode. This mode enables/disables access log. Just run one of these commands before running **UGin**:\n```bash\n// Debug mod\nexport GIN_MODE=debug\n// Test mod\nexport GIN_MODE=test\n// Release mod\nexport GIN_MODE=release\n```\n\n\n## Packages\n**UGin** uses great open source projects list below: **Gin** for main framework, **Gorm** for database and **Viper** for configuration.\n```\ngo get -u github.com/gin-gonic/gin\ngo get -u github.com/jinzhu/gorm\ngo get -u github.com/jinzhu/gorm/dialects/postgres\ngo get -u github.com/jinzhu/gorm/dialects/sqlite\ngo get -u github.com/jinzhu/gorm/dialects/mysql\ngo get -u github.com/spf13/viper\n```\n## Middlewares\n### 1. Logger and Recovery Middlewares\nGin has 2 important built-in middlewares: **Logger** and **Recovery**. UGin calls these two in default.\n```\nrouter := gin.Default()\n```\n\nThis is same with the following lines.\n```\nrouter := gin.New()\nrouter.Use(gin.Logger())\nrouter.Use(gin.Recovery())\n```\n\n### 2. CORS Middleware\nCORS is important for API's and UGin has it's own CORS middleware in **include/middleware.go**. CORS middleware is called with the code below.\n```\nrouter.Use(include.CORS())\n```\nThere is also a good repo for this: https://github.com/gin-contrib/cors\n\n### 3. BasicAuth Middleware\nAlmost every API needs a protected area. Gin has **BasicAuth** middleware for protecting routes. Basic Auth is an authorization type that requires a verified username and password to access a data resource. In UGin, you can find an example for a basic auth. To access these protected routes, you need to add **Basic Authorization credentials** in your requests. If you try to reach these endpoints from browser, you should see a window prompting you for username and password.\n\n```\nauthorized := router.Group(\"/admin\", gin.BasicAuth(gin.Accounts{\n    \"username\": \"password\",\n}))\n\n// /admin/dashboard endpoint is now protected\nauthorized.GET(\"/dashboard\", controller.Dashboard)\n```\n\n\n## What is next?\n- Ugin needs a user service and an authentication method with JWT.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyakuter%2Fugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyakuter%2Fugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyakuter%2Fugin/lists"}