{"id":15104966,"url":"https://github.com/letscool/dij-gin","last_synced_at":"2026-01-20T14:02:07.311Z","repository":{"id":64298509,"uuid":"561620384","full_name":"LETSCOOL/dij-gin","owner":"LETSCOOL","description":"A web framework in golang.","archived":false,"fork":false,"pushed_at":"2022-12-15T06:13:42.000Z","size":2464,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-05T12:42:09.817Z","etag":null,"topics":["dependency","dependency-injection","dij","dij-gin","framework","gin","gin-gonic","go","golang","injection","web"],"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/LETSCOOL.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}},"created_at":"2022-11-04T05:00:35.000Z","updated_at":"2023-07-25T08:40:17.000Z","dependencies_parsed_at":"2023-01-15T09:01:26.924Z","dependency_job_id":null,"html_url":"https://github.com/LETSCOOL/dij-gin","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/LETSCOOL/dij-gin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LETSCOOL%2Fdij-gin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LETSCOOL%2Fdij-gin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LETSCOOL%2Fdij-gin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LETSCOOL%2Fdij-gin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LETSCOOL","download_url":"https://codeload.github.com/LETSCOOL/dij-gin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LETSCOOL%2Fdij-gin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28604712,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T12:01:53.233Z","status":"ssl_error","status_checked_at":"2026-01-20T12:01:46.545Z","response_time":117,"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":["dependency","dependency-injection","dij","dij-gin","framework","gin","gin-gonic","go","golang","injection","web"],"created_at":"2024-09-25T20:04:43.290Z","updated_at":"2026-01-20T14:02:07.296Z","avatar_url":"https://github.com/LETSCOOL.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dij-gin\n\nA dij-style gin library. [gin](https://github.com/gin-gonic/gin) is one of \nmost popular web frameworks for golang. [dij](https://github.com/LETSCOOL/lc-go)\nstands for dependency injection. This library provides a dij-style gin wrapper.\n\n\nRefer to completed examples in [go-examples](https://github.com/LETSCOOL/go-examples).\n\n\n## Contents\n__________\n- [Gin Style](#gin-style)\n  - [Get method](#get-method)\n  - [Hierarchy](#hierarchycontroller)\n- [dij-gin Style](#dij-gin-style)\n  - [Query](#query)\n  - [Where variable data came from?](#where-variable-data-came-from)\n  - [Customize path name and http method](#customize-path-name-and-http-method)\n    - [No route](#no-route)\n  - Body\n    - Form\n    - Json\n  - [Validator](#validator)\n  - [Response](#response)\n  - [Middlewares](#middlewares)\n    - [Log](#log) \n    - [Basic Auth](#basic-auth)\n    - [Bearer](#bearer)\n    - [CORS](#cors)\n  - [OpenAPI generation](#openapi-generation)\n    - tag/group\n  - Runtime environment\n- [Http tag](#http-tag)\n- [TODO List](#todo-list)\n\n\n## Gin Style\n___\n### Get method\nThe *WebContext* embeds *gin.Context*, any gin helper functions can be used directly.\n```go\npackage main\n\nimport (\n\t. \"github.com/letscool/dij-gin\"\n\t\"log\"\n\t\"net/http\"\n)\n\ntype TWebServer struct {\n\tWebServer\n}\n\n// GetHello a http request with \"get\" method.\n// Url should like this in local: http://localhost:8000/hello\nfunc (s *TWebServer) GetHello(ctx WebContext) {\n\tctx.IndentedJSON(http.StatusOK, \"/hello\")\n}\n\nfunc main() {\n\t//dij.EnableLog()\n\tif err := LaunchGin(\u0026TWebServer{}); err != nil {\n\t\tlog.Fatalln(err)\n\t}\n}\n```\nThe function name *GetHello* should combine a method and a path name.\nMethod should be one of valid http methods, for examples: **Get**, **Post**, **Delete**, etc.\n\n### Hierarchy/Controller\nYou can group a few http functions in one controller, \nwhich likes what *gin.router.Group* function does.\n\n```go\npackage main\n\nimport (\n\t. \"github.com/letscool/dij-gin\"\n\t\"log\"\n\t\"net/http\"\n)\n\ntype TWebServer struct {\n\tWebServer\n\n\tuserCtl *TUserController `di:\"\"` // inject dependency by class/default name\n}\n\ntype TUserController struct {\n\tWebController `http:\"user\"` //group by 'user' path\n}\n\n// Get a http request with \"get\" method.\n// Url should like this in local: http://localhost:8000/user\nfunc (u *TUserController) Get(ctx WebContext) {\n\tctx.IndentedJSON(http.StatusOK, \"/user\")\n}\n\n// GetMe a http request with \"get\" method.\n// Url should like this in local: http://localhost:8000/user/me\nfunc (u *TUserController) GetMe(ctx WebContext) {\n\tctx.IndentedJSON(http.StatusOK, \"/user/me\")\n}\n\nfunc main() {\n\t//dij.EnableLog()\n\tif err := LaunchGin(\u0026TWebServer{}); err != nil {\n\t\tlog.Fatalln(err)\n\t}\n}\n```\n\n## dij-gin Style\n_____\ndij-gin style includes many features:\n- Easy way to retrieve path parameters, query parameters, etc.\n- Easy way to response data with different http code.\n- Support OpenAPI(v3.0) generation.  \n- Http functions support to enable or disable by runtime environment, aka: prod, dev, and test.\n\n\n### Query\n```go\npackage main\n\nimport (\n  \"fmt\"\n  . \"github.com/letscool/dij-gin\"\n  \"log\"\n  \"net/http\"\n)\n\ntype TWebServer struct {\n  WebServer\n}\n\n// GetHello a http request with \"get\" method.\n// Url should like this in local: http://localhost:8000/hello?name=wayne\u0026age=123.\n// The result will be:\n//\n//\t\"/hello wayne, 123 years old\"\nfunc (s *TWebServer) GetHello(ctx struct {\n  WebContext\n  Name string `http:\"name\"`\n  Age  int    `http:\"age\"`\n}) {\n  ctx.IndentedJSON(http.StatusOK, fmt.Sprintf(\"/hello %s, %d years old\", ctx.Name, ctx.Age))\n}\n\nfunc main() {\n  if err := LaunchGin(\u0026TWebServer{}); err != nil {\n    log.Fatalln(err)\n  }\n}\n```\n\n### Where variable data came from?\n\nAdd an attribute \"in=xxx\" in http tag. About http tag setting, see\nthe [reference](#http-tag)\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t. \"github.com/letscool/dij-gin\"\n\t\"log\"\n\t\"net/http\"\n)\n\ntype TWebServer struct {\n\tWebServer\n\n\tuserCtl *TUserController `di:\"\"` // inject dependency by class/default name\n}\n\ntype TUserController struct {\n\tWebController `http:\"user\"` //group by 'user' path\n}\n\n// PutUserById a http request with \"get\" method.\n// Curl this url should like this in local:\n//\n//\tcurl -d \"age=34\u0026name=wayne\" -X PUT http://localhost:8000/user/2345/profile\n//\n// The result should be:\n//\n//\t\"update user(#2345)'s name wayne and age 34\"\nfunc (u *TUserController) PutUserById(ctx struct {\n\tWebContext `http:\":id/profile\"`\n\tId         int    `http:\"id,in=path\"`\n\tName       string `http:\"name,in=body\"`\n\tAge        int    `http:\"age,in=body\"`\n}) {\n\tctx.IndentedJSON(http.StatusOK, fmt.Sprintf(\"update user(#%d)'s name %s and age %d\", ctx.Id, ctx.Name, ctx.Age))\n}\n\nfunc main() {\n\tif err := LaunchGin(\u0026TWebServer{}); err != nil {\n\t\tlog.Fatalln(err)\n\t}\n}\n```\n\n### Customize path name and http method\n\nAdd http tag with the format \"[path],method=[method]\".\n\n```go\npackage main\n\nimport (\n\t. \"github.com/letscool/dij-gin\"\n\t\"log\"\n\t\"net/http\"\n)\n\ntype TWebServer struct {\n\tWebServer\n}\n\n// SayHi a http request with \"get\" method.\n// Url should like this in local: http://localhost:8000/hello.\nfunc (s *TWebServer) SayHi(ctx struct {\n\tWebContext `http:\"hello,method=get\"`\n}) {\n\tctx.IndentedJSON(http.StatusOK, \"hello\")\n}\n\nfunc main() {\n\tif err := LaunchGin(\u0026TWebServer{}); err != nil {\n\t\tlog.Fatalln(err)\n\t}\n}\n```\n\n#### No Route\n```go\npackage main\n\nimport (\n\t. \"github.com/letscool/dij-gin\"\n\t\"log\"\n)\n\ntype TWebServer struct {\n\tWebServer\n}\n\n// NoRoute is entry for page not found, is only supported in root path currently.\n// Any query will show the log.\nfunc (s *TWebServer) NoRoute(ctx WebContext) {\n\tlog.Printf(\"no route: %s\\n\", ctx.Request.RequestURI)\n}\n\nfunc main() {\n\tif err := LaunchGin(\u0026TWebServer{}); err != nil {\n\t\tlog.Fatalln(err)\n\t}\n}\n```\n\n### Validator\n\ndij-gin uses [go-playground/validator/v10](https://github.com/go-playground/validator) for validation.\ngin uses 'binding' as validation tag key instead of 'validate', 'validate' tag key is chose from go-playground/validator/v10 official.\ndij-gin still uses 'validate' tag key.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t. \"github.com/letscool/dij-gin\"\n\t\"log\"\n\t\"net/http\"\n)\n\ntype TWebServer struct {\n\tWebServer\n\n\tuserCtl *TUserController `di:\"\"` // inject dependency by class/default name\n}\n\ntype TUserController struct {\n\tWebController `http:\"user\"` //group by 'user' path\n}\n\n// GetUserById a http request with \"get\" method.\n// Url should like this in local: http://localhost:8000/user/2345/profile.\n// The result will be:\n//\n//\t{\"message\":\"Key: 'Id' Error:Field validation for 'Id' failed on the 'lte' tag\",\"code\":\"400\"}\nfunc (u *TUserController) GetUserById(ctx struct {\n\tWebContext `http:\":id/profile\"`\n\tId         int `http:\"id,in=path\" validate:\"gte=100,lte=999\"`\n}) {\n\tctx.IndentedJSON(http.StatusOK, fmt.Sprintf(\"get user(#%d)'s profile\", ctx.Id))\n}\n\nfunc main() {\n\tif err := LaunchGin(\u0026TWebServer{}); err != nil {\n\t\tlog.Fatalln(err)\n\t}\n}\n```\n\n### Response\n\n```go\npackage main\n\nimport (\n  \"errors\"\n  . \"github.com/letscool/dij-gin\"\n  \"log\"\n)\n\ntype TWebServer struct {\n  WebServer\n}\n\n// GetResp a http request with \"get\" method.\n// Url should like this in local: http://localhost:8000/resp?select=1 .\n// Use *curl -v* command to see response code.\nfunc (s *TWebServer) GetResp(ctx struct {\n  WebContext\n  Select int `http:\"select\"`\n}) (result struct {\n  Ok200       *string // the range of last three characters is between 2xx and 5xx, so the response code = 200\n  Ok          *string `http:\"201\"` // force response code to 201\n  Redirect302 *string // redirect data should be string type, because it is redirect location.\n  Error       error   // default response code for error is 400\n}) {\n  switch ctx.Select {\n  case 1:\n    data := \"ok\"\n    result.Ok200 = \u0026data\n  case 2:\n    data := \"ok\"\n    result.Ok = \u0026data\n  case 3:\n    url := \"https://github.com/letscool\"\n    result.Redirect302 = \u0026url\n  default:\n    result.Error = errors.New(\"an error\")\n  }\n  return\n}\n\nfunc main() {\n  if err := LaunchGin(\u0026TWebServer{}); err != nil {\n    log.Fatalln(err)\n  }\n}\n```\n\n### Middlewares\n\n#### Log\n- Log all http methods for a controller and all it's sub-controllers\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"github.com/gin-gonic/gin\"\n  . \"github.com/letscool/dij-gin\"\n  \"github.com/letscool/dij-gin/libs\"\n  \"log\"\n  \"net/http\"\n)\n\ntype TWebServer struct {\n  WebServer `http:\",middleware=log\"`\n\n  _ *libs.LogMiddleware `di:\"\"`\n}\n\n// GetHello a http request with \"get\" method.\n// Url should like this in local: http://localhost:8000/hello\nfunc (t *TWebServer) GetHello(ctx WebContext) {\n  ctx.IndentedJSON(http.StatusOK, \"/hello\")\n}\n\nfunc main() {\n  //f, _ := os.Create(\"gin.log\") // log to file\n  config := NewWebConfig().\n          //SetDefaultWriter(io.MultiWriter(f)).\n          SetDependentRef(libs.RefKeyForLogFormatter, (gin.LogFormatter)(func(params gin.LogFormatterParams) string {\n            // your custom format\n            return fmt.Sprintf(\"[%s-%s] \\\"%s %s\\\"\\n\",\n              params.ClientIP,\n              params.TimeStamp.Format(\"15:04:05.000\"),\n              params.Method,\n              params.Path,\n            )\n          }))\n  if err := LaunchGin(\u0026TWebServer{}, config); err != nil {\n    log.Fatalln(err)\n  }\n}\n```\n\n- Log functions only which set *log* middleware\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"github.com/gin-gonic/gin\"\n  . \"github.com/letscool/dij-gin\"\n  \"github.com/letscool/dij-gin/libs\"\n  \"log\"\n  \"net/http\"\n)\n\ntype TWebServer struct {\n  WebServer `http:\"\"`\n\n  _ *libs.LogMiddleware `di:\"\"`\n}\n\n// GetHelloWithLog a http request with \"get\" method.\n// Url should like this in local: http://localhost:8000/hello_with_log\nfunc (t *TWebServer) GetHelloWithLog(ctx struct {\n  WebContext `http:\"hello_with_log,middleware=log\"`\n}) {\n  ctx.IndentedJSON(http.StatusOK, \"hello with log\")\n}\n\n// GetHelloWithoutLog a http request with \"get\" method.\n// Url should like this in local: http://localhost:8000/hello_without_log\nfunc (t *TWebServer) GetHelloWithoutLog(ctx struct {\n  WebContext `http:\"hello_without_log\"`\n}) {\n  ctx.IndentedJSON(http.StatusOK, \"hello without log\")\n}\n\nfunc main() {\n  //f, _ := os.Create(\"gin.log\") // log to file\n  config := NewWebConfig().\n          //SetDefaultWriter(io.MultiWriter(f)).\n          SetDependentRef(libs.RefKeyForLogFormatter, (gin.LogFormatter)(func(params gin.LogFormatterParams) string {\n            // your custom format\n            return fmt.Sprintf(\"[%s-%s] \\\"%s %s\\\"\\n\",\n              params.ClientIP,\n              params.TimeStamp.Format(\"15:04:05.000\"),\n              params.Method,\n              params.Path,\n            )\n          }))\n  if err := LaunchGin(\u0026TWebServer{}, config); err != nil {\n    log.Fatalln(err)\n  }\n}\n```\n\n#### Basic Auth\n\nThis sample includes a middleware [basic_auth_middleware.go](https://github.com/LETSCOOL/go-examples/blob/main/dij-gin/shared/basic_auth_middleware.go)\nand a fake account db [account.go](https://github.com/LETSCOOL/go-examples/blob/main/dij-gin/shared/account.go),\nand also enables OpenAPI document.\n\n```go\npackage main\n\nimport (\n  . \"github.com/letscool/dij-gin\"\n  \"github.com/letscool/dij-gin/libs\"\n  \"github.com/letscool/go-examples/dij-gin/shared\"\n  \"log\"\n)\n\ntype TWebServer struct {\n  WebServer\n  _ *libs.SwaggerController `di:\"\"` // Bind OpenApi controller in root.\n  _ *TUserController        `di:\"\"`\n}\n\ntype TUserController struct {\n  WebController `http:\"user\"`\n\n  _ *shared.BasicAuthMiddleware `di:\"\"`\n}\n\n// GetMe a http request with \"get\" method.\n// Url should like this in local: http://localhost:8000/user/me.\n// And login with username \"john\" and password \"abc\".\nfunc (u *TUserController) GetMe(ctx struct {\n  WebContext `http:\",middleware=basic_auth\" security:\"basic_auth_1\"`\n}) (result struct {\n  Account *shared.Account `http:\"200,json\"`\n}) {\n  result.Account = ctx.MustGet(shared.BasicAuthUserKey).(*shared.Account)\n  return\n}\n\nfunc main() {\n  ac := \u0026shared.FakeAccountDb{} // This object should implement shared.BasicAuthAccountCenter interface.\n  ac.InitFakeDb()\n  config := NewWebConfig().\n    SetDependentRef(shared.RefKeyForBasicAuthAccountCenter, ac).\n          SetOpenApi(func(o *OpenApiConfig) {\n            o.Enable().UseHttpOnly().SetDocPath(\"doc\").\n              AppendBasicAuth(\"basic_auth_1\")\n          })\n  if err := LaunchGin(\u0026TWebServer{}, config); err != nil {\n    log.Fatalln(err)\n  }\n}\n```\n\n#### Bearer\nThis sample includes a middleware [bearer_middleware.go](https://github.com/LETSCOOL/go-examples/blob/main/dij-gin/shared/bearer_middleware.go)\nand a fake account db [account.go](https://github.com/LETSCOOL/go-examples/blob/main/dij-gin/shared/account.go),\nand also enables OpenAPI document.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/golang-jwt/jwt/v4\"\n\t. \"github.com/letscool/dij-gin\"\n\t\"github.com/letscool/dij-gin/libs\"\n\t\"github.com/letscool/go-examples/dij-gin/shared\"\n\t\"log\"\n\t\"time\"\n)\n\ntype TWebServer struct {\n\tWebServer\n\t_ *libs.SwaggerController `di:\"\"` // Bind OpenApi controller in root.\n\t_ *TUserController        `di:\"\"`\n}\n\ntype TUserController struct {\n\tWebController `http:\"user\"`\n\n\t_ *shared.BearerMiddleware `di:\"\"`\n}\n\n// GetMe a http request with \"get\" method.\n// Url should like this in local: http://localhost:8000/user/me.\n// And login with username \"john\" and password \"abc\".\nfunc (u *TUserController) GetMe(ctx struct {\n\tWebContext `http:\",middleware=bearer\" security:\"bearer_1\"`\n}) (result struct {\n\tAccount *shared.Account `http:\"200,json\"`\n}) {\n\tresult.Account = ctx.MustGet(shared.BearerUserKey).(*shared.Account)\n\treturn\n}\n\nfunc main() {\n\tac := \u0026shared.FakeAccountDb{} // This object must implement shared.BearerValidator interface.\n\taccounts := ac.InitFakeDb()\n\t// generate a jwt token for test\n\ttoken := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.RegisteredClaims{\n\t\tExpiresAt: jwt.NewNumericDate(time.Now().Add(5 * time.Minute)),\n\t\tIssuedAt:  jwt.NewNumericDate(time.Now()),\n\t\tIssuer:    \"dij-gin-samples\",\n\t\tID:        accounts[0].User,\n\t})\n\t// Sign and get the complete encoded token as a string using the secret\n\ttokenString, err := token.SignedString([]byte(ac.BearerSecret()))\n\tif err != nil {\n\t\tlog.Panicln(err)\n\t} else {\n\t\tfmt.Println(\"*************************\")\n\t\tfmt.Printf(\"User: %s\\n\", accounts[0].User)\n\t\tfmt.Printf(\"Bearer token: %s\\n\", tokenString)\n\t\tfmt.Println(\"*************************\")\n\t}\n\t//\n\tconfig := NewWebConfig().\n\t\tSetDependentRef(shared.RefKeyForBearerValidator, ac).\n\t\tSetOpenApi(func(o *OpenApiConfig) {\n\t\t\to.Enable().UseHttpOnly().SetDocPath(\"doc\").\n\t\t\t\tAppendBearerAuth(\"bearer_1\")\n\t\t})\n\tif err := LaunchGin(\u0026TWebServer{}, config); err != nil {\n\t\tlog.Fatalln(err)\n\t}\n}\n```\n\n#### ApiKey\nThis sample also enables OpenAPI document.\n\n```go\npackage main\n\nimport (\n\t\"errors\"\n\t. \"github.com/letscool/dij-gin\"\n\t\"github.com/letscool/dij-gin/libs\"\n\t\"log\"\n)\n\ntype TWebServer struct {\n\tWebServer\n\t_ *libs.SwaggerController `di:\"\"` // Bind OpenApi controller in root.\n\t_ *TUserController        `di:\"\"`\n}\n\ntype TUserController struct {\n\tWebController `http:\"user\"`\n}\n\n// GetMe a http request with \"get\" method.\n// Url should like this in local: http://localhost:8000/user/me.\n// And login with username \"john\" and password \"abc\".\nfunc (u *TUserController) GetMe(ctx struct {\n\tWebContext `http:\"\" security:\"ApiId,ApiKey\" description:\"Set ApiId=abc and ApiKey=EFG\"`\n\tapiId      string `http:\"api_id\"`\n\tapiKey     string `http:\"api_key\"`\n}) (result struct {\n\tMessage *string `http:\"200\"`\n\tError   error   `http:\"401\"`\n}) {\n\tif ctx.apiId == \"abc\" \u0026\u0026 ctx.apiKey == \"EFG\" {\n\t\tmsg := \"You got permission to access this api\"\n\t\tresult.Message = \u0026msg\n\t} else {\n\t\tresult.Error = errors.New(\"unauthorized api key\")\n\t}\n\treturn\n}\n\nfunc main() {\n\t// launch a web server\n\tconfig := NewWebConfig().\n\t\tSetOpenApi(func(o *OpenApiConfig) {\n\t\t\to.Enable().UseHttpOnly().SetDocPath(\"doc\").\n\t\t\t\tAppendApiKeyAuth(\"ApiId\", \"query\", \"api_id\").\n\t\t\t\tAppendApiKeyAuth(\"ApiKey\", \"query\", \"api_key\")\n\t\t})\n\tif err := LaunchGin(\u0026TWebServer{}, config); err != nil {\n\t\tlog.Fatalln(err)\n\t}\n}\n```\n\n#### CORS\n(on-going)\n\n\n### OpenAPI generation\nWhen you use dij-gin style to setup server, dij-gin server will automatically\ngenerate OpenAPI document if you need.\n\n```go\n// Copyright 2022 Yuchi Chen. All rights reserved.\n// Use of this source code is governed by a MIT style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"errors\"\n\t. \"github.com/letscool/dij-gin\"\n\t\"github.com/letscool/dij-gin/libs\"\n\t\"log\"\n)\n\ntype TWebServer struct {\n\tWebServer\n\n\topenapi *libs.SwaggerController `di:\"\"` // Bind OpenApi controller in root.\n}\n\n// GetResp a http request with \"get\" method.\n// Url should like this in local: http://localhost:8000/resp?select=1 .\n// Use *curl -v* command to see response code.\nfunc (s *TWebServer) GetResp(ctx struct {\n\tWebContext\n\tSelect int `http:\"select\"`\n}) (result struct {\n\tOk200 *string // the range of last three characters is between 2xx and 5xx, so the response code = 200\n\tOk    *string `http:\"201\"` // force response code to 201\n\tError error   // default response code for error is 400\n}) {\n\tswitch ctx.Select {\n\tcase 1:\n\t\tdata := \"ok\"\n\t\tresult.Ok200 = \u0026data\n\tcase 2:\n\t\tdata := \"ok\"\n\t\tresult.Ok = \u0026data\n\tdefault:\n\t\tresult.Error = errors.New(\"an error\")\n\t}\n\treturn\n}\n\n// The OpenAPI page will be enabled in location: http://localhost:8000/doc.\nfunc main() {\n\tconfig := NewWebConfig().\n\t\tSetOpenApi(func(o *OpenApiConfig) {\n\t\t\to.SetEnabled(true).UseHttpOnly().SetDocPath(\"doc\")\n\t\t})\n\tif err := LaunchGin(\u0026TWebServer{}, config); err != nil {\n\t\tlog.Fatalln(err)\n\t}\n}\n```\n\n\n## Http Tag\n______\n\n(on-going)\n\n#### Attributes\n\n- path\n- name\n- method\n- env\n- tag\n- middleware\n\n##### Coding/Media Type for Request Input\nThe http tag includes an attribute \"[AttrKey]\" for request and response body.\nand \"mime=[MIME_TYPE]\" for response body only.\n\n|      AttrKey       | Req/Resp | MIME Type                         |\n|:------------------:|:--------:|:----------------------------------|\n|  form, multipart   |   Req    | multipart/form-data               |\n| urlenc, urlencoded |   BOTH   | application/x-www-form-urlencoded |\n|        json        |   Both   | application/json                  |\n|        xml         |   Both   | application/xml                   |\n|       plain        |   Resp   | text/plain                        |\n|     page, html     |   Resp   | text/html                         |\n|       octet        |   Resp   | application/octet-stream          |\n|     jpeg, png      |   Resp   | image/jpeg,png                    |\n\n\n#### Data way for Request Input Variables\nThe http tag includes an attribute \"in=[AttrKey]\"\n\n| AttrKey | Default situation                    | Meaning |\n|:-------:|:-------------------------------------|:--------|\n| header  |                                      |         |\n| cookie  |                                      |         |\n|  path   | If variable name is included in path |         |\n|  query  |                                      |         |\n|  body   |                                      |         |\n\n\n## TODO List\n_____\n\nStill many function should be implemented, such as:\n- Redirect response\n- Response urlencoded data\n- More middlewares\n- Fix bugs\n- More examples for http tag settings\n- Add unit tests\n- Dynamic path for controller\n- NoRoute","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fletscool%2Fdij-gin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fletscool%2Fdij-gin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fletscool%2Fdij-gin/lists"}