{"id":35164975,"url":"https://github.com/ethanbaker/api","last_synced_at":"2026-05-21T09:03:07.545Z","repository":{"id":288717169,"uuid":"957317803","full_name":"ethanbaker/api","owner":"ethanbaker","description":"A modular implementation of a golang API with Gin","archived":false,"fork":false,"pushed_at":"2025-06-15T15:07:04.000Z","size":249,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-31T07:20:11.943Z","etag":null,"topics":["api","api-keys","gin","go","golang","jwt","template","template-generic-repo"],"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/ethanbaker.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-03-30T04:00:22.000Z","updated_at":"2025-06-15T15:08:01.000Z","dependencies_parsed_at":"2025-06-10T00:18:44.542Z","dependency_job_id":"c9b88bbf-4156-47ee-b5bc-1f8a00a6faad","html_url":"https://github.com/ethanbaker/api","commit_stats":null,"previous_names":["ethanbaker/api"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/ethanbaker/api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethanbaker%2Fapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethanbaker%2Fapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethanbaker%2Fapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethanbaker%2Fapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ethanbaker","download_url":"https://codeload.github.com/ethanbaker/api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethanbaker%2Fapi/sbom","scorecard":{"id":383777,"data":{"date":"2025-08-11","repo":{"name":"github.com/ethanbaker/api","commit":"8c0864e35464fcb8877044481d9a42fc5fa010f3"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.7,"checks":[{"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":"Dangerous-Workflow","score":-1,"reason":"no workflows found","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":5,"reason":"6 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 5","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":0,"reason":"Found 0/5 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":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"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":"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":-1,"reason":"no dependencies found","details":null,"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 'main'"],"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 3 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":10,"reason":"0 existing vulnerabilities detected","details":null,"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-18T16:06:39.463Z","repository_id":288717169,"created_at":"2025-08-18T16:06:39.463Z","updated_at":"2025-08-18T16:06:39.463Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33295252,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-21T02:57:32.698Z","status":"ssl_error","status_checked_at":"2026-05-21T02:57:31.990Z","response_time":62,"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":["api","api-keys","gin","go","golang","jwt","template","template-generic-repo"],"created_at":"2025-12-28T19:13:07.251Z","updated_at":"2026-05-21T09:03:07.536Z","avatar_url":"https://github.com/ethanbaker.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!--\n  Created by: Ethan Baker (contact@ethanbaker.dev)\n  \n  Adapted from:\n    https://github.com/othneildrew/Best-README-Template/\n\nHere are different preset \"variables\" that you can search and replace in this template.\n`path_to_logo`\n`path_to_demo`\n--\u003e\n\u003cdiv id=\"top\"\u003e\u003c/div\u003e\n\n\n\u003c!-- PROJECT SHIELDS/BUTTONS --\u003e\n\u003c!-- \nNEED GITHUB WORKFLOW [![Go Coverage](https://github.com/USER/REPO/wiki/coverage.svg)](https://raw.githack.com/wiki/USER/REPO/coverage.html)\n--\u003e\n![1.1.1](https://img.shields.io/badge/status-1.1.1-yellow)\n[![GoDoc](https://godoc.org/github.com/ethanbaker/api?status.svg)](https://godoc.org/github.com/ethanbaker/api)\n[![Go Report Card](https://goreportcard.com/badge/github.com/ethanbaker/api)](https://goreportcard.com/report/github.com/ethanbaker/api)\n[![Contributors][contributors-shield]][contributors-url]\n[![Forks][forks-shield]][forks-url]\n[![Stargazers][stars-shield]][stars-url]\n[![Issues][issues-shield]][issues-url]\n[![License][license-shield]][license-url]\n[![LinkedIn][linkedin-shield]][linkedin-url]\n\n\u003c!-- PROJECT LOGO --\u003e\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://github.com/ethanbaker/api\"\u003e\n    \u003cimg src=\"./docs/logo.png\" alt=\"Logo\" width=\"80\" height=\"80\"\u003e\n  \u003c/a\u003e\n\n  \u003ch3 align=\"center\"\u003eGo-API Template\u003c/h3\u003e\n\n  \u003cp align=\"center\"\u003e\n    A modular implementation of a golang API with Gin\n  \u003c/p\u003e\n\u003c/div\u003e\n\n\n\u003c!-- TABLE OF CONTENTS --\u003e\n\u003cdetails\u003e\n  \u003csummary\u003eTable of Contents\u003c/summary\u003e\n  \u003col\u003e\n    \u003cli\u003e\n      \u003ca href=\"#about-the-project\"\u003eAbout\u003c/a\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#built-with\"\u003eBuilt With\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n    \u003c/li\u003e\n    \u003cli\u003e\n      \u003ca href=\"#getting-started\"\u003eGetting Started\u003c/a\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#prerequisites\"\u003ePrerequisites\u003c/a\u003e\u003c/li\u003e\n        \u003cli\u003e\u003ca href=\"#installation\"\u003eInstallation\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n    \u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#usage\"\u003eUsage\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#roadmap\"\u003eRoadmap\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#contributing\"\u003eContributing\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#license\"\u003eLicense\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#contact\"\u003eContact\u003c/a\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/details\u003e\n\n\n\u003c!-- ABOUT --\u003e\n## About\n\nThis project provides a well-structured API using Go and the Gin framework. It\nincludes authentication, key-based validation, and user management features. Inside\nthe `pkg` directory, there are numerous external packages you can use in your custom\nAPIs. In addition, you can clone and modify these packages as needed.\n\nThe idea of this project is to serve multiple different API functionalities (dubbed modules)\nfrom the same instance (or URL if you're self hosting). Each module should be *its own use case* \nand shouldn't require direct overlap with other modules. For example, you *should* separate\na personal budget API schema into one module and a netflix movie catalog API schema into a\ndifferent module. You should *not* separate related functionality, such as transactions and\ninvoice endpoints for one project, as they probably use common types (`Transaction`, `Invoice`, etc).\n\nThe general implementation follows a modular architecture in the `template` directory:\n\n* **internal**: Handle shared functionality between modules. For example, if you are running an API\nto serve multiple customer sites, you'll probably need different modules for each site's\nspecifications. But, if all sites implement a chat-bot feature, you could create one common package\nin the `internal` directory to house this\n\n* **modules**: Custom-defined API modules, all being served from the same API.\nModify these as you desire according to the Gin framework!\n\n* **docs**: Contain documentation (markdown files, word files, images, etc) for your API\n\n* **main.go**: Set global configuration settings and run your API!\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n### Built With\n\n* [Golang](https://go.dev/)\n* [Gin](https://gin-gonic.com/)\n* [JWT Authentication](https://jwt.io/)\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\u003c!-- GETTING STARTED --\u003e\n## Getting Started\n\n### Prerequisites\n\n* Go (v1.24)\n* Git\n\n### Installation\n\nInstall instructions are written in bash for simplicity.\n\n1. Clone the repo\n```bash\ngit clone https://github.com/ethanbaker/api.git\n```\n\n2. Navigate to project folder\n```bash\ncd api\n```\n\n3. Copy template folder to your intended destination\n```bash\ncp -r templates/ ...\n```\n\n4. Implement custom modules in the `modules/` directory. You can import module routes into the \n`main.go` file. You can import `pkg` libraries from this repository directly or modify them\nfrom the clone and add them to `internal/` in your template\n\n5. Set up environment variables in .env file as needed for your API\n```bash\nPORT=8080\nJWT_SECRET=your_secret_key\n...\n```\n\n6. Start the server\n```bash\ngo run main.go\n```\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\u003c!-- USAGE EXAMPLES --\u003e\n## Usage\n\nExample endpoints and `pkg` library usage can be found in the `example` directory.\n\nIn order for the `users` module to properly work, you must supply a `.env` file with\na value for `JWT_SECRET`.\n\n### Health Module (Open Endpoint)\n\nThis module serves as a basic health check. It returns an \"ok\" message when queried,\nconfirming that the API is running. This is the most basic API route with no protection.\n\n```bash\ncurl -X GET 'http://localhost:8080/health'\n```\n\nResponse:\n```json\n{\"status\":\"success\",\"code\":200,\"message\":\"OK\"}\n```\n\n### Key Module (API Key Validation)\n\nThis module verifies API keys. A request will only succeed if a valid API key is\nincluded in the request headers.\n\n**Successful API Query:**\n```bash\ncurl -X GET 'http://localhost:8080/key/response' -H 'X-API-KEY: 1234567890'\n```\n\nResponse:\n```json\n{\"status\":\"success\",\"code\":200,\"message\":\"API Key is valid\"}\n```\n\n**Invalid API Query:**\n```bash\ncurl -X GET 'http://localhost:8080/key/response' \\\n    -H 'X-API-KEY: invalid-key'\n```\n\nResponse:\n```json\n{\"status\":\"fail\",\"code\":403,\"message\":\"\",\"error\":\"Invalid API Key\"}\n```\n\n### User Module (JWT Authentication)\n\nThis module tests user authentication with JWT. Users must log in to receive a\ntoken, which is required to access protected endpoints.\n\n**Successful Unprotected Query:**\n```bash\ncurl -X GET 'http://localhost:8080/users/anon-response'\n```\n\nResponse:\n```json\n{\"status\":\"success\",\"code\":200,\"message\":\"Hello, anonymous user!\"}\n```\n\n**Invalid Protected Query:**\n```bash\ncurl -X GET 'http://localhost:8080/users/response'\n```\n\nResponse:\n```json\n{\"status\":\"fail\",\"code\":401,\"message\":\"\",\"error\":\"cookie token is empty\"}\n```\n\n**Successful Login Attempt:**\n```bash\ncurl -X POST 'http://localhost:8080/users/auth/login' \\\n    -H 'Content-Type: application/json' \\\n    -d '{\"username\": \"admin\", \"password\": \"admin\"}'\n```\n\nResponse:\n```json\n{\"code\":200,\"expire\":\"YYYY-MM-DDTHH:MM:SSZ\",\"token\":\"JWT_TOKEN\"}\n```\n\n**Successful Protected Query:**\n```bash\ncurl -X GET 'http://localhost:8080/users/response' \\\n    -H 'Authorization: Bearer JWT_TOKEN'\n```\n\nResponse:\n```json\n{\"status\":\"success\",\"code\":200,\"message\":\"Hello admin!\",\"data\":{\"username\":\"admin\"}}\n```\n\n_For more examples, please refer to the [documentation][documentation-url]._\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\u003c!-- ROADMAP --\u003e\n## Roadmap\n\n- [x] Generalizable package\n- [ ] Cmd scaffolding tool\n- [ ] Docker Containerization\n- [ ] Comprehensive MySQL Integration\n\nSee the [open issues][issues-url] for a full list of proposed features (and known issues).\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\u003c!-- CONTRIBUTING --\u003e\n## Contributing\n\nFor issues and suggestions, please include as much useful information as possible.\nReview the [documentation][documentation-url] and make sure the issue is actually\npresent or the suggestion is not included. Please share issues/suggestions on the\n[issue tracker][issues-url].\n\nFor patches and feature additions, please submit them as [pull requests][pulls-url]. \nPlease adhere to the [conventional commits][conventional-commits-url]. standard for\ncommit messaging. In addition, please try to name your git branch according to your\nnew patch. [These standards][conventional-branches-url] are a great guide you can follow.\n\nYou can follow these steps below to create a pull request:\n\n1. Fork the Project\n2. Create your Feature Branch (`git checkout -b branch_name`)\n3. Commit your Changes (`git commit -m \"commit_message\"`)\n4. Push to the Branch (`git push origin branch_name`)\n5. Open a Pull Request\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\u003c!-- LICENSE --\u003e\n## License\n\nThis project uses the MIT License.\n\nYou can find more information in the [LICENSE][license-url] file.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\u003c!-- CONTACT --\u003e\n## Contact\n\nEthan Baker - contact@ethanbaker.dev - [LinkedIn][linkedin-url]\n\nProject Link: [https://github.com/ethanbaker/api][project-url]\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- MARKDOWN LINKS \u0026 IMAGES --\u003e\n\u003c!-- https://www.markdownguide.org/basic-syntax/#reference-style-links --\u003e\n[contributors-shield]: https://img.shields.io/github/contributors/ethanbaker/api.svg\n[forks-shield]: https://img.shields.io/github/forks/ethanbaker/api.svg\n[stars-shield]: https://img.shields.io/github/stars/ethanbaker/api.svg\n[issues-shield]: https://img.shields.io/github/issues/ethanbaker/api.svg\n[license-shield]: https://img.shields.io/github/license/ethanbaker/api.svg\n[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?logo=linkedin\u0026colorB=555\n\n[contributors-url]: \u003chttps://github.com/ethanbaker/api/graphs/contributors\u003e\n[forks-url]: \u003chttps://github.com/ethanbaker/api/network/members\u003e\n[stars-url]: \u003chttps://github.com/ethanbaker/api/stargazers\u003e\n[issues-url]: \u003chttps://github.com/ethanbaker/api/issues\u003e\n[pulls-url]: \u003chttps://github.com/ethanbaker/api/pulls\u003e\n[license-url]: \u003chttps://github.com/ethanbaker/api/blob/master/LICENSE\u003e\n[linkedin-url]: \u003chttps://linkedin.com/in/ethandbaker\u003e\n[project-url]: \u003chttps://github.com/ethanbaker/api\u003e\n\n[product-screenshot]: path_to_demo\n[documentation-url]: https://godoc.org/github.com/ethanbaker/api\n\n[conventional-commits-url]: \u003chttps://www.conventionalcommits.org/en/v1.0.0/#summary\u003e\n[conventional-branches-url]: \u003chttps://docs.microsoft.com/en-us/azure/devops/repos/git/git-branching-guidance?view=azure-devops\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fethanbaker%2Fapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fethanbaker%2Fapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fethanbaker%2Fapi/lists"}