{"id":38714917,"url":"https://github.com/pangpanglabs/echoswagger","last_synced_at":"2026-01-17T11:02:33.583Z","repository":{"id":53088005,"uuid":"146755453","full_name":"pangpanglabs/echoswagger","owner":"pangpanglabs","description":"Swagger UI generator for Echo framework","archived":false,"fork":false,"pushed_at":"2022-11-08T02:34:28.000Z","size":95,"stargazers_count":66,"open_issues_count":4,"forks_count":16,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-09-26T03:54:34.385Z","etag":null,"topics":["echo","go","swagger","swagger-ui"],"latest_commit_sha":null,"homepage":null,"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/pangpanglabs.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":"security.go","support":null}},"created_at":"2018-08-30T13:41:51.000Z","updated_at":"2025-03-09T14:07:03.000Z","dependencies_parsed_at":"2022-09-18T18:15:31.843Z","dependency_job_id":null,"html_url":"https://github.com/pangpanglabs/echoswagger","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/pangpanglabs/echoswagger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pangpanglabs%2Fechoswagger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pangpanglabs%2Fechoswagger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pangpanglabs%2Fechoswagger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pangpanglabs%2Fechoswagger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pangpanglabs","download_url":"https://codeload.github.com/pangpanglabs/echoswagger/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pangpanglabs%2Fechoswagger/sbom","scorecard":{"id":719092,"data":{"date":"2025-08-11","repo":{"name":"github.com/pangpanglabs/echoswagger","commit":"aeec649d7f0abc0c2fa1dd409ce6bcbae141120e"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.6,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 1/20 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/pangpanglabs/echoswagger/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/pangpanglabs/echoswagger/ci.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/pangpanglabs/echoswagger/ci.yml/master?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'","Warn: branch protection not enabled for branch 'v2'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 20 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":1,"reason":"9 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2022-0229 / GHSA-cjjc-xp8v-855w","Warn: Project is vulnerable to: GO-2020-0012 / GHSA-ffhg-7mh4-33c4","Warn: Project is vulnerable to: GO-2021-0227 / GHSA-3vm4-22fp-5rfm","Warn: Project is vulnerable to: GO-2022-0968 / GHSA-gwc9-m7rh-j2ww","Warn: Project is vulnerable to: GO-2021-0356 / GHSA-8c26-wmh5-6g9v","Warn: Project is vulnerable to: GO-2024-2961","Warn: Project is vulnerable to: GO-2023-2402 / GHSA-45x7-px36-x8w8","Warn: Project is vulnerable to: GO-2024-3321 / GHSA-v778-237x-gjrc","Warn: Project is vulnerable to: GO-2025-3487 / GHSA-hcg3-q754-cr77"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T10:42:48.662Z","repository_id":53088005,"created_at":"2025-08-22T10:42:48.662Z","updated_at":"2025-08-22T10:42:48.662Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28506593,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T10:25:30.148Z","status":"ssl_error","status_checked_at":"2026-01-17T10:25:29.718Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: 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":["echo","go","swagger","swagger-ui"],"created_at":"2026-01-17T11:02:33.192Z","updated_at":"2026-01-17T11:02:33.457Z","avatar_url":"https://github.com/pangpanglabs.png","language":"Go","readme":"English | [简体中文](./README_zh-CN.md)\n\n# Echoswagger\n[Swagger UI](https://github.com/swagger-api/swagger-ui) generator for [Echo](https://github.com/labstack/echo) framework\n\n[![Ci](https://github.com/pangpanglabs/echoswagger/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/pangpanglabs/echoswagger/actions/workflows/ci.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/pangpanglabs/echoswagger)](https://goreportcard.com/report/github.com/pangpanglabs/echoswagger)\n[![Go Reference](https://pkg.go.dev/badge/github.com/pangpanglabs/echoswagger.svg)](https://pkg.go.dev/github.com/pangpanglabs/echoswagger)\n[![codecov](https://codecov.io/gh/pangpanglabs/echoswagger/branch/master/graph/badge.svg)](https://codecov.io/gh/pangpanglabs/echoswagger)\n\n## Feature\n- No SwaggerUI HTML/CSS dependency\n- Highly integrated with Echo, low intrusive design\n- Take advantage of the strong typing language and chain programming to make it easy to use\n- Recycle garbage in time, low memory usage\n\n## Installation\n```\ngo get github.com/pangpanglabs/echoswagger\n```\n\n## Go modules support\nIf your project has migrated to Go modules, you can:\n- Choose v2 version of Echoswagger for Echo version v4.\n- Choose v1 version of Echoswagger for Echo version \u003c= v3.\n\nTo use v2 version, just do:\n- `go get github.com/pangpanglabs/echoswagger/v2`\n- import `github.com/labstack/echo/v4` and `github.com/pangpanglabs/echoswagger/v2` in your project\n\nMeanwhile, v1 version will still be updated if needed. For more details of Go modules, please refer to [Go Wiki](https://github.com/golang/go/wiki/Modules).\n\n## Example\n```go\npackage main\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/labstack/echo\"\n\t\"github.com/pangpanglabs/echoswagger\"\n)\n\nfunc main() {\n\t// ApiRoot with Echo instance\n\tr := echoswagger.New(echo.New(), \"/doc\", nil)\n\n\t// Routes with parameters \u0026 responses\n\tr.POST(\"/\", createUser).\n\t\tAddParamBody(User{}, \"body\", \"User input struct\", true).\n\t\tAddResponse(http.StatusCreated, \"successful\", nil, nil)\n\n\t// Start server\n\tr.Echo().Logger.Fatal(r.Echo().Start(\":1323\"))\n}\n\ntype User struct {\n\tName string\n}\n\n// Handler\nfunc createUser(c echo.Context) error {\n\treturn c.JSON(http.StatusCreated, nil)\n}\n\n```\n\n## Usage\n#### Create a `ApiRoot` with `New()`, which is a wrapper of `echo.New()`\n```go\nr := echoswagger.New(echo.New(), \"/doc\", nil)\n```\nYou can use the result `ApiRoot` instance to:\n- Setup Security definitions, request/response Content-Types, UI options, Scheme, etc.\n```go\nr.AddSecurityAPIKey(\"JWT\", \"JWT Token\", echoswagger.SecurityInHeader).\n\tSetRequestContentType(\"application/x-www-form-urlencoded\", \"multipart/form-data\").\n\tSetUI(UISetting{HideTop: true}).\n\tSetScheme(\"https\", \"http\")\n```\n- Get `echo.Echo` instance.\n```go\nr.Echo()\n```\n- Registers a new GET, POST, PUT, DELETE, OPTIONS, HEAD or PATCH route in default group, these are wrappers of Echo's create route methods.\nIt returns a new `Api` instance.\n```go\nr.GET(\"/:id\", handler)\n```\n- And: ↓\n\n#### Create a `ApiGroup` with `Group()`, which is a wrapper of `echo.Group()`\n```go\ng := r.Group(\"Users\", \"/users\")\n```\nYou can use the result `ApiGroup` instance to:\n- Set description, etc.\n```go\ng.SetDescription(\"The desc of group\")\n```\n- Set security for all routes in this group.\n```go\ng.SetSecurity(\"JWT\")\n```\n- Get `echo.Group` instance.\n```go\ng.EchoGroup()\n```\n- And: ↓\n\n#### Registers a new route in `ApiGroup`\nGET, POST, PUT, DELETE, OPTIONS, HEAD or PATCH methods are supported by Echoswagger, these are wrappers of Echo's create route methods.\n```go\na := g.GET(\"/:id\", handler)\n```\nYou can use the result `Api` instance to:\n- Add parameter with these methods:\n```go\nAddParamPath(p interface{}, name, desc string)\n\nAddParamPathNested(p interface{})\n\nAddParamQuery(p interface{}, name, desc string, required bool)\n\nAddParamQueryNested(p interface{})\n\nAddParamForm(p interface{}, name, desc string, required bool)\n\nAddParamFormNested(p interface{})\n\nAddParamHeader(p interface{}, name, desc string, required bool)\n\nAddParamHeaderNested(p interface{})\n\nAddParamBody(p interface{}, name, desc string, required bool)\n\nAddParamFile(name, desc string, required bool)\n```\n\nThe methods which name's suffix are `Nested` means these methods treat parameter `p` 's fields as paramters, so it must be a struct type.\n\ne.g.\n```go\ntype SearchInput struct {\n\tQ         string `query:\"q\" swagger:\"desc(Keywords),required\"`\n\tSkipCount int    `query:\"skipCount\"`\n}\na.AddParamQueryNested(SearchInput{})\n```\nIs equivalent to:\n```go\na.AddParamQuery(\"\", \"q\", \"Keywords\", true).\n\tAddParamQuery(0, \"skipCount\", \"\", false)\n```\n- Add responses.\n```go\na.AddResponse(http.StatusOK, \"response desc\", body{}, nil)\n```\n- Set Security, request/response Content-Types, summary, description, etc.\n```go\na.SetSecurity(\"JWT\").\n\tSetResponseContentType(\"application/xml\").\n\tSetSummary(\"The summary of API\").\n\tSetDescription(\"The desc of API\")\n```\n- Get `echo.Route` instance.\n```go\na.Route()\n```\n\n#### With `swagger` tag, you can set more info with `AddParam...` methods.\ne.g.\n```go\ntype User struct {\n\tAge    int       `swagger:\"min(0),max(99)\"`\n\tGender string    `swagger:\"enum(male|female|other),required\"`\n\tMoney  []float64 `swagger:\"default(0),readOnly\"`\n}\na.AddParamBody(\u0026User{}, \"Body\", \"\", true)\n```\nThe definition is equivalent to:\n```json\n{\n    \"definitions\": {\n        \"User\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"Age\": {\n                    \"type\": \"integer\",\n                    \"format\": \"int32\",\n                    \"minimum\": 0,\n                    \"maximum\": 99\n                },\n                \"Gender\": {\n                    \"type\": \"string\",\n                    \"enum\": [\n                        \"male\",\n                        \"female\",\n                        \"other\"\n                    ],\n                    \"format\": \"string\"\n                },\n                \"Money\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"type\": \"number\",\n                        \"default\": 0,\n                        \"format\": \"double\"\n                    },\n                    \"readOnly\": true\n                }\n            },\n            \"required\": [\n                \"Gender\"\n            ]\n        }\n    }\n}\n```\n\n**Supported `swagger` tags:**\n\nTag | Type | Description\n---|:---:|---\ndesc | `string` | Description.\nmin | `number` | -\nmax | `number` | -\nminLen | `integer` | -\nmaxLen | `integer` | -\nallowEmpty | `boolean` | Sets the ability to pass empty-valued parameters. This is valid only for either `query` or `formData` parameters and allows you to send a parameter with a name only or  an empty value. Default value is `false`.\nrequired | `boolean` | Determines whether this parameter is mandatory. If the parameter is `in` \"path\", this property is `true` without setting. Otherwise, the property MAY be included and its default value is `false`.\nreadOnly | `boolean` | Relevant only for Schema `\"properties\"` definitions. Declares the property as \"read only\". This means that it MAY be sent as part of a response but MUST NOT be sent as part of the request. Properties marked as `readOnly` being `true` SHOULD NOT be in the `required` list of the defined schema. Default value is `false`.\nenum | [*] | Enumerate value, multiple values should be separated by \"\\|\"\ndefault | * | Default value, which type is same as the field's type.\n\n#### If you want to disable Echoswagger in some situation, please use `NewNop` method. It would neither create router nor generate any doc.\ne.g.\n```go\ne := echo.New()\nvar se echoswagger.ApiRoot\nif os.Getenv(\"env\") == \"production\" {\n    // Disable SwaggerEcho in production enviroment\n\tse = echoswagger.NewNop(e)\n} else {\n\tse = echoswagger.New(e, \"doc/\", nil)\n}\n```\n\n## Reference\n[OpenAPI Specification 2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md)\n\n## License\n\n[MIT](https://github.com/pangpanglabs/echoswagger/blob/master/LICENSE)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpangpanglabs%2Fechoswagger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpangpanglabs%2Fechoswagger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpangpanglabs%2Fechoswagger/lists"}