{"id":21634284,"url":"https://github.com/cookeem/gohub-trending","last_synced_at":"2026-04-09T01:31:20.197Z","repository":{"id":139312441,"uuid":"157511575","full_name":"cookeem/gohub-trending","owner":"cookeem","description":"golang github trending demo app","archived":false,"fork":false,"pushed_at":"2019-02-25T04:46:18.000Z","size":13970,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-03T16:31:37.096Z","etag":null,"topics":["gin","github","golang","gorm","jwt","mysql","react","redux","trending"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cookeem.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2018-11-14T07:53:42.000Z","updated_at":"2023-07-20T03:45:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"1618c7b9-fba7-496d-9d4e-9cf6ede50258","html_url":"https://github.com/cookeem/gohub-trending","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/cookeem/gohub-trending","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cookeem%2Fgohub-trending","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cookeem%2Fgohub-trending/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cookeem%2Fgohub-trending/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cookeem%2Fgohub-trending/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cookeem","download_url":"https://codeload.github.com/cookeem/gohub-trending/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cookeem%2Fgohub-trending/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31581864,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T14:31:17.711Z","status":"ssl_error","status_checked_at":"2026-04-08T14:31:17.202Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["gin","github","golang","gorm","jwt","mysql","react","redux","trending"],"created_at":"2024-11-25T03:16:13.663Z","updated_at":"2026-04-09T01:31:20.187Z","avatar_url":"https://github.com/cookeem.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# golang github trending demo app\n\n## 界面样例\n\n![](images/gitrepo-search.png)\n\n## 界面流程\n\n- 界面跳转流程图如下：\n\n![](images/gitrepo-ui-diagram.png)\n\n## 服务架构\n\n- 服务分为五个模块，架构图如下图：\n\n  ![](images/gitrepo-modules.png)\n\n  - 前端界面（frontend-svc）：用户操作的前端webapp\n\n  - 后端服务（backend-svc）：这是一个后端服务的反向代理，frontend-svc所有请求都指向backend-svc，backend-svc再把请求forward给对应的服务。\n\n  - 用户管理服务（user-svc）：用于管理用户信息，包括新用户注册、用户登录、修改密码、注销等业务逻辑。\n\n  - 项目管理服务（gitrepo-svc）：用于管理开源项目信息。当用户发起搜索请求的时候，gitrepo-svc调用github的developer api，获取项目列表，并写入到数据库，然后返回项目列表给用户。当用户发起列表请求的时候，gitrepo-svc从数据库获取项目列表返回给用户。当用户查看某个项目的时候，gitrepo-svc调用review-svc，获取评论信息和项目信息返回给用户。\n\n  - 评论管理（review-svc）：用于管理评论信息，包括创建和删除评论，以及获取评论列表。\n\n## 微服务部署模式设计\n\n- 如下图所示，微服务的所有实例在kubernetes容器云中都是以多副本的形式运行，并通过service的形式对外提供服务。\n\n![](images/gitrepo-microservice.png)\n\n- 无状态：由于服务会被随机调度到任意pod，所有模块都不能使用有状态的形式实现，不能把会话信息保存在pod的运行态内存中，否则就会出现在pod1上已经登录，但是在pod2上没有登录而引起资源请求无权限的异常。所有服务必须使用无状态方式实现登录状态保存（可以使用jwt实现无状态服务）。\n\n- 服务发现：由于kubernetes自身已经有服务发现能力，所有模块无需再额外实现服务发现。\n\n- 流量治理：由于kubernetes的`istio`组件可以实现服务编排，包括熔断、超时、重试、服务跟踪、安全等流量治理能力，所有模块无需再额外实现流量治理能力。\n\n## 安装依赖\n\n```bash\n# 安装backend依赖\n$ go get -u -v github.com/jinzhu/gorm\n$ go get -u -v github.com/jinzhu/gorm/dialects/mysql\n$ go get -u -v gopkg.in/yaml.v2\n$ go get -u -v github.com/gin-gonic/gin\n$ go get -u -v github.com/dgrijalva/jwt-go\n$ go get -u -v github.com/gin-contrib/cors\n$ go get -u -v github.com/gin-contrib/static\n\n# 安装frontend依赖\n$ cd frontend-svc \u0026\u0026 npm install\n```\n\n## 配置文件\n\n- `config.yaml`是backend的配置文件，运行在容器中请修改配置\n\n- `frontend-svc/app/config.js`是frontend的配置文件，从调试环境切换到生产环境请修改配置\n\n## 版本特性\n\n- v1.x.x：支持github项目搜索列表，github项目评论\n\n- v2.x.x：支持github项目采用\n\n- v3.x.x：支持github项目关注\n\n## 运行服务\n\n```bash\n# 运行数据库\n$ docker-compose up -d\n\n# 运行backend-svc\n$ go build backend-svc/backend.go \u0026\u0026 ./backend\n\n# 运行user-svc\n$ go build user-svc/user.go \u0026\u0026 ./user\n\n# 运行gitrepo-svc\n$ go build gitrepo-svc/gitrepo.go \u0026\u0026 ./gitrepo\n\n# 运行review-svc\n$ go build review-svc/review.go \u0026\u0026 ./review\n\n# 构建frontend-svc\n$ cd frontend-svc \u0026\u0026 npm run build\n```\n\n- 访问 http://localhost:3000 可以查看应用\n\n![](images/gitrepo-login.png)\n\n- 如果本地调试前端，可以修改前端的配置文件`frontend-svc/app/config.js`为以下内容：\n\n```javascript\n// 如果要发布到正式环境，请替换为以下内容\n//export const backendUri = '';\n\n// 如果要使用npm run start，作为开发调试，请替换为以下内容\nexport const backendUri = 'http://localhost:3000';\n```\n\n- 然后使用以下命令启动frontend-svc的热加载调试\n\n```bash\n$ cd frontend-svc\n\n# 使用热加载方式启动frontend，每次修改frontend页面的内容都会自动更新前端页面\n$ npm run start\n```\n\n- 命令会自动打开 http://localhost:8080 作为前端的访问URL\n\n## 接口说明\n\n- 外部`github.com`的restfulAPI\n\n  - `github.com\b`开源项目清单的接口参见文档： https://developer.github.com/v3/search/#search-repositories\n\n  ```bash\n  https://api.github.com/search/repositories?q=kubernetes\u0026sort=stars\u0026order=desc\n  ```\n\n- `user-svc`接口设计\n\n  - 用户注册\n\n    \u003e `method`: POST\n\n    \u003e `path`: /users/\n\n    \u003e `request params`: username, password, repassword（重复输入新密码）\n\n    \u003e `request header`: N/A\n\n    \u003e `response header`: x-user-token（返回用户的登录jwt）\n\n    \u003e `response body`: error=0表示成功，否则就是失败\n\n    ```json\n    {\n      \"error\": 0,\n      \"msg\": \"create user succeed\"\n    }\n    ```\n\n  - 用户登录\n\n    \u003e `method`: POST\n\n    \u003e `path`: /users/login\n\n    \u003e `request params`: username, password\n\n    \u003e `request header`: N/A\n\n    \u003e `response header`: x-user-token（返回用户的登录jwt）\n\n    \u003e `response body`: error=0表示成功，否则就是失败\n\n    ```json\n    {\n      \"error\": 0,\n      \"msg\": \"login succeed\"\n    }\n    ```\n\n  - 用户注销\n\n    \u003e `method`: POST\n\n    \u003e `path`: /users/logout\n\n    \u003e `request params`: N/A\n\n    \u003e `request header`: x-user-token（用户的登录jwt）\n\n    \u003e `response header`: N/A\n\n    \u003e `response body`: error=0表示成功，否则就是失败\n\n    ```json\n\n    {\n      \"error\": 0,\n      \"msg\": \"logout succeed\"\n    }\n    ```\n\n  - 修改用户信息时获取用户信息\n\n    \u003e `method`: GET\n\n    \u003e `path`: /users/\n\n    \u003e `request params`: N/A\n\n    \u003e `request header`: x-user-token（用户的登录jwt）\n\n    \u003e `response header`: x-user-token（用户的登录jwt）\n\n    \u003e `response body`: error=0表示成功，否则就是失败\n\n    ```json\n    {\n      \"error\": 0,\n      \"msg\": \"get login user info succeed\"\n    }\n    ```\n\n  - 修改用户密码\n\n    \u003e `method`: PUT\n\n    \u003e `path`: /users/\n\n    \u003e `request params`: oldpassword, password, repassword\n\n    \u003e `request header`: x-user-token（用户的登录jwt）\n\n    \u003e `response header`: x-user-token（用户的登录jwt）\n\n    \u003e `response body`: error=0表示成功，否则就是失败\n\n    ```json\n    {\n      \"error\": 0,\n      \"msg\": \"update password succeed\"\n    }\n    ```\n\n- `review-svc`接口设计\n\n  - 发表gitrepo点评\n\n    \u003e `method`: POST\n\n    \u003e `path`: /reviews/\n\n    \u003e `request params`: gid（gitrepo id）, content（评论内容）\n\n    \u003e `request header`: x-user-token（用户的登录jwt）\n\n    \u003e `response header`: x-user-token（用户的登录jwt）\n\n    \u003e `response body`: error=0表示成功，否则就是失败\n\n    ```json\n    {\n      \"error\": 0,\n      \"msg\": \"new review succeed\",\n      \"rid\": 4\n    }\n    ```\n\n  - 删除gitrepo点评\n\n    \u003e `method`: DELETE\n\n    \u003e `path`: /reviews/\n\n    \u003e `request params`: rid（评论id）\n\n    \u003e `request header`: x-user-token（用户的登录jwt）\n\n    \u003e `response header`: x-user-token（用户的登录jwt）\n\n    \u003e `response body`: error=0表示成功，否则就是失败\n\n    ```json\n    {\n      \"error\": 0,\n      \"msg\": \"delete review succeed\"\n    }\n    ```\n\n  - 获取gitrepo的点评列表\n\n    \u003e `method`: GET\n\n    \u003e `path`: /reviews/:gid\n\n    \u003e `request params`: gid（gitrepo id）\n\n    \u003e `request header`: x-user-token（用户的登录jwt）\n\n    \u003e `response header`: x-user-token（用户的登录jwt）\n\n    \u003e `response body`: error=0表示成功，否则就是失败\n\n    ```json\n    {\n      \"error\": 0,\n      \"msg\": \"list reviews succeed\",\n      \"reviews\": [\n        {\n          \"content\": \"hello world\",\n          \"created_at\": \"2019-01-24T07:15:00Z\",\n          \"gid\": 51,\n          \"rid\": 1,\n          \"uid\": 1,\n          \"username\": \"cookeem\"\n        }\n      ]\n    }\n    ```\n\n  - 发表gitrepo采用 (v2.0.0特性)\n\n    \u003e `method`: POST\n\n    \u003e `path`: /reviews/adapt/\n\n    \u003e `request params`: gid（gitrepo id）\n\n    \u003e `request header`: x-user-token（用户的登录jwt）\n\n    \u003e `response header`: x-user-token（用户的登录jwt）\n\n    \u003e `response body`: error=0表示成功，否则就是失败\n\n    ```json\n    {\n      \"error\": 0,\n      \"msg\": \"new adapt succeed\",\n      \"aid\": 4\n    }\n    ```\n\n  - 发表gitrepo关注 (v3.0.0特性)\n\n    \u003e `method`: POST\n\n    \u003e `path`: /reviews/follow/\n\n    \u003e `request params`: gid（gitrepo id）\n\n    \u003e `request header`: x-user-token（用户的登录jwt）\n\n    \u003e `response header`: x-user-token（用户的登录jwt）\n\n    \u003e `response body`: error=0表示成功，否则就是失败\n\n    ```json\n    {\n      \"error\": 0,\n      \"msg\": \"new follow succeed\",\n      \"fid\": 4\n    }\n    ```\n\n- `gitrepo-svc`接口设计\n\n  - 获取gitrepo列表\n\n    \u003e `method`: PUT\n\n    \u003e `path`: /gitrepos/\n\n    \u003e `request params`: language, page（第几页）, per_page（每页项目数量）\n\n    \u003e `request header`: x-user-token（用户的登录jwt）\n\n    \u003e `response header`: x-user-token（用户的登录jwt）\n\n    \u003e `response body`: error=0表示成功，否则就是失败\n\n    ```json\n    {\n      \"error\": 0,\n      \"gitrepos\": [\n        {\n          \"gid\": 51,\n          \"full_name\": \"moby/moby\",\n          \"description\": \"Moby Project - a collaborative project for the container ecosystem to assemble container-based systems\",\n          \"language\": \"Go\",\n          \"html_url\": \"https://github.com/moby/moby\",\n          \"stargazers_count\": 51968,\n          \"watchers_count\": 51968,\n          \"forks_count\": 15071,\n          \"open_issues_count\": 3576,\n          \"reviews_count\": 1,\n          \"adapts_count\": 1,\n          \"follows_count\": 1,\n          \"created_at\": \"2013-01-18T18:10:57Z\",\n          \"updated_at\": \"2019-01-25T01:24:13Z\",\n          \"pushed_at\": \"2019-01-24T02:34:41Z\",\n          \"adapt\": 1,\n          \"follow\": 1,\n        }\n      ],\n      \"languages\": [\n        {\n          \"language\": \"Assembly\",\n          \"repos_count\": 1\n        }\n      ],\n      \"msg\": \"list gitrepos succeed\"\n    }\n    ```\n\n  - 搜索gitrepo列表\n\n    \u003e `method`: POST\n\n    \u003e `path`: /gitrepos/\n\n    \u003e `request params`: topics（关键字）, page（第几页）, per_page（每页项目数量）\n\n    \u003e `request header`: x-user-token（用户的登录jwt）\n\n    \u003e `response header`: x-user-token（用户的登录jwt）\n\n    \u003e `response body`: error=0表示成功，否则就是失败\n\n    ```json\n    {\n      \"error\": 0,\n      \"gitrepos\": [\n        {\n          \"gid\": 106,\n          \"full_name\": \"goharbor/harbor\",\n          \"description\": \"An open source trusted cloudnative registry project that stores, signs, andscans content.\",\n          \"language\": \"Go\",\n          \"html_url\": \"https://github.com/goharbor/harbor\",\n          \"stargazers_count\": 6741,\n          \"watchers_count\": 6741,\n          \"forks_count\": 1867,\n          \"open_issues_count\": 441,\n          \"reviews_count\": 0,\n          \"adapts_count\": 1,\n          \"follows_count\": 1,\n          \"created_at\": \"2016-01-28T21:10:28Z\",\n          \"updated_at\": \"2019-01-24T23:34:12Z\",\n          \"pushed_at\": \"2019-01-24T16:42:29Z\"\n        }\n      ],\n      \"languages\": [\n        {\n          \"language\": \"Assembly\",\n          \"repos_count\": 1\n        }\n      ],\n      \"msg\": \"search gitrepos succeed\"\n    }\n    ```\n\n  - 获取gitrepo详情\n\n    \u003e `method`: GET\n\n    \u003e `path`: /gitrepos/:gid\n\n    \u003e `request params`: gid\n\n    \u003e `request header`: x-user-token（用户的登录jwt）\n\n    \u003e `response header`: x-user-token（用户的登录jwt）\n\n    \u003e `response body`: error=0表示成功，否则就是失败\n\n    ```json\n    {\n      \"error\": 0,\n      \"gitrepo\": {\n        \"gid\": 51,\n        \"full_name\": \"moby/moby\",\n        \"description\": \"Moby Project - a collaborative project for the container ecosystem to assemble container-based systems\",\n        \"language\": \"Go\",\n        \"html_url\": \"https://github.com/moby/moby\",\n        \"stargazers_count\": 51968,\n        \"watchers_count\": 51968,\n        \"forks_count\": 15071,\n        \"open_issues_count\": 3576,\n        \"reviews_count\": 1,\n          \"adapts_count\": 1,\n          \"follows_count\": 1,\n        \"created_at\": \"2013-01-18T18:10:57Z\",\n        \"updated_at\": \"2019-01-25T01:24:13Z\",\n        \"pushed_at\": \"2019-01-24T02:34:41Z\"\n      },\n      \"msg\": \"get gitrepo reviews succeed\",\n      \"reviews\": [\n        {\n          \"content\": \"hello world\",\n          \"created_at\": \"2019-01-24T07:15:00Z\",\n          \"gid\": 51,\n          \"rid\": 1,\n          \"uid\": 1,\n          \"username\": \"cookeem\"\n        }\n      ]\n    }\n    ```\n\n## 数据库设计\n\n```bash\ngit_languages\n+-------------+-------------+------+-----+---------+-------+\n| Field       | Type        | Null | Key | Default | Extra |\n+-------------+-------------+------+-----+---------+-------+\n| language    | varchar(50) | NO   | PRI |         |       |\n| repos_count | int(11)     | NO   |     | 0       |       |\n+-------------+-------------+------+-----+---------+-------+\n\ngit_repos\n+-------------------+--------------+------+-----+---------+----------------+\n| Field             | Type         | Null | Key | Default | Extra          |\n+-------------------+--------------+------+-----+---------+----------------+\n| gid               | int(11)      | NO   | PRI | NULL    | auto_increment |\n| full_name         | varchar(100) | NO   | PRI |         |                |\n| description       | varchar(500) | NO   |     |         |                |\n| language          | varchar(50)  | NO   |     |         |                |\n| html_url          | varchar(200) | NO   |     |         |                |\n| stargazers_count  | int(11)      | NO   |     | 0       |                |\n| watchers_count    | int(11)      | NO   |     | 0       |                |\n| forks_count       | int(11)      | NO   |     | 0       |                |\n| open_issues_count | int(11)      | NO   |     | 0       |                |\n| reviews_count     | int(11)      | NO   |     | 0       |                |\n| adapts_count      | int(11)      | NO   |     | 0       |                |\n| follows_count     | int(11)      | NO   |     | 0       |                |\n| created_at        | timestamp    | YES  |     | NULL    |                |\n| updated_at        | timestamp    | YES  |     | NULL    |                |\n| pushed_at         | timestamp    | YES  |     | NULL    |                |\n+-------------------+--------------+------+-----+---------+----------------+\n\nreviews\n+------------+--------------+------+-----+---------+----------------+\n| Field      | Type         | Null | Key | Default | Extra          |\n+------------+--------------+------+-----+---------+----------------+\n| rid        | int(11)      | NO   | PRI | NULL    | auto_increment |\n| gid        | int(11)      | NO   |     | 0       |                |\n| uid        | int(11)      | NO   |     | 0       |                |\n| content    | varchar(500) | NO   |     |         |                |\n| created_at | timestamp    | YES  |     | NULL    |                |\n| updated_at | timestamp    | YES  |     | NULL    |                |\n+------------+--------------+------+-----+---------+----------------+\n\nusers\n+------------+-------------+------+-----+---------+----------------+\n| Field      | Type        | Null | Key | Default | Extra          |\n+------------+-------------+------+-----+---------+----------------+\n| uid        | int(11)     | NO   | PRI | NULL    | auto_increment |\n| username   | varchar(12) | NO   | UNI |         |                |\n| password   | varchar(50) | NO   |     |         |                |\n| created_at | timestamp   | YES  |     | NULL    |                |\n| updated_at | timestamp   | YES  |     | NULL    |                |\n+------------+-------------+------+-----+---------+----------------+\n\nadapts (v2.0.0特性)\n+------------+-----------+------+-----+---------+----------------+\n| Field      | Type      | Null | Key | Default | Extra          |\n+------------+-----------+------+-----+---------+----------------+\n| aid        | int(11)   | NO   | PRI | NULL    | auto_increment |\n| gid        | int(11)   | NO   |     | 0       |                |\n| uid        | int(11)   | NO   |     | 0       |                |\n| created_at | timestamp | YES  |     | NULL    |                |\n| updated_at | timestamp | YES  |     | NULL    |                |\n+------------+-----------+------+-----+---------+----------------+\n\nfollows (v3.0.0特性)\n+------------+-----------+------+-----+---------+----------------+\n| Field      | Type      | Null | Key | Default | Extra          |\n+------------+-----------+------+-----+---------+----------------+\n| fid        | int(11)   | NO   | PRI | NULL    | auto_increment |\n| gid        | int(11)   | NO   |     | 0       |                |\n| uid        | int(11)   | NO   |     | 0       |                |\n| created_at | timestamp | YES  |     | NULL    |                |\n| updated_at | timestamp | YES  |     | NULL    |                |\n+------------+-----------+------+-----+---------+----------------+\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcookeem%2Fgohub-trending","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcookeem%2Fgohub-trending","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcookeem%2Fgohub-trending/lists"}