{"id":15091358,"url":"https://github.com/contiamo/openapi-generator-go","last_synced_at":"2025-10-15T15:09:31.905Z","repository":{"id":37337900,"uuid":"312311416","full_name":"contiamo/openapi-generator-go","owner":"contiamo","description":"An opinionated OpenAPI v3 code generator for Go. Use this to generate API models and router scaffolding.","archived":false,"fork":false,"pushed_at":"2025-03-31T11:32:24.000Z","size":496,"stargazers_count":109,"open_issues_count":10,"forks_count":11,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-05-25T11:06:13.840Z","etag":null,"topics":["code-generator","golang","openapi","openapi-generator","openapi-spec","openapi3","platform"],"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/contiamo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-11-12T15:04:52.000Z","updated_at":"2025-03-09T07:05:01.000Z","dependencies_parsed_at":"2023-11-25T11:24:00.272Z","dependency_job_id":"90275606-b1ea-463d-bc30-62153faca5b1","html_url":"https://github.com/contiamo/openapi-generator-go","commit_stats":{"total_commits":123,"total_committers":12,"mean_commits":10.25,"dds":0.7642276422764227,"last_synced_commit":"ff2160a0bd29ff3a9a0d7b08c3dd040f0c5e69e9"},"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"purl":"pkg:github/contiamo/openapi-generator-go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/contiamo%2Fopenapi-generator-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/contiamo%2Fopenapi-generator-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/contiamo%2Fopenapi-generator-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/contiamo%2Fopenapi-generator-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/contiamo","download_url":"https://codeload.github.com/contiamo/openapi-generator-go/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/contiamo%2Fopenapi-generator-go/sbom","scorecard":{"id":303514,"data":{"date":"2025-08-11","repo":{"name":"github.com/contiamo/openapi-generator-go","commit":"d709ad4531430d5e0e827d23e3988fe556d95bfa"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.3,"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":"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":"Code-Review","score":6,"reason":"Found 6/9 approved changesets -- score normalized to 6","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":"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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/conventional-commits.yaml:1","Warn: no topLevel permission defined: .github/workflows/release-please.yaml:1","Warn: topLevel 'contents' permission set to 'write': .github/workflows/release.yaml:8","Warn: topLevel 'packages' permission set to 'write': .github/workflows/release.yaml:9","Warn: no topLevel permission defined: .github/workflows/test.yaml: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":"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":"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/conventional-commits.yaml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/conventional-commits.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/conventional-commits.yaml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/conventional-commits.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-please.yaml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/release-please.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/release.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/release.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yaml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/release.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yaml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/release.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yaml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/release.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yaml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/release.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yaml:68: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/release.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yaml:70: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/release.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yaml:72: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/release.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yaml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/test.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yaml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/test.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yaml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/contiamo/openapi-generator-go/test.yaml/master?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1: pin your Docker image by updating gcr.io/distroless/static:nonroot to gcr.io/distroless/static:nonroot@sha256:cdf4daaf154e3e27cfffc799c16f343a384228f38646928a1513d925f473cb46","Info:   0 out of   5 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of  10 third-party GitHubAction dependencies pinned","Info:   0 out of   1 containerImage 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":"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":"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":"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":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"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":"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":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 27 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":9,"reason":"1 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2025-3533 / GHSA-wq9g-9vfc-cfq9"],"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-17T21:22:41.630Z","repository_id":37337900,"created_at":"2025-08-17T21:22:41.630Z","updated_at":"2025-08-17T21:22:41.630Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279085811,"owners_count":26100020,"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","status":"online","status_checked_at":"2025-10-15T02:00:07.814Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["code-generator","golang","openapi","openapi-generator","openapi-spec","openapi3","platform"],"created_at":"2024-09-25T10:40:34.745Z","updated_at":"2025-10-15T15:09:31.877Z","avatar_url":"https://github.com/contiamo.png","language":"Go","readme":"openapi-generator-go\n====================\n\n![test](https://github.com/contiamo/openapi-generator-go/workflows/test/badge.svg)\n\nGenerate go code from an openapi spec!\n\n```bash\n# generate structs, enums and a router from a spec file\nopenapi-generator-go generate --spec ./example/api.yaml --output ./example/generated\n# generate models and router independently\nopenapi-generator-go generate models --spec ./example/api.yaml --output ./example/models --package-name models\nopenapi-generator-go generate router --spec ./example/api.yaml --output ./example/router --package-name router\n```\n\n## Why\nThe platform team at Contiamo has a schema first development flow. This means we write and review the OpenAPI spec before we write the implementation.\n\nTo make this easier we started using (or tried to use) various OpenAPI code generators to reduce busy work and ensure precise consistent implementations. Unfortunately, we never really enjoyed the output from these generators and have created our own generator that matches our preferred style and conventions.\n\n## What\nThe generator consists of two parts\n\n1. generator for the HTTP server mux using [go-chi](https://github.com/go-chi/chi), and\n2. a model generator for the request and response objects.\n\n### The router generator\nWe chose `go-chi` because it is fast, supports the standard library Handler interface, and is easy to add middlewares using `r.Use`.\n\nThe generator will create a method `NewRouter` and handler interfaces that you must then implement and pass to `NewRouter`. It is important to note that it does not generate any handler logic, just the required interfaces.  Handlers can be grouped into specific interfaces by adding `x-handler-group: \u003cName\u003e` to your schema. This is one of the only schema extensions we have added to improve our code generation. The handler interface will be called `NameHandler` and will have a method matching the `operationId` from the spec.\n\nFor example, each of our projects will implement a project specific `NewRouter` that does the handler configuration and  initialization of the generated router. In the next example, `openapi.NewRouter` is generated using\n\n```sh\nopenapi-generator-go generate router --spec ./example/api.yaml --output ./example/router --package-name openapi\n```\nThe project specific router initialization:\n```go\nfunc NewRouter(ctx context.Context, db *sql.DB, cfg config.Config) (http.Handler, error) {\n    // do setup stuff\n\n    // and probably some more setup for each of the handler implementations\n    userHandler := handlers.NewUserHandler(ctx, db)\n    resourcesHandler := handlers.NewResource(ctx, db)\n\n    // openapi-generator-go generate router --spec ./example/api.yaml --output ./example/router --package-name openapi\n    apiRouter := openapi.NewRouter(\n        // the UsersHandler interface contains a method for endpoint with\n        // x-handler-group: Users\n        userHandler,\n\n        // ResourcesHandler interace contains a method for each endpoint with\n        // x-handler-group: Resources\n        resourcesHandler,\n    )\n\n    root.Route(\"/\", func(api chi.Router) {\n        // now  init and dd your middlewares\n\t\tr := middlewares.WithRecovery(os.Stderr, cfg.Debug)\n\t\tt := middlewares.WithTracing(config.ApplicationName, nil, middlewares.ChiRouteName)\n\t\tl := middlewares.WithLogging(config.ApplicationName)\n\t\tm := middlewares.WithMetrics(config.ApplicationName, nil)\n\t\ta := authorization.NewMiddleware(cfg.Authorization.HeaderName, publicKey)\n\n\t\tapi.Use(r.WrapHandler)\n\t\tapi.Use(t.WrapHandler)\n\t\tapi.Use(l.WrapHandler)\n\t\tapi.Use(m.WrapHandler)\n\t\tapi.Use(a.WrapHandler)\n\n        // mount the generate router\n\t\tapi.Mount(\"/\", apiRouter)\n\t})\n\n\treturn root, nil\n\n}\n```\n\n### The model generator\nThe model generator is a work in progress, but covers the most common cases we need in a REST API.\n\nYou can find various examples of the what is supported and the corresponding output in our [test fixtures](./pkg/generators/models/testdata/cases).\n\nOur generator differs from the official OpenAPI generator tools by also providing getters for many fields, which makes it easier to define and work with interfaces of the models.\n\nWe also provide better support for :\n* [enums](./pkg/generators/models/testdata/cases/enums/expected/model_filter_type.go), enum support also includes some utility methods that make validating the enums much easier,\n  * Now including support for string, integer, and number (i.e. decimal) enums.\n* [arrays](./pkg/generators/models/testdata/cases/typed_arrays/expected/model_foo.go),\n* [allOf](./pkg/generators/models/testdata/cases/allof1/expected/model_foo.go),\n* and [oneOf](./pkg/generators/models/testdata/cases/oneof/expected/model_foo.go)\nthat feel more natural in Go. Creating as many strong types as is possible and using `interface{}` otherwise. These cases often failed or generated non-compilable code with the official generator.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontiamo%2Fopenapi-generator-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcontiamo%2Fopenapi-generator-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontiamo%2Fopenapi-generator-go/lists"}