{"id":15192162,"url":"https://github.com/cage1016/gokit-todo","last_synced_at":"2026-03-05T07:32:24.650Z","repository":{"id":42715476,"uuid":"321618609","full_name":"cage1016/gokit-todo","owner":"cage1016","description":"todomvc full stack demo project. react + backend API by gokit microservice toolkit. include unit test, integration test, e2e test, github action ci ","archived":false,"fork":false,"pushed_at":"2022-03-28T13:49:06.000Z","size":25261,"stargazers_count":16,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-06T15:11:23.669Z","etag":null,"topics":["ci","codecov","docker-compose","e2e-tests","github-actions","go-kit","godev","gokit","gomock","integration-testing","istio","kubernetes","microservice","todomvc","unittest"],"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/cage1016.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2020-12-15T09:33:12.000Z","updated_at":"2023-07-09T13:03:57.000Z","dependencies_parsed_at":"2022-08-26T07:00:58.594Z","dependency_job_id":null,"html_url":"https://github.com/cage1016/gokit-todo","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/cage1016/gokit-todo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cage1016%2Fgokit-todo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cage1016%2Fgokit-todo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cage1016%2Fgokit-todo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cage1016%2Fgokit-todo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cage1016","download_url":"https://codeload.github.com/cage1016/gokit-todo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cage1016%2Fgokit-todo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30114254,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T03:40:26.266Z","status":"ssl_error","status_checked_at":"2026-03-05T03:39:15.902Z","response_time":93,"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":["ci","codecov","docker-compose","e2e-tests","github-actions","go-kit","godev","gokit","gomock","integration-testing","istio","kubernetes","microservice","todomvc","unittest"],"created_at":"2024-09-27T21:05:50.904Z","updated_at":"2026-03-05T07:32:24.628Z","avatar_url":"https://github.com/cage1016.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gokit-todo\n\n![GitHub Workflow Status](https://github.com/cage1016/gokit-todo/workflows/ci/badge.svg)\n[![\"GitHub Discussions\"](https://img.shields.io/badge/%20GitHub-%20Discussions-gray.svg?longCache=true\u0026logo=github\u0026colorB=purple)](https://github.com/cage1016/gokit-todo/discussions)\n[![GoDev](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go\u0026logoColor=white\u0026style=flat-square)](https://pkg.go.dev/github.com/cage1016/gokit-todo)\n[![codecov](https://codecov.io/gh/cage1016/gokit-todo/branch/master/graph/badge.svg)](https://codecov.io/gh/cage1016/gokit-todo)\n[![Go Report Card](https://goreportcard.com/badge/cage1016/gokit-todo)](https://goreportcard.com/report/cage1016/gokit-todo)\n[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)\n\n| Service  | Description           |\n| -------- | --------------------- |\n| todo     | todoMVC backend API   |\n| [gokit-todo-frontend](https://github.com/cage1016/gokit-todo-frontend)| todoMVC client        |\n\n![gokit-todo](demo.gif)\n\n## Features\n\n- **[Kubernetes](https://kubernetes.io)/[GKE](https://cloud.google.com/kubernetes-engine/):**\n  The app is designed to run on Kubernetes (both locally on \"Docker for\n  Desktop\", as well as on the cloud with GKE).\n- **[gRPC](https://grpc.io):** Microservices use a high volume of gRPC calls to\n  communicate to each other.\n- **[Istio](https://istio.io):** Application works on Istio service mesh.\n- **[Skaffold](https://skaffold.dev):** Application\n  is deployed to Kubernetes with a single command using Skaffold.\n- **[go-kit/kit](https://github.com/go-kit/kit):** Go kit is a programming toolkit for building microservices (or elegant monoliths) in Go. We solve common problems in distributed systems and application architecture so you can focus on delivering business value.\n- **[todomvc](https://github.com/tastejs/todomvc):** Helping you select an MV* framework\n\n## Motivation\n\nI use [go-kit/kit](https://github.com/go-kit/kit)(microservices toolkit) to build business project and run on Kubernetes and Istio. I also to give few talks about How i use gokit\n - [GoPherCon 2020 TW: 如何透過 Go-kit 快速搭建微服務架構應用程式實戰 ｜ KaiChu](https://kaichu.io/posts/gokit-engineering-operation/)\n - [GDG Cloud Taipei meetup #50 - Build go kit microservices at kubernete…](https://www2.slideshare.net/cagechung/gdg-cloud-taipei-meetup-50-build-go-kit-microservices-at-kubernetes-with-ease-206252668)\n- [GDG Devfest 2019 - Build go kit microservices at kubernetes with ease](https://www2.slideshare.net/cagechung/gdg-devfest-2019-build-go-kit-microservices-at-kubernetes-with-ease)\n- [cage1016/gokit-workshop](https://github.com/cage1016/gokit-workshop)\n\nGo kit microservices toolkit include many microservices components itself (auth, circuitbreaker, ratelimit etcs.). We build microservices application and deploy to Kubernetes. We could drop those microservices components out with Service Mesh soluation (Istion Envoy proxy) and keep single microservice core business logic clear without any infra codes.\n\nThis demo project is [todomvc/gokit-todo-frontend](https://github.com/cage1016/gokit-todo-frontend) backend API implemented by gokit microservice tookit with best practice by myself.\n\n## Goals\n- **Project**: quick start a new microservice by toolchain [cage1016/gk](https://github.com/cage1016/gk/tree/feature/gokitconsulk8sistio). Team member could follow same guideline to develop microservice quickly.\n  - project layout\n- **Testing**: how to write `unit` test with table test `go-sqlmock` and `gomock`. `integration` test, `e2e` test with `TestMain` and `docker-compose`\n- **DevOps**: setup CI/CD workflow to increase devops lifecycle\n  - skaffold\n  - github action (CI)\n  - Kubernetes\n  - Istio\n## Install\n\nthis demo support `docker-compose` or `nginx-ingress` and `istio`\n\n### Docker-Compose\n\n1. Run todomvc frontend \u0026 gokit-todo backend API with docker-compose\n    ```sh\n    docker-compose -f docker-compose.full.yaml up -d\n    ```\n2. Visit http://localhost:8080 for demo\n3. Clean docker-compose\n    ```sh\n    docker-compose -f docker-compose.full.yaml down --volume\n    ```\n### k8s + Istio \n\n1. Prepare a Kubernetes cluster\n2. Install Istio (**1.6.11**)\n    ```sh\n    istioctl install\n    kubectl label namespace default istio-injection=enabled\n    ```\n3. Install `gokit-todo` \u0026 `frontend`\n    ```sh\n    kubectl apply -f https://raw.githubusercontent.com/cage1016/gokit-todo/master/deployments/k8s-istio.yaml\n    ```\n4. Set up `GATEWAY_HTTP_URL`\n    ```sh\n    export INGRESS_HTTP_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name==\"http2\")].port}')\n    export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')\n    export GATEWAY_HTTP_URL=$INGRESS_HOST:$INGRESS_HTTP_PORT\n    echo $GATEWAY_HTTP_URL\n    ```\n5. Visit `$GATEWAY_HTTP_URL` to access todomvc with gokit-todo backend API\n6. Delete `gokit-todo` \u0026 `frontend`\n    ```sh\n    kubectl delete -f https://raw.githubusercontent.com/cage1016/gokit-todo/master/deployments/k8s-istio.yaml\n    ```\n7. Uninstall Istio\n    ```sh\n    istioctl manifest generate | kubectl delete -f -\n    kubectl delete namespace istio-system\n    kubectl label namespace default istio-injection=enabled --overwrite\n    ```\n\n### k8s + nginx-ingress\n\n1. Prepare a Kubernetes cluster\n2. Install `nginx-ingress` CRD by helm3\n    ```sh\n    helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx\n    helm repo update\n    helm install ingress-nginx ingress-nginx/ingress-nginx\n    ```\n3. Install `gokit-todo` \u0026 `frontend`\n    ```sh\n    kubectl apply -f https://raw.githubusercontent.com/cage1016/gokit-todo/master/deployments/k8s-nginx-ingress.yaml\n    ```\n4. Set up `INGRESS_HTTP_URL`\n    ```sh\n    export INGRESS_HTTP_PORT=$(kubectl get ingress frontend-ingress -o jsonpath='{.spec.rules.*.http.paths.*.backend.servicePort}')\n    export INGRESS_HOST=$(kubectl get ingress frontend-ingress -o jsonpath='{.status.loadBalancer.ingress.*.hostname}')\n    export INGRESS_HTTP_URL=$INGRESS_HOST:$INGRESS_HTTP_PORT\n    echo $INGRESS_HTTP_URL\n    ```\n5. Visit `$INGRESS_HTTP_URL` to access todomvc with gokit-todo backend API\n6. Delete `gokit-todo` \u0026 `frontend`\n    ```sh\n    kubectl delete -f https://raw.githubusercontent.com/cage1016/gokit-todo/master/deployments/k8s-nginx-ingress.yaml\n    ```\n7. Uninstall nginx ingress\n    ```sh\n    helm uninstall ingress-nginx\n    ```  \n\n## Testing\n\n1. `Makefile`\n    ```sh\n    $ make\n      down                           docker-compose down\n      generate                       Regenerates GRPC proto and gomock\n      help                           this help\n      mod                            tidy go mod\n      run                            docker-compose stop \u0026 up\n      stop                           docker-compose stop\n      test                           test: run unit test\n      test-e2e                       test-e2e: run e2e test\n      test-integration               test-integration: run integration test\n      up                             docker-compose up\n    ```\n2. unit test\n    ```sh\n    make test\n    ```\n3. unit integration test by docker-compose\n    ```sh\n    make test-integration\n    ```\n4. unit e2e test by docker-compose\n    ```sh\n    make test-e2e\n    ```\n## License\n\nCopyright © 2020 [kaichu.io](https://kaichu.io/).\u003cbr /\u003e\nThis project is [MIT](https://github.com/cage1016/gokit-todo/blob/master/LICENSE) licensed.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcage1016%2Fgokit-todo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcage1016%2Fgokit-todo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcage1016%2Fgokit-todo/lists"}