├── showcases
├── mq
│ └── .gitkeep
├── go-boot
│ ├── doc.go
│ ├── README.md
│ ├── go.mod
│ ├── version.go
│ ├── middleware.go
│ ├── utils
│ │ ├── encrypt
│ │ │ ├── md5.go
│ │ │ ├── aes_test.go
│ │ │ └── aes.go
│ │ ├── codec
│ │ │ ├── json.go
│ │ │ ├── xml.go
│ │ │ ├── protobuf.go
│ │ │ ├── codec.go
│ │ │ └── string.go
│ │ └── convert
│ │ │ └── convert_test.go
│ ├── error.go
│ ├── config.go
│ ├── .gitignore
│ ├── plugins
│ │ ├── debug.go
│ │ └── cryption.go
│ ├── hook.go
│ ├── retry.go
│ ├── cmd
│ │ ├── server.go
│ │ ├── server_test.go
│ │ └── callback.go
│ ├── session
│ │ └── session.go
│ ├── packet.go
│ ├── server.go
│ └── router.go
├── minitask
│ ├── input
│ │ └── .gitignore
│ ├── logs
│ │ └── .gitignore
│ ├── output
│ │ └── .gitignore
│ ├── .DS_Store
│ ├── src
│ │ ├── .DS_Store
│ │ ├── logger
│ │ │ └── logger.go
│ │ ├── httpbuilder
│ │ │ └── httpbuilder.go
│ │ ├── executer
│ │ │ └── executer.go
│ │ └── commandrunner
│ │ │ └── commandrunner.go
│ ├── compile.sh
│ └── LICENSE
├── 2024~simplebank
│ ├── .gitignore
│ ├── db
│ │ ├── migration
│ │ │ ├── 000003_add_sessions.down.sql
│ │ │ ├── 000005_add_role_to_users.down.sql
│ │ │ ├── 000005_add_role_to_users.up.sql
│ │ │ ├── 000001_init_schema.down.sql
│ │ │ ├── 000004_add_verify_emails.down.sql
│ │ │ ├── 000002_add_users.down.sql
│ │ │ ├── 000003_add_sessions.up.sql
│ │ │ ├── 000004_add_verify_emails.up.sql
│ │ │ ├── 000002_add_users.up.sql
│ │ │ └── 000001_init_schema.up.sql
│ │ ├── query
│ │ │ ├── session.sql
│ │ │ ├── entry.sql
│ │ │ ├── verify_email.sql
│ │ │ ├── transfer.sql
│ │ │ ├── user.sql
│ │ │ └── account.sql
│ │ └── sqlc
│ │ │ ├── error.go
│ │ │ ├── exec_tx.go
│ │ │ ├── main_test.go
│ │ │ ├── tx_create_user.go
│ │ │ ├── db.go
│ │ │ ├── store.go
│ │ │ └── tx_verify_email.go
│ ├── start.sh
│ ├── util
│ │ ├── role.go
│ │ ├── currency.go
│ │ ├── password.go
│ │ ├── password_test.go
│ │ ├── random.go
│ │ └── config.go
│ ├── backend-master.png
│ ├── doc
│ │ └── swagger
│ │ │ ├── favicon-16x16.png
│ │ │ ├── favicon-32x32.png
│ │ │ ├── index.css
│ │ │ ├── swagger-initializer.js
│ │ │ └── index.html
│ ├── eks
│ │ ├── ingress-nginx.yaml
│ │ ├── install.sh
│ │ ├── aws-auth.yaml
│ │ ├── service.yaml
│ │ ├── issuer.yaml
│ │ ├── ingress-http.yaml
│ │ ├── deployment.yaml
│ │ └── ingress-grpc.yaml
│ ├── proto
│ │ ├── rpc_verify_email.proto
│ │ ├── rpc_create_user.proto
│ │ ├── user.proto
│ │ ├── rpc_update_user.proto
│ │ ├── rpc_login_user.proto
│ │ └── google
│ │ │ └── api
│ │ │ └── annotations.proto
│ ├── api
│ │ ├── validator.go
│ │ ├── main_test.go
│ │ └── middleware.go
│ ├── Dockerfile
│ ├── token
│ │ ├── maker.go
│ │ ├── payload.go
│ │ ├── paseto_maker_test.go
│ │ └── paseto_maker.go
│ ├── sqlc.yaml
│ ├── app.env
│ ├── gapi
│ │ ├── converter.go
│ │ ├── error.go
│ │ ├── metadata.go
│ │ ├── server.go
│ │ ├── main_test.go
│ │ ├── rpc_verify_email.go
│ │ └── authorization.go
│ ├── worker
│ │ ├── distributor.go
│ │ └── logger.go
│ ├── mail
│ │ ├── sender_test.go
│ │ └── sender.go
│ ├── docker-compose.yaml
│ ├── LICENSE
│ ├── .github
│ │ └── workflows
│ │ │ └── test.yml
│ └── val
│ │ └── validator.go
├── .DS_Store
├── gorm.db
├── db
│ ├── .DS_Store
│ ├── redis
│ │ ├── .DS_Store
│ │ ├── sessions
│ │ │ ├── sessions.go
│ │ │ ├── memory.go
│ │ │ ├── middleware.go
│ │ │ └── redis.go
│ │ ├── example
│ │ │ └── main.go
│ │ ├── logger
│ │ │ └── logger.go
│ │ ├── config.go
│ │ ├── exec_test.go
│ │ ├── sort_test.go
│ │ ├── config_test.go
│ │ ├── exec.go
│ │ ├── sort.go
│ │ └── cmd
│ │ │ ├── qclient
│ │ │ └── main.go
│ │ │ ├── pserver
│ │ │ └── main.go
│ │ │ ├── qserver
│ │ │ └── main.go
│ │ │ ├── pclient
│ │ │ └── main.go
│ │ │ └── server
│ │ │ └── main.go
│ ├── dbinterface
│ │ ├── mockgen.sh
│ │ ├── exec.go
│ │ ├── create.go
│ │ ├── transaction.go
│ │ ├── example
│ │ │ └── main.go
│ │ ├── query.go
│ │ ├── create_test.go
│ │ ├── query_test.go
│ │ └── exec_test.go
│ ├── mongodb
│ │ ├── example
│ │ │ └── main.go
│ │ ├── config.go
│ │ ├── exec_test.go
│ │ ├── config_test.go
│ │ └── exec.go
│ ├── storage
│ │ ├── example
│ │ │ └── main.go
│ │ ├── storage.go
│ │ ├── mongoconfig.go
│ │ ├── mongointerface.go
│ │ └── exec.go
│ ├── pools
│ │ ├── example
│ │ │ └── main.go
│ │ ├── timeout.go
│ │ ├── pools.go
│ │ ├── timeout_test.go
│ │ └── pools_test.go
│ ├── database
│ │ ├── example
│ │ │ └── main.go
│ │ ├── exec.go
│ │ ├── create.go
│ │ ├── config.go
│ │ ├── config_test.go
│ │ ├── query.go
│ │ ├── query_test.go
│ │ ├── create_test.go
│ │ └── exec_test.go
│ └── firebase
│ │ ├── auth_test.go
│ │ ├── example
│ │ └── main.go
│ │ ├── client.go
│ │ ├── auth.go
│ │ └── client_test.go
├── gloc
│ ├── .DS_Store
│ ├── Gopkg.toml
│ ├── bspool.go
│ ├── Makefile
│ ├── option.go
│ ├── examples
│ │ ├── files.go
│ │ └── languages.go
│ ├── utils_test.go
│ └── xml.go
├── go-http-proxy-cli
│ ├── .DS_Store
│ ├── go.mod
│ ├── model
│ │ ├── file_type.go
│ │ └── file.go
│ ├── client
│ │ └── bp_client.go
│ └── cli
│ │ └── main.go
├── golang-gin-realworld-example-app
│ ├── logo.png
│ ├── scripts
│ │ ├── gofmt.sh
│ │ └── coverage.sh
│ ├── doc.go
│ ├── users
│ │ ├── doc.go
│ │ └── serializers.go
│ ├── articles
│ │ └── doc.go
│ ├── BACKEND_INSTRUCTIONS.md
│ ├── .gitignore
│ ├── .travis.yml
│ ├── MOBILE_INSTRUCTIONS.md
│ ├── LICENSE
│ ├── common
│ │ └── database.go
│ └── go.mod
└── minimal-server
│ └── main.go
├── boilerplates
├── standards-layout
│ ├── api
│ │ ├── .keep
│ │ └── README.md
│ ├── assets
│ │ ├── .keep
│ │ └── README.md
│ ├── configs
│ │ ├── .keep
│ │ └── README.md
│ ├── docs
│ │ ├── .keep
│ │ └── README.md
│ ├── init
│ │ ├── .keep
│ │ └── README.md
│ ├── scripts
│ │ ├── .keep
│ │ └── README.md
│ ├── test
│ │ ├── .keep
│ │ └── README.md
│ ├── tools
│ │ ├── .keep
│ │ └── README.md
│ ├── vendor
│ │ ├── .keep
│ │ └── README.md
│ ├── web
│ │ ├── app
│ │ │ └── .keep
│ │ ├── static
│ │ │ └── .keep
│ │ ├── template
│ │ │ └── .keep
│ │ └── README.md
│ ├── deployments
│ │ ├── .keep
│ │ └── README.md
│ ├── examples
│ │ ├── .keep
│ │ └── README.md
│ ├── githooks
│ │ ├── .keep
│ │ └── README.md
│ ├── third_party
│ │ ├── .keep
│ │ └── README.md
│ ├── cmd
│ │ ├── _your_app_
│ │ │ └── .keep
│ │ └── README.md
│ ├── pkg
│ │ └── _your_public_lib_
│ │ │ └── .keep
│ ├── internal
│ │ ├── app
│ │ │ └── _your_app_
│ │ │ │ └── .keep
│ │ ├── pkg
│ │ │ └── _your_private_lib_
│ │ │ │ └── .keep
│ │ └── README.md
│ ├── Makefile
│ ├── website
│ │ └── README.md
│ └── .gitignore
├── go-backend-clean-architecture
│ ├── internal
│ │ └── fakeutil
│ │ │ └── fakeutil.go
│ ├── .gitignore
│ ├── domain
│ │ ├── error_response.go
│ │ ├── success_response.go
│ │ ├── profile.go
│ │ ├── jwt_custom.go
│ │ ├── login.go
│ │ ├── user.go
│ │ ├── refresh_token.go
│ │ ├── task.go
│ │ ├── signup.go
│ │ └── mocks
│ │ │ └── ProfileUsecase.go
│ ├── assets
│ │ ├── button-view-api-docs.png
│ │ ├── go-backend-arch-diagram.png
│ │ ├── go-backend-clean-architecture.png
│ │ ├── go-arch-private-api-request-flow.png
│ │ └── go-arch-public-api-request-flow.png
│ ├── Dockerfile
│ ├── .env.example
│ ├── bootstrap
│ │ ├── app.go
│ │ ├── database.go
│ │ └── env.go
│ ├── api
│ │ ├── controller
│ │ │ ├── profile_controller.go
│ │ │ └── task_controller.go
│ │ ├── route
│ │ │ └── v1
│ │ │ │ ├── profile_route.go
│ │ │ │ ├── login_route.go
│ │ │ │ ├── task_route.go
│ │ │ │ ├── signup_route.go
│ │ │ │ ├── refresh_token_route.go
│ │ │ │ └── route.go
│ │ └── middleware
│ │ │ └── jwt_auth_middleware.go
│ ├── cmd
│ │ └── main.go
│ ├── docker-compose.yaml
│ ├── usecase
│ │ ├── profile_usecase.go
│ │ ├── task_usecase.go
│ │ ├── login_usecase.go
│ │ ├── signup_usecase.go
│ │ └── refresh_token_usecase.go
│ ├── mongo
│ │ └── mocks
│ │ │ ├── SingleResult.go
│ │ │ └── Database.go
│ └── repository
│ │ └── task_repository.go
├── .DS_Store
└── go-clean-architecture
│ ├── .DS_Store
│ ├── api
│ ├── .DS_Store
│ └── middleware
│ │ ├── cors.go
│ │ └── auth.go
│ ├── pkg
│ ├── .DS_Store
│ ├── user
│ │ ├── entity.go
│ │ └── repository.go
│ ├── admin
│ │ ├── entity.go
│ │ └── repository.go
│ └── errors.go
│ ├── README.md
│ ├── Makefile
│ ├── .gitignore
│ ├── .air.conf
│ ├── docker-compose.yml
│ ├── config.json
│ └── go.mod
├── .DS_Store
└── LICENSE
/showcases/mq/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/api/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/assets/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/configs/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/docs/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/init/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/scripts/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/test/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/tools/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/vendor/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/web/app/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/deployments/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/examples/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/githooks/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/third_party/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/web/static/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/web/template/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/showcases/go-boot/doc.go:
--------------------------------------------------------------------------------
1 | package go_boot
2 |
--------------------------------------------------------------------------------
/showcases/minitask/input/.gitignore:
--------------------------------------------------------------------------------
1 | *.txt
2 |
--------------------------------------------------------------------------------
/showcases/minitask/logs/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 |
--------------------------------------------------------------------------------
/showcases/minitask/output/.gitignore:
--------------------------------------------------------------------------------
1 | *.txt
2 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/cmd/_your_app_/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/pkg/_your_public_lib_/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | .vscode
3 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/internal/app/_your_app_/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/internal/pkg/_your_private_lib_/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/Makefile:
--------------------------------------------------------------------------------
1 | # note: call scripts from /scripts
--------------------------------------------------------------------------------
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/.DS_Store
--------------------------------------------------------------------------------
/boilerplates/standards-layout/githooks/README.md:
--------------------------------------------------------------------------------
1 | # `/githooks`
2 |
3 | Git hooks.
4 |
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/internal/fakeutil/fakeutil.go:
--------------------------------------------------------------------------------
1 | package fakeutil
2 |
--------------------------------------------------------------------------------
/showcases/go-boot/README.md:
--------------------------------------------------------------------------------
1 | # go-boot
2 |
3 | go-boot 是从零实现的 TCP/UDP/HTTP/WebSocket 服务器。
4 |
--------------------------------------------------------------------------------
/showcases/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/showcases/.DS_Store
--------------------------------------------------------------------------------
/showcases/gorm.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/showcases/gorm.db
--------------------------------------------------------------------------------
/boilerplates/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/boilerplates/.DS_Store
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/migration/000003_add_sessions.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS "sessions";
2 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -e
4 |
5 | echo "start the app"
6 | exec "$@"
7 |
--------------------------------------------------------------------------------
/showcases/db/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/showcases/db/.DS_Store
--------------------------------------------------------------------------------
/showcases/gloc/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/showcases/gloc/.DS_Store
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | bin/
3 | /.idea
4 | .idea
5 | .env
6 | .vscode
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/migration/000005_add_role_to_users.down.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "users" DROP COLUMN "role";
2 |
--------------------------------------------------------------------------------
/showcases/db/redis/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/showcases/db/redis/.DS_Store
--------------------------------------------------------------------------------
/showcases/minitask/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/showcases/minitask/.DS_Store
--------------------------------------------------------------------------------
/showcases/minitask/src/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/showcases/minitask/src/.DS_Store
--------------------------------------------------------------------------------
/showcases/go-http-proxy-cli/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/showcases/go-http-proxy-cli/.DS_Store
--------------------------------------------------------------------------------
/boilerplates/standards-layout/assets/README.md:
--------------------------------------------------------------------------------
1 | # `/assets`
2 |
3 | Other assets to go along with your repository (images, logos, etc).
4 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/util/role.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | const (
4 | DepositorRole = "depositor"
5 | BankerRole = "banker"
6 | )
7 |
--------------------------------------------------------------------------------
/boilerplates/go-clean-architecture/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/boilerplates/go-clean-architecture/.DS_Store
--------------------------------------------------------------------------------
/showcases/2024~simplebank/backend-master.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/showcases/2024~simplebank/backend-master.png
--------------------------------------------------------------------------------
/boilerplates/standards-layout/web/README.md:
--------------------------------------------------------------------------------
1 | # `/web`
2 |
3 | Web application specific components: static web assets, server side templates and SPAs.
4 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/migration/000005_add_role_to_users.up.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "users" ADD COLUMN "role" varchar NOT NULL DEFAULT 'depositor';
2 |
--------------------------------------------------------------------------------
/boilerplates/go-clean-architecture/api/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/boilerplates/go-clean-architecture/api/.DS_Store
--------------------------------------------------------------------------------
/boilerplates/go-clean-architecture/pkg/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/boilerplates/go-clean-architecture/pkg/.DS_Store
--------------------------------------------------------------------------------
/showcases/golang-gin-realworld-example-app/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/showcases/golang-gin-realworld-example-app/logo.png
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/domain/error_response.go:
--------------------------------------------------------------------------------
1 | package domain
2 |
3 | type ErrorResponse struct {
4 | Message string `json:"message"`
5 | }
6 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/init/README.md:
--------------------------------------------------------------------------------
1 | # `/init`
2 |
3 | System init (systemd, upstart, sysv) and process manager/supervisor (runit, supervisord) configs.
4 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/third_party/README.md:
--------------------------------------------------------------------------------
1 | # `/third_party`
2 |
3 | External helper tools, forked code and other 3rd party utilities (e.g., Swagger UI).
4 |
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/domain/success_response.go:
--------------------------------------------------------------------------------
1 | package domain
2 |
3 | type SuccessResponse struct {
4 | Message string `json:"message"`
5 | }
6 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/migration/000001_init_schema.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS entries;
2 | DROP TABLE IF EXISTS transfers;
3 | DROP TABLE IF EXISTS accounts;
4 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/doc/swagger/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/showcases/2024~simplebank/doc/swagger/favicon-16x16.png
--------------------------------------------------------------------------------
/showcases/2024~simplebank/doc/swagger/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/showcases/2024~simplebank/doc/swagger/favicon-32x32.png
--------------------------------------------------------------------------------
/boilerplates/go-clean-architecture/README.md:
--------------------------------------------------------------------------------
1 | # Clean Architecture Sample
2 | Reference code for my article on [Clean Architecture, the right way](https://bit.ly/CleanArch).
3 |
--------------------------------------------------------------------------------
/boilerplates/go-clean-architecture/Makefile:
--------------------------------------------------------------------------------
1 | .Phony: begin
2 | begin:
3 | @~/.air -d -c .air.conf
4 |
5 | .phony: build
6 | build:
7 | CGOENABLED=0 go build -o bin/main api/main.go
8 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/migration/000004_add_verify_emails.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS "verify_emails" CASCADE;
2 |
3 | ALTER TABLE "users" DROP COLUMN "is_email_verified";
4 |
--------------------------------------------------------------------------------
/showcases/db/dbinterface/mockgen.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | mockgen -destination mocks_test.go -package dbinterface github.com/agtorre/go-cookbook/chapter5/dbinterface DB,Transaction
3 |
--------------------------------------------------------------------------------
/showcases/go-boot/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/wxyyxc1992/go-boot
2 |
3 | require (
4 | github.com/golang/protobuf v1.3.0
5 | github.com/gorilla/websocket v1.4.0
6 | )
7 |
8 | go 1.13
9 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/configs/README.md:
--------------------------------------------------------------------------------
1 | # `/configs`
2 |
3 | Configuration file templates or default configs.
4 |
5 | Put your `confd` or `consule-template` template files here.
6 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/eks/ingress-nginx.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: networking.k8s.io/v1
2 | kind: IngressClass
3 | metadata:
4 | name: nginx
5 | spec:
6 | controller: k8s.io/ingress-nginx
7 |
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/assets/button-view-api-docs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/boilerplates/go-backend-clean-architecture/assets/button-view-api-docs.png
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/assets/go-backend-arch-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/boilerplates/go-backend-clean-architecture/assets/go-backend-arch-diagram.png
--------------------------------------------------------------------------------
/showcases/go-http-proxy-cli/go.mod:
--------------------------------------------------------------------------------
1 | module dev.wx
2 |
3 | go 1.13
4 |
5 | require (
6 | github.com/imroc/req v0.2.4
7 | github.com/json-iterator/go v1.1.8
8 | github.com/urfave/cli/v2 v2.0.0
9 | )
10 |
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.19-alpine
2 |
3 | RUN mkdir /app
4 |
5 | ADD . /app
6 |
7 | WORKDIR /app
8 |
9 | RUN go build -o main cmd/main.go
10 |
11 | CMD ["/app/main"]
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/assets/go-backend-clean-architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/boilerplates/go-backend-clean-architecture/assets/go-backend-clean-architecture.png
--------------------------------------------------------------------------------
/boilerplates/standards-layout/deployments/README.md:
--------------------------------------------------------------------------------
1 | # `/deployments`
2 |
3 | IaaS, PaaS, system and container orchestration deployment configurations and templates (docker-compose, kubernetes/helm, mesos, terraform, bosh).
4 |
--------------------------------------------------------------------------------
/showcases/db/mongodb/example/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "github.com/agtorre/go-solutions/section5/mongodb"
4 |
5 | func main() {
6 | if err := mongodb.Exec(); err != nil {
7 | panic(err)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/showcases/db/storage/example/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "github.com/agtorre/go-solutions/section5/storage"
4 |
5 | func main() {
6 | if err := storage.Exec(); err != nil {
7 | panic(err)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/assets/go-arch-private-api-request-flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/boilerplates/go-backend-clean-architecture/assets/go-arch-private-api-request-flow.png
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/assets/go-arch-public-api-request-flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wx-chevalier/go-examples/main/boilerplates/go-backend-clean-architecture/assets/go-arch-public-api-request-flow.png
--------------------------------------------------------------------------------
/showcases/db/pools/example/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "github.com/agtorre/go-solutions/section5/pools"
4 |
5 | func main() {
6 | if err := pools.ExecWithTimeout(); err != nil {
7 | panic(err)
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/showcases/go-boot/version.go:
--------------------------------------------------------------------------------
1 | package go_boot
2 |
3 | const (
4 | // Version current Linker version
5 | Version = "1.0.0"
6 |
7 | // MinimumGoVersion minimum required Go version for Linker
8 | MinimumGoVersion = ">=1.9"
9 | )
10 |
--------------------------------------------------------------------------------
/showcases/db/redis/sessions/sessions.go:
--------------------------------------------------------------------------------
1 | package sessions
2 |
3 | type Session struct {
4 | VisitCount int `json:"visitCount"`
5 | }
6 |
7 | type Store interface {
8 | Get(string) (Session, error)
9 | Set(string, Session) error
10 | }
11 |
--------------------------------------------------------------------------------
/boilerplates/go-clean-architecture/api/middleware/cors.go:
--------------------------------------------------------------------------------
1 | package middleware
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/rs/cors"
7 | )
8 |
9 | func CorsEveryWhere(mux http.Handler) http.Handler {
10 | return cors.Default().Handler(mux)
11 | }
12 |
--------------------------------------------------------------------------------
/showcases/db/mongodb/config.go:
--------------------------------------------------------------------------------
1 | package mongodb
2 |
3 | import mgo "gopkg.in/mgo.v2"
4 |
5 | func Setup() (*mgo.Session, error) {
6 | session, err := mgo.Dial("localhost")
7 | if err != nil {
8 | return nil, err
9 | }
10 | return session, nil
11 | }
12 |
--------------------------------------------------------------------------------
/showcases/gloc/Gopkg.toml:
--------------------------------------------------------------------------------
1 | [[constraint]]
2 | name = "github.com/jessevdk/go-flags"
3 | version = "1.4.0"
4 |
5 | [[constraint]]
6 | name = "gopkg.in/src-d/enry.v1"
7 | version = "1.6.3"
8 |
9 | [prune]
10 | go-tests = true
11 | unused-packages = true
12 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/api/README.md:
--------------------------------------------------------------------------------
1 | # `/api`
2 |
3 | OpenAPI/Swagger specs, JSON schema files, protocol definition files.
4 |
5 | Examples:
6 |
7 | * https://github.com/kubernetes/kubernetes/tree/master/api
8 | * https://github.com/openshift/origin/tree/master/api
9 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/migration/000002_add_users.down.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE IF EXISTS "accounts" DROP CONSTRAINT IF EXISTS "owner_currency_key";
2 |
3 | ALTER TABLE IF EXISTS "accounts" DROP CONSTRAINT IF EXISTS "accounts_owner_fkey";
4 |
5 | DROP TABLE IF EXISTS "users";
6 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/docs/README.md:
--------------------------------------------------------------------------------
1 | # `/docs`
2 |
3 | Design and user documents (in addition to your godoc generated documentation).
4 |
5 | Examples:
6 |
7 | * https://github.com/gohugoio/hugo/tree/master/docs
8 | * https://github.com/openshift/origin/tree/master/docs
9 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/eks/install.sh:
--------------------------------------------------------------------------------
1 | kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/aws/deploy.yaml
2 | kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.1/cert-manager.yaml
3 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/vendor/README.md:
--------------------------------------------------------------------------------
1 | # `/vendor`
2 |
3 | Application dependencies (managed manually or by your favorite dependency management tool like [`dep`](https://github.com/golang/dep)).
4 |
5 | Don't commit your application dependencies if you are building a library.
6 |
--------------------------------------------------------------------------------
/showcases/db/redis/example/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "github.com/agtorre/go-solutions/section5/redis"
4 |
5 | func main() {
6 | if err := redis.Exec(); err != nil {
7 | panic(err)
8 | }
9 |
10 | if err := redis.Sort(); err != nil {
11 | panic(err)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/showcases/db/storage/storage.go:
--------------------------------------------------------------------------------
1 | package storage
2 |
3 | import "context"
4 |
5 | type Item struct {
6 | Name string
7 | Price int64
8 | }
9 |
10 | type Storage interface {
11 | GetByName(context.Context, string) (*Item, error)
12 | Put(context.Context, *Item) error
13 | }
14 |
--------------------------------------------------------------------------------
/showcases/go-boot/middleware.go:
--------------------------------------------------------------------------------
1 | package go_boot
2 |
3 | // 全局中间件,每个请求都有执行的操作
4 | type Middleware interface {
5 | Handle(Context) Context
6 | }
7 |
8 | // 响应数据被发送到客户端以后需要执行的操作
9 | type TerminateMiddleware interface {
10 | Handle(Context) Context
11 | Terminate(Context)
12 | }
13 |
--------------------------------------------------------------------------------
/showcases/go-boot/utils/encrypt/md5.go:
--------------------------------------------------------------------------------
1 | package encrypt
2 |
3 | import (
4 | "crypto/md5"
5 | "encoding/hex"
6 | )
7 |
8 | func Md5(src string) string {
9 | hash := md5.New()
10 | hash.Write([]byte(src))
11 | cipher := hash.Sum(nil)
12 | return hex.EncodeToString(cipher)
13 | }
14 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/website/README.md:
--------------------------------------------------------------------------------
1 | # `/website`
2 |
3 | This is the place to put your project's website data if you are not using Github pages.
4 |
5 | Examples:
6 |
7 | * https://github.com/hashicorp/vault/tree/master/website
8 | * https://github.com/perkeep/perkeep/tree/master/website
9 |
--------------------------------------------------------------------------------
/showcases/db/dbinterface/exec.go:
--------------------------------------------------------------------------------
1 | package dbinterface
2 |
3 | func Exec(db DB) error {
4 |
5 | defer db.Exec("DROP TABLE example")
6 |
7 | if err := Create(db); err != nil {
8 | return err
9 | }
10 |
11 | if err := Query(db); err != nil {
12 | return err
13 | }
14 | return nil
15 | }
16 |
--------------------------------------------------------------------------------
/showcases/gloc/bspool.go:
--------------------------------------------------------------------------------
1 | package gocloc
2 |
3 | import "sync"
4 |
5 | var bsPool = sync.Pool{New: func() interface{} { return make([]byte, 0, 128*1024) }}
6 |
7 | func getByteSlice() []byte {
8 | return bsPool.Get().([]byte)
9 | }
10 |
11 | func putByteSlice(bs []byte) {
12 | bsPool.Put(bs)
13 | }
14 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/tools/README.md:
--------------------------------------------------------------------------------
1 | # `/tools`
2 |
3 | Supporting tools for this project. Note that these tools can import code from the `/pkg` and `/internal` directories.
4 |
5 | Examples:
6 |
7 | * https://github.com/istio/istio/tree/master/tools
8 | * https://github.com/openshift/origin/tree/master/tools
9 |
--------------------------------------------------------------------------------
/showcases/db/redis/logger/logger.go:
--------------------------------------------------------------------------------
1 | package logger
2 |
3 | import (
4 | "github.com/labstack/echo"
5 | "github.com/sirupsen/logrus"
6 | )
7 |
8 | func FromContext(ectx echo.Context) *logrus.Entry {
9 | sessionID := ectx.Get("sessionID").(string)
10 | return logrus.WithField("sessionID", sessionID)
11 | }
12 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/doc/swagger/index.css:
--------------------------------------------------------------------------------
1 | html {
2 | box-sizing: border-box;
3 | overflow: -moz-scrollbars-vertical;
4 | overflow-y: scroll;
5 | }
6 |
7 | *,
8 | *:before,
9 | *:after {
10 | box-sizing: inherit;
11 | }
12 |
13 | body {
14 | margin: 0;
15 | background: #fafafa;
16 | }
17 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/eks/aws-auth.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: aws-auth
5 | namespace: kube-system
6 | data:
7 | mapUsers: |
8 | - userarn: arn:aws:iam::760486049168:user/github-ci
9 | username: github-ci
10 | groups:
11 | - system:masters
12 |
--------------------------------------------------------------------------------
/showcases/go-http-proxy-cli/model/file_type.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | type FileType string
4 |
5 | const (
6 | INI FileType = "INI"
7 | BPP FileType = "BPP"
8 | CLI FileType = "CLI"
9 | )
10 |
11 | type FileSource string
12 |
13 | const (
14 | local FileSource = "local"
15 | remote FileSource = "remote"
16 | )
17 |
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/domain/profile.go:
--------------------------------------------------------------------------------
1 | package domain
2 |
3 | import "context"
4 |
5 | type Profile struct {
6 | Name string `json:"name"`
7 | Email string `json:"email"`
8 | }
9 |
10 | type ProfileUsecase interface {
11 | GetProfileByID(c context.Context, userID string) (*Profile, error)
12 | }
13 |
--------------------------------------------------------------------------------
/showcases/golang-gin-realworld-example-app/scripts/gofmt.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | gofmt=$(govendor fmt +l)
4 | echo $gofmt
5 |
6 | if [ ${#gofmt} != 0 ]; then
7 | echo "There is unformatted code, you should use `go fmt ./\.\.\.` to format it."
8 | exit 1
9 | else
10 | echo "Codes are formatted."
11 | exit 0
12 | fi
13 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/proto/rpc_verify_email.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package pb;
4 |
5 | option go_package = "github.com/techschool/simplebank/pb";
6 |
7 | message VerifyEmailRequest {
8 | int64 email_id = 1;
9 | string secret_code = 2;
10 | }
11 |
12 | message VerifyEmailResponse {
13 | bool is_verified = 1;
14 | }
15 |
--------------------------------------------------------------------------------
/showcases/db/database/example/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/agtorre/go-solutions/section5/database"
5 | _ "github.com/go-sql-driver/mysql"
6 | )
7 |
8 | func main() {
9 | db, err := database.Setup()
10 | if err != nil {
11 | panic(err)
12 | }
13 |
14 | if err := database.Exec(db); err != nil {
15 | panic(err)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/showcases/minitask/compile.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
4 |
5 | export GOROOT=/usr/local/go
6 | export PATH=$PATH:/usr/local/go/bin
7 | export GOBIN=$dir/bin
8 | export GOPATH=$GOPATH:$dir
9 | export PKG_CONFIG_PATH=/usr/lib/pkgconfig/
10 |
11 | echo "/usr/local/go/bin/go install "$dir"/src/"$1
12 | go install $dir/src/$1
--------------------------------------------------------------------------------
/showcases/go-boot/error.go:
--------------------------------------------------------------------------------
1 | package go_boot
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | type SystemError struct {
9 | when time.Time
10 | file string
11 | line int
12 | what string
13 | }
14 |
15 | func (e SystemError) Error() string {
16 | return fmt.Sprintf("[datetime]:%v [file]:%v [line]:%v [message]:%v", e.when, e.file, e.line, e.what)
17 | }
18 |
--------------------------------------------------------------------------------
/showcases/golang-gin-realworld-example-app/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Golang Gonic/Gin startup project fork form RealWorld https://realworld.io
3 |
4 | You can find all the spec and front end demo in the Realworld project
5 |
6 | This project will include objects and relationships' CRUD, you will know how to write a golang/gin app though small perfectly formed.
7 | */
8 | package main
9 |
--------------------------------------------------------------------------------
/showcases/gloc/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: test build
2 |
3 | build:
4 | go build
5 | mkdir -p bin
6 | go build -o ./bin/gocloc cmd/gocloc/main.go
7 |
8 | update-vendor:
9 | dep ensure
10 |
11 | update-package:
12 | go get -u github.com/hhatto/gocloc
13 |
14 | run-example:
15 | go run examples/languages.go
16 | go run examples/files.go
17 |
18 | test:
19 | go test -v
20 |
--------------------------------------------------------------------------------
/showcases/golang-gin-realworld-example-app/users/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | The user module containing the user CRU operation.
3 |
4 | model.go: definition of orm based data model
5 |
6 | routers.go: router binding and core logic
7 |
8 | serializers.go: definition the schema of return data
9 |
10 | validators.go: definition the validator of form data
11 | */
12 | package users
13 |
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/domain/jwt_custom.go:
--------------------------------------------------------------------------------
1 | package domain
2 |
3 | import (
4 | "github.com/golang-jwt/jwt/v4"
5 | )
6 |
7 | type JwtCustomClaims struct {
8 | Name string `json:"name"`
9 | ID string `json:"id"`
10 | jwt.StandardClaims
11 | }
12 |
13 | type JwtCustomRefreshClaims struct {
14 | ID string `json:"id"`
15 | jwt.StandardClaims
16 | }
17 |
--------------------------------------------------------------------------------
/boilerplates/go-clean-architecture/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 |
8 | # Test binary, built with `go test -c`
9 | *.test
10 |
11 | # Output of the go coverage tool, specifically when used with LiteIDE
12 | *.out
13 |
14 | # Dependency directories (remove the comment below to include it)
15 | # vendor/
16 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/query/session.sql:
--------------------------------------------------------------------------------
1 | -- name: CreateSession :one
2 | INSERT INTO sessions (
3 | id,
4 | username,
5 | refresh_token,
6 | user_agent,
7 | client_ip,
8 | is_blocked,
9 | expires_at
10 | ) VALUES (
11 | $1, $2, $3, $4, $5, $6, $7
12 | ) RETURNING *;
13 |
14 | -- name: GetSession :one
15 | SELECT * FROM sessions
16 | WHERE id = $1 LIMIT 1;
17 |
--------------------------------------------------------------------------------
/showcases/db/database/exec.go:
--------------------------------------------------------------------------------
1 | package database
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | func Exec(db *sql.DB) error {
10 | defer db.Exec("DROP TABLE example")
11 |
12 | if err := Create(db); err != nil {
13 | return err
14 | }
15 |
16 | if err := Query(db); err != nil {
17 | return err
18 | }
19 | return nil
20 | }
21 |
--------------------------------------------------------------------------------
/showcases/db/pools/timeout.go:
--------------------------------------------------------------------------------
1 | package pools
2 |
3 | import (
4 | "context"
5 | "time"
6 | )
7 |
8 | func ExecWithTimeout() error {
9 | db, err := Setup()
10 | if err != nil {
11 | return err
12 | }
13 |
14 | ctx := context.Background()
15 | ctx, can := context.WithDeadline(ctx, time.Now())
16 |
17 | defer can()
18 |
19 | _, err = db.BeginTx(ctx, nil)
20 | return err
21 | }
22 |
--------------------------------------------------------------------------------
/showcases/db/redis/config.go:
--------------------------------------------------------------------------------
1 | package redis
2 |
3 | import (
4 | "os"
5 |
6 | redis "gopkg.in/redis.v5"
7 | )
8 |
9 | func Setup() (*redis.Client, error) {
10 | client := redis.NewClient(&redis.Options{
11 | Addr: "localhost:6379",
12 | Password: os.Getenv("REDISPASSWORD"),
13 | DB: 0,
14 | })
15 |
16 | _, err := client.Ping().Result()
17 | return client, err
18 | }
19 |
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/.env.example:
--------------------------------------------------------------------------------
1 | APP_ENV=development
2 | SERVER_ADDRESS=:8080
3 | PORT=8080
4 | CONTEXT_TIMEOUT=2
5 | DB_HOST=mongodb
6 | DB_PORT=27017
7 | DB_USER=
8 | DB_PASS=
9 | DB_NAME=go-backend-clean-architecture-db
10 | ACCESS_TOKEN_EXPIRY_HOUR = 2
11 | REFRESH_TOKEN_EXPIRY_HOUR = 168
12 | ACCESS_TOKEN_SECRET=access_token_secret
13 | REFRESH_TOKEN_SECRET=refresh_token_secret
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/query/entry.sql:
--------------------------------------------------------------------------------
1 | -- name: CreateEntry :one
2 | INSERT INTO entries (
3 | account_id,
4 | amount
5 | ) VALUES (
6 | $1, $2
7 | ) RETURNING *;
8 |
9 | -- name: GetEntry :one
10 | SELECT * FROM entries
11 | WHERE id = $1 LIMIT 1;
12 |
13 | -- name: ListEntries :many
14 | SELECT * FROM entries
15 | WHERE account_id = $1
16 | ORDER BY id
17 | LIMIT $2
18 | OFFSET $3;
19 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/examples/README.md:
--------------------------------------------------------------------------------
1 | # `/examples`
2 |
3 | Examples for your applications and/or public libraries.
4 |
5 | Examples:
6 |
7 | * https://github.com/nats-io/go-nats/tree/master/examples
8 | * https://github.com/docker-slim/docker-slim/tree/master/examples
9 | * https://github.com/gohugoio/hugo/tree/master/examples
10 | * https://github.com/hashicorp/packer/tree/master/examples
11 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/util/currency.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | // Constants for all supported currencies
4 | const (
5 | USD = "USD"
6 | EUR = "EUR"
7 | CAD = "CAD"
8 | )
9 |
10 | // IsSupportedCurrency returns true if the currency is supported
11 | func IsSupportedCurrency(currency string) bool {
12 | switch currency {
13 | case USD, EUR, CAD:
14 | return true
15 | }
16 | return false
17 | }
18 |
--------------------------------------------------------------------------------
/showcases/golang-gin-realworld-example-app/articles/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | The article module containing the article CRUD operation and relationship CRUD.
3 |
4 | model.go: definition of orm based data model
5 |
6 | routers.go: router binding and core logic
7 |
8 | serializers.go: definition the schema of return data
9 |
10 | validators.go: definition the validator of form data
11 | */
12 | package articles
13 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/api/validator.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "github.com/go-playground/validator/v10"
5 | "github.com/techschool/simplebank/util"
6 | )
7 |
8 | var validCurrency validator.Func = func(fieldLevel validator.FieldLevel) bool {
9 | if currency, ok := fieldLevel.Field().Interface().(string); ok {
10 | return util.IsSupportedCurrency(currency)
11 | }
12 | return false
13 | }
14 |
--------------------------------------------------------------------------------
/showcases/go-boot/utils/codec/json.go:
--------------------------------------------------------------------------------
1 | package codec
2 |
3 | import "encoding/json"
4 |
5 | type JsonCoder struct{}
6 |
7 | func (c *JsonCoder) Encoder(data interface{}) ([]byte, error) {
8 | return json.Marshal(data)
9 | }
10 |
11 | func (c *JsonCoder) Decoder(data []byte, v interface{}) error {
12 | return json.Unmarshal(data, v)
13 | }
14 |
15 | func init() {
16 | Register(JSON, &JsonCoder{})
17 | }
18 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/.gitignore:
--------------------------------------------------------------------------------
1 | # Mac OS X files
2 | .DS_Store
3 |
4 | # Binaries for programs and plugins
5 | *.exe
6 | *.dll
7 | *.so
8 | *.dylib
9 |
10 | # Test binary, build with `go test -c`
11 | *.test
12 |
13 | # Output of the go coverage tool, specifically when used with LiteIDE
14 | *.out
15 |
16 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
17 | .glide/
18 |
--------------------------------------------------------------------------------
/showcases/go-boot/utils/codec/xml.go:
--------------------------------------------------------------------------------
1 | package codec
2 |
3 | import (
4 | "encoding/xml"
5 | )
6 |
7 | type XMLCoder struct{}
8 |
9 | func (c *XMLCoder) Encoder(data interface{}) ([]byte, error) {
10 | return xml.Marshal(data)
11 | }
12 |
13 | func (c *XMLCoder) Decoder(data []byte, v interface{}) error {
14 | return xml.Unmarshal(data, v)
15 | }
16 |
17 | func init() {
18 | Register(XML, &JsonCoder{})
19 | }
20 |
--------------------------------------------------------------------------------
/showcases/golang-gin-realworld-example-app/BACKEND_INSTRUCTIONS.md:
--------------------------------------------------------------------------------
1 | > *Note: Delete this file before publishing your app!*
2 |
3 | # [Backend API spec](https://github.com/gothinkster/realworld/tree/master/api)
4 |
5 | For your convenience, we have a [Postman collection](https://github.com/gothinkster/realworld/blob/master/api/Conduit.postman_collection.json) that you can use to test your API endpoints as you build your app.
6 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/scripts/README.md:
--------------------------------------------------------------------------------
1 | # `/scripts`
2 |
3 | Scripts to perform various build, install, analysis, etc operations.
4 |
5 | These scripts keep the root level Makefile small and simple.
6 |
7 | Examples:
8 |
9 | * https://github.com/kubernetes/helm/tree/master/scripts
10 | * https://github.com/cockroachdb/cockroach/tree/master/scripts
11 | * https://github.com/hashicorp/terraform/tree/master/scripts
--------------------------------------------------------------------------------
/showcases/2024~simplebank/proto/rpc_create_user.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package pb;
4 |
5 | import "user.proto";
6 |
7 | option go_package = "github.com/techschool/simplebank/pb";
8 |
9 | message CreateUserRequest {
10 | string username = 1;
11 | string full_name = 2;
12 | string email = 3;
13 | string password = 4;
14 | }
15 |
16 | message CreateUserResponse {
17 | User user = 1;
18 | }
19 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/proto/user.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package pb;
4 |
5 | import "google/protobuf/timestamp.proto";
6 |
7 | option go_package = "github.com/techschool/simplebank/pb";
8 |
9 | message User {
10 | string username = 1;
11 | string full_name = 2;
12 | string email = 3;
13 | google.protobuf.Timestamp password_changed_at = 4;
14 | google.protobuf.Timestamp created_at = 5;
15 | }
16 |
--------------------------------------------------------------------------------
/showcases/db/dbinterface/create.go:
--------------------------------------------------------------------------------
1 | package dbinterface
2 |
3 | import _ "github.com/go-sql-driver/mysql"
4 |
5 | func Create(db DB) error {
6 | if _, err := db.Exec("CREATE TABLE example (name VARCHAR(20), created DATETIME)"); err != nil {
7 | return err
8 | }
9 |
10 | if _, err := db.Exec(`INSERT INTO example (name, created) values ("Aaron", NOW())`); err != nil {
11 | return err
12 | }
13 |
14 | return nil
15 | }
16 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/eks/service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: simple-bank-api-service
5 | spec:
6 | selector:
7 | app: simple-bank-api
8 | ports:
9 | - protocol: TCP
10 | port: 80
11 | targetPort: http-server
12 | name: http-service
13 | - protocol: TCP
14 | port: 90
15 | targetPort: grpc-server
16 | name: grpc-service
17 | type: ClusterIP
18 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/Dockerfile:
--------------------------------------------------------------------------------
1 | # Build stage
2 | FROM golang:1.22-alpine3.19 AS builder
3 | WORKDIR /app
4 | COPY . .
5 | RUN go build -o main main.go
6 |
7 | # Run stage
8 | FROM alpine:3.19
9 | WORKDIR /app
10 | COPY --from=builder /app/main .
11 | COPY app.env .
12 | COPY start.sh .
13 | COPY wait-for.sh .
14 | COPY db/migration ./db/migration
15 |
16 | EXPOSE 8080 9090
17 | CMD [ "/app/main" ]
18 | ENTRYPOINT [ "/app/start.sh" ]
19 |
--------------------------------------------------------------------------------
/showcases/go-boot/config.go:
--------------------------------------------------------------------------------
1 | package go_boot
2 |
3 | import "time"
4 |
5 | // Config for socket server
6 | type Config struct {
7 | Debug bool
8 | ReadBufferSize int
9 | WriteBufferSize int
10 | Timeout time.Duration
11 | MaxPayload uint32
12 | ContentType string
13 | PluginForPacketSender []PacketPlugin
14 | PluginForPacketReceiver []PacketPlugin
15 | }
16 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/proto/rpc_update_user.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package pb;
4 |
5 | import "user.proto";
6 |
7 | option go_package = "github.com/techschool/simplebank/pb";
8 |
9 | message UpdateUserRequest {
10 | string username = 1;
11 | optional string full_name = 2;
12 | optional string email = 3;
13 | optional string password = 4;
14 | }
15 |
16 | message UpdateUserResponse {
17 | User user = 1;
18 | }
19 |
--------------------------------------------------------------------------------
/showcases/db/redis/exec_test.go:
--------------------------------------------------------------------------------
1 | package redis
2 |
3 | import "testing"
4 |
5 | func TestExec(t *testing.T) {
6 | tests := []struct {
7 | name string
8 | wantErr bool
9 | }{
10 | {"base-case", false},
11 | }
12 | for _, tt := range tests {
13 | t.Run(tt.name, func(t *testing.T) {
14 | if err := Exec(); (err != nil) != tt.wantErr {
15 | t.Errorf("Exec() error = %v, wantErr %v", err, tt.wantErr)
16 | }
17 | })
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/showcases/db/redis/sort_test.go:
--------------------------------------------------------------------------------
1 | package redis
2 |
3 | import "testing"
4 |
5 | func TestSort(t *testing.T) {
6 | tests := []struct {
7 | name string
8 | wantErr bool
9 | }{
10 | {"base-case", false},
11 | }
12 | for _, tt := range tests {
13 | t.Run(tt.name, func(t *testing.T) {
14 | if err := Sort(); (err != nil) != tt.wantErr {
15 | t.Errorf("Sort() error = %v, wantErr %v", err, tt.wantErr)
16 | }
17 | })
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/showcases/db/mongodb/exec_test.go:
--------------------------------------------------------------------------------
1 | package mongodb
2 |
3 | import "testing"
4 |
5 | func TestExec(t *testing.T) {
6 | tests := []struct {
7 | name string
8 | wantErr bool
9 | }{
10 | {"base-case", false},
11 | }
12 | for _, tt := range tests {
13 | t.Run(tt.name, func(t *testing.T) {
14 | if err := Exec(); (err != nil) != tt.wantErr {
15 | t.Errorf("Exec() error = %v, wantErr %v", err, tt.wantErr)
16 | }
17 | })
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/boilerplates/go-clean-architecture/.air.conf:
--------------------------------------------------------------------------------
1 | root = "."
2 |
3 | watch_dir = "."
4 | tmp_dir = ""
5 |
6 | [build]
7 | cmd = "go build -o ./api/main ./api/main.go"
8 | bin = "api/main"
9 | include_ext = ["go", "tpl", "tmpl", "html"]
10 | exclude_dir = ["assets", "tmp", "vendor", "postgres-data"]
11 | delay = 100 # ms
12 |
13 | [log]
14 | time = true
15 |
16 | [color]
17 | main = "magenta"
18 | watcher = "cyan"
19 | build = "yellow"
20 | runner = "green"
21 |
--------------------------------------------------------------------------------
/showcases/go-http-proxy-cli/model/file.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | type File struct {
4 | fileId string ""
5 | fileType FileType "INI | BPP | CLI"
6 | fileSource FileSource "remote"
7 | url string
8 | fileHash string
9 | }
10 |
11 | func NewFile(fileId string, fileType FileType, fileSource FileSource, url string, fileHash string) *File {
12 | file := &File{fileId, fileType, fileSource, url, fileHash}
13 |
14 | return file
15 | }
16 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/token/maker.go:
--------------------------------------------------------------------------------
1 | package token
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | // Maker is an interface for managing tokens
8 | type Maker interface {
9 | // CreateToken creates a new token for a specific username and duration
10 | CreateToken(username string, role string, duration time.Duration) (string, *Payload, error)
11 |
12 | // VerifyToken checks if the token is valid or not
13 | VerifyToken(token string) (*Payload, error)
14 | }
15 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/query/verify_email.sql:
--------------------------------------------------------------------------------
1 | -- name: CreateVerifyEmail :one
2 | INSERT INTO verify_emails (
3 | username,
4 | email,
5 | secret_code
6 | ) VALUES (
7 | $1, $2, $3
8 | ) RETURNING *;
9 |
10 | -- name: UpdateVerifyEmail :one
11 | UPDATE verify_emails
12 | SET
13 | is_used = TRUE
14 | WHERE
15 | id = @id
16 | AND secret_code = @secret_code
17 | AND is_used = FALSE
18 | AND expired_at > now()
19 | RETURNING *;
20 |
--------------------------------------------------------------------------------
/showcases/golang-gin-realworld-example-app/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /bower_components
6 |
7 | # IDEs and editors
8 | /.idea
9 | .project
10 | .classpath
11 | *.launch
12 | .settings/
13 |
14 | #System Files
15 | .DS_Store
16 | Thumbs.db
17 |
18 | vendor/*
19 | !vendor/vendor.json
20 |
21 | tmp/*
22 | gorm.db
23 | coverage.txt
24 |
25 | bak.*
26 |
27 | build
28 |
--------------------------------------------------------------------------------
/showcases/minimal-server/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "net/http"
7 | )
8 |
9 | func sayHelloName(w http.ResponseWriter, r *http.Request) {
10 | r.ParseForm()
11 | fmt.Println("path:", r.URL.Path)
12 | fmt.Fprintf(w, "hello go")
13 | }
14 |
15 | func main() {
16 | http.HandleFunc("/", sayHelloName)
17 | err := http.ListenAndServe(":9090", nil)
18 |
19 | if err != nil {
20 | log.Fatal("ListenAndServer: ", err)
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/showcases/db/database/create.go:
--------------------------------------------------------------------------------
1 | package database
2 |
3 | import (
4 | "database/sql"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | func Create(db *sql.DB) error {
10 | if _, err := db.Exec("CREATE TABLE example (name VARCHAR(20),
11 | created DATETIME)"); err != nil {
12 | return err
13 | }
14 |
15 | if _, err := db.Exec(`INSERT INTO example (name, created)
16 | values ("Aaron", NOW())`); err != nil {
17 | return err
18 | }
19 |
20 | return nil
21 | }
22 |
--------------------------------------------------------------------------------
/showcases/db/mongodb/config_test.go:
--------------------------------------------------------------------------------
1 | package mongodb
2 |
3 | import "testing"
4 |
5 | func TestSetup(t *testing.T) {
6 | tests := []struct {
7 | name string
8 | wantErr bool
9 | }{
10 | {"base-case", false},
11 | }
12 | for _, tt := range tests {
13 | t.Run(tt.name, func(t *testing.T) {
14 | _, err := Setup()
15 | if (err != nil) != tt.wantErr {
16 | t.Errorf("Setup() error = %v, wantErr %v", err, tt.wantErr)
17 | return
18 | }
19 | })
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/showcases/db/pools/pools.go:
--------------------------------------------------------------------------------
1 | package pools
2 |
3 | import (
4 | "database/sql"
5 | "fmt"
6 | "os"
7 |
8 | _ "github.com/go-sql-driver/mysql"
9 | )
10 |
11 | func Setup() (*sql.DB, error) {
12 | db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@/gosolutions?parseTime=true", os.Getenv("MYSQLUSERNAME"), os.Getenv("MYSQLPASSWORD")))
13 | if err != nil {
14 | return nil, err
15 | }
16 |
17 | db.SetMaxOpenConns(24)
18 | db.SetMaxIdleConns(24)
19 |
20 | return db, nil
21 | }
22 |
--------------------------------------------------------------------------------
/showcases/db/pools/timeout_test.go:
--------------------------------------------------------------------------------
1 | package pools
2 |
3 | import "testing"
4 |
5 | func TestExecWithTimeout(t *testing.T) {
6 | tests := []struct {
7 | name string
8 | wantErr bool
9 | }{
10 | {"base-case", true},
11 | }
12 | for _, tt := range tests {
13 | t.Run(tt.name, func(t *testing.T) {
14 | if err := ExecWithTimeout(); (err != nil) != tt.wantErr {
15 | t.Errorf("ExecWithTimeout() error = %v, wantErr %v", err, tt.wantErr)
16 | }
17 | })
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/query/transfer.sql:
--------------------------------------------------------------------------------
1 | -- name: CreateTransfer :one
2 | INSERT INTO transfers (
3 | from_account_id,
4 | to_account_id,
5 | amount
6 | ) VALUES (
7 | $1, $2, $3
8 | ) RETURNING *;
9 |
10 | -- name: GetTransfer :one
11 | SELECT * FROM transfers
12 | WHERE id = $1 LIMIT 1;
13 |
14 | -- name: ListTransfers :many
15 | SELECT * FROM transfers
16 | WHERE
17 | from_account_id = $1 OR
18 | to_account_id = $2
19 | ORDER BY id
20 | LIMIT $3
21 | OFFSET $4;
22 |
--------------------------------------------------------------------------------
/showcases/db/redis/config_test.go:
--------------------------------------------------------------------------------
1 | package redis
2 |
3 | import "testing"
4 |
5 | func TestSetup(t *testing.T) {
6 | tests := []struct {
7 | name string
8 | wantErr bool
9 | }{
10 | {"base-case", false},
11 | }
12 | for _, tt := range tests {
13 | t.Run(tt.name, func(t *testing.T) {
14 | _, err := Setup()
15 | if (err != nil) != tt.wantErr {
16 | t.Errorf("Setup() error = %v, wantErr %v", err, tt.wantErr)
17 | return
18 | }
19 |
20 | })
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/showcases/db/dbinterface/transaction.go:
--------------------------------------------------------------------------------
1 | package dbinterface
2 |
3 | import "database/sql"
4 |
5 | type DB interface {
6 | Exec(query string, args ...interface{}) (sql.Result, error)
7 | Prepare(query string) (*sql.Stmt, error)
8 | Query(query string, args ...interface{}) (*sql.Rows, error)
9 | QueryRow(query string, args ...interface{}) *sql.Row
10 | }
11 |
12 | type Transaction interface {
13 | DB
14 | Commit() error
15 | Rollback() error
16 | Stmt(stmt *sql.Stmt) *sql.Stmt
17 | }
18 |
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/bootstrap/app.go:
--------------------------------------------------------------------------------
1 | package bootstrap
2 |
3 | import "github.com/amitshekhariitbhu/go-backend-clean-architecture/mongo"
4 |
5 | type Application struct {
6 | Env *Env
7 | Mongo mongo.Client
8 | }
9 |
10 | func App() Application {
11 | app := &Application{}
12 | app.Env = NewEnv()
13 | app.Mongo = NewMongoDatabase(app.Env)
14 | return *app
15 | }
16 |
17 | func (app *Application) CloseDBConnection() {
18 | CloseMongoDBConnection(app.Mongo)
19 | }
20 |
--------------------------------------------------------------------------------
/showcases/db/firebase/auth_test.go:
--------------------------------------------------------------------------------
1 | package firebase
2 |
3 | import "testing"
4 |
5 | func TestAuthenticate(t *testing.T) {
6 |
7 | tests := []struct {
8 | name string
9 | wantErr bool
10 | }{
11 | {"base-case", false},
12 | }
13 | for _, tt := range tests {
14 | t.Run(tt.name, func(t *testing.T) {
15 | _, err := Authenticate()
16 | if (err != nil) != tt.wantErr {
17 | t.Errorf("Authenticate() error = %v, wantErr %v", err, tt.wantErr)
18 | return
19 | }
20 | })
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/migration/000003_add_sessions.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "sessions" (
2 | "id" uuid PRIMARY KEY,
3 | "username" varchar NOT NULL,
4 | "refresh_token" varchar NOT NULL,
5 | "user_agent" varchar NOT NULL,
6 | "client_ip" varchar NOT NULL,
7 | "is_blocked" boolean NOT NULL DEFAULT false,
8 | "expires_at" timestamptz NOT NULL,
9 | "created_at" timestamptz NOT NULL DEFAULT (now())
10 | );
11 |
12 | ALTER TABLE "sessions" ADD FOREIGN KEY ("username") REFERENCES "users" ("username");
13 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/sqlc.yaml:
--------------------------------------------------------------------------------
1 | version: "2"
2 | sql:
3 | - schema: "db/migration"
4 | queries: "db/query"
5 | engine: "postgresql"
6 | gen:
7 | go:
8 | package: "db"
9 | out: "db/sqlc"
10 | sql_package: "pgx/v5"
11 | emit_json_tags: true
12 | emit_interface: true
13 | emit_empty_slices: true
14 | overrides:
15 | - db_type: "timestamptz"
16 | go_type: "time.Time"
17 | - db_type: "uuid"
18 | go_type: "github.com/google/uuid.UUID"
19 |
--------------------------------------------------------------------------------
/boilerplates/go-clean-architecture/pkg/user/entity.go:
--------------------------------------------------------------------------------
1 | package user
2 |
3 | import "github.com/jinzhu/gorm"
4 |
5 | type User struct {
6 | gorm.Model
7 | FirstName string `json:"first_name,omitempty"`
8 | LastName string `json:"last_name,omitempty"`
9 | Password string `json:"password,omitempty"`
10 | PhoneNumber string `json:"phone_number,omitempty"`
11 | Email string `json:"email,omitempty"`
12 | Address string `json:"address,omitempty"`
13 | DisplayPic string `json:"display_pic,omitempty"`
14 | }
15 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/app.env:
--------------------------------------------------------------------------------
1 | ENVIRONMENT=development
2 | DB_SOURCE=postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable
3 | MIGRATION_URL=file://db/migration
4 | HTTP_SERVER_ADDRESS=0.0.0.0:8080
5 | GRPC_SERVER_ADDRESS=0.0.0.0:9090
6 | TOKEN_SYMMETRIC_KEY=12345678901234567890123456789012
7 | ACCESS_TOKEN_DURATION=15m
8 | REFRESH_TOKEN_DURATION=24h
9 | REDIS_ADDRESS=0.0.0.0:6379
10 | EMAIL_SENDER_NAME=Simple Bank
11 | EMAIL_SENDER_ADDRESS=simplebanktest@gmail.com
12 | EMAIL_SENDER_PASSWORD=jekfcygyenvzekke
13 |
--------------------------------------------------------------------------------
/showcases/db/storage/mongoconfig.go:
--------------------------------------------------------------------------------
1 | package storage
2 |
3 | import mgo "gopkg.in/mgo.v2"
4 |
5 | type MongoStorage struct {
6 | *mgo.Session
7 | DB string
8 | Collection string
9 | }
10 |
11 | func NewMongoStorage(connection, db, collection string)
12 | (*MongoStorage, error) {
13 | session, err := mgo.Dial("localhost")
14 | if err != nil {
15 | return nil, err
16 | }
17 | ms := MongoStorage{
18 | Session: session,
19 | DB: db,
20 | Collection: collection,
21 | }
22 | return &ms, nil
23 | }
24 |
--------------------------------------------------------------------------------
/boilerplates/go-clean-architecture/pkg/admin/entity.go:
--------------------------------------------------------------------------------
1 | package admin
2 |
3 | import "github.com/jinzhu/gorm"
4 |
5 | type Admin struct {
6 | gorm.Model
7 | FirstName string `json:"first_name,omitempty"`
8 | LastName string `json:"last_name,omitempty"`
9 | Password string `json:"password,omitempty"`
10 | PhoneNumber string `json:"phone_number,omitempty"`
11 | Email string `json:"email,omitempty"`
12 | Address string `json:"address,omitempty"`
13 | DisplayPic string `json:"display_pic,omitempty"`
14 | }
15 |
--------------------------------------------------------------------------------
/showcases/db/database/config.go:
--------------------------------------------------------------------------------
1 | package database
2 |
3 | import (
4 | "database/sql"
5 | "fmt"
6 | "os"
7 | "time"
8 |
9 | _ "github.com/go-sql-driver/mysql"
10 | )
11 |
12 | type Example struct {
13 | Name string
14 | Created *time.Time
15 | }
16 |
17 | func Setup() (*sql.DB, error) {
18 | db, err := sql.Open("mysql",
19 | fmt.Sprintf("%s:%s@/gosolutions?parseTime=true",
20 | os.Getenv("MYSQLUSERNAME"), os.Getenv("MYSQLPASSWORD")))
21 | if err != nil {
22 | return nil, err
23 | }
24 | return db, nil
25 | }
26 |
--------------------------------------------------------------------------------
/showcases/db/pools/pools_test.go:
--------------------------------------------------------------------------------
1 | package pools
2 |
3 | import (
4 | "testing"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | func TestSetup(t *testing.T) {
10 | tests := []struct {
11 | name string
12 | wantErr bool
13 | }{
14 | {"base-case", false},
15 | }
16 | for _, tt := range tests {
17 | t.Run(tt.name, func(t *testing.T) {
18 | _, err := Setup()
19 | if (err != nil) != tt.wantErr {
20 | t.Errorf("Setup() error = %v, wantErr %v", err, tt.wantErr)
21 | return
22 | }
23 | })
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/showcases/go-boot/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Go template
3 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
4 | *.o
5 | *.a
6 | *.so
7 |
8 | # Folders
9 | _obj
10 | _test
11 |
12 | # Architecture specific extensions/prefixes
13 | *.[568vq]
14 | [568vq].out
15 |
16 | *.cgo1.go
17 | *.cgo2.c
18 | _cgo_defun.c
19 | _cgo_gotypes.go
20 | _cgo_export.*
21 |
22 | _testmain.go
23 |
24 | *.exe
25 | *.test
26 | *.prof
27 | *~
28 | .DS_Store
29 |
30 | /.idea/
31 | /linker.iml
32 | /vendor/
33 |
--------------------------------------------------------------------------------
/showcases/db/database/config_test.go:
--------------------------------------------------------------------------------
1 | package database
2 |
3 | import (
4 | "testing"
5 |
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | func TestSetup(t *testing.T) {
10 | tests := []struct {
11 | name string
12 | wantErr bool
13 | }{
14 | {"base-case", false},
15 | }
16 | for _, tt := range tests {
17 | t.Run(tt.name, func(t *testing.T) {
18 | _, err := Setup()
19 | if (err != nil) != tt.wantErr {
20 | t.Errorf("Setup() error = %v, wantErr %v", err, tt.wantErr)
21 | return
22 | }
23 | })
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/showcases/gloc/option.go:
--------------------------------------------------------------------------------
1 | package gocloc
2 |
3 | import "regexp"
4 |
5 | type ClocOptions struct {
6 | Debug bool
7 | SkipDuplicated bool
8 | ExcludeExts map[string]struct{}
9 | IncludeLangs map[string]struct{}
10 | ReNotMatchDir *regexp.Regexp
11 | ReMatchDir *regexp.Regexp
12 | }
13 |
14 | func NewClocOptions() *ClocOptions {
15 | return &ClocOptions{
16 | Debug: false,
17 | SkipDuplicated: false,
18 | ExcludeExts: make(map[string]struct{}),
19 | IncludeLangs: make(map[string]struct{}),
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/sqlc/error.go:
--------------------------------------------------------------------------------
1 | package db
2 |
3 | import (
4 | "errors"
5 |
6 | "github.com/jackc/pgx/v5"
7 | "github.com/jackc/pgx/v5/pgconn"
8 | )
9 |
10 | const (
11 | ForeignKeyViolation = "23503"
12 | UniqueViolation = "23505"
13 | )
14 |
15 | var ErrRecordNotFound = pgx.ErrNoRows
16 |
17 | var ErrUniqueViolation = &pgconn.PgError{
18 | Code: UniqueViolation,
19 | }
20 |
21 | func ErrorCode(err error) string {
22 | var pgErr *pgconn.PgError
23 | if errors.As(err, &pgErr) {
24 | return pgErr.Code
25 | }
26 | return ""
27 | }
28 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/gapi/converter.go:
--------------------------------------------------------------------------------
1 | package gapi
2 |
3 | import (
4 | db "github.com/techschool/simplebank/db/sqlc"
5 | "github.com/techschool/simplebank/pb"
6 | "google.golang.org/protobuf/types/known/timestamppb"
7 | )
8 |
9 | func convertUser(user db.User) *pb.User {
10 | return &pb.User{
11 | Username: user.Username,
12 | FullName: user.FullName,
13 | Email: user.Email,
14 | PasswordChangedAt: timestamppb.New(user.PasswordChangedAt),
15 | CreatedAt: timestamppb.New(user.CreatedAt),
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/showcases/db/storage/mongointerface.go:
--------------------------------------------------------------------------------
1 | package storage
2 |
3 | import (
4 | "context"
5 |
6 | "gopkg.in/mgo.v2/bson"
7 | )
8 |
9 | func (m *MongoStorage) GetByName(ctx context.Context, name string)
10 | (*Item, error) {
11 | c := m.Session.DB(m.DB).C(m.Collection)
12 | var i Item
13 | if err := c.Find(bson.M{"name": name}).One(&i); err != nil {
14 | return nil, err
15 | }
16 | return &i, nil
17 | }
18 |
19 | func (m *MongoStorage) Put(ctx context.Context, i *Item) error {
20 | c := m.Session.DB(m.DB).C(m.Collection)
21 | return c.Insert(i)
22 | }
23 |
--------------------------------------------------------------------------------
/showcases/db/redis/exec.go:
--------------------------------------------------------------------------------
1 | package redis
2 |
3 | import (
4 | "fmt"
5 | "time"
6 |
7 | redis "gopkg.in/redis.v5"
8 | )
9 |
10 | func Exec() error {
11 | conn, err := Setup()
12 | if err != nil {
13 | return err
14 | }
15 |
16 | c1 := "value"
17 | conn.Set("key", c1, 5*time.Second)
18 |
19 | var result string
20 | if err := conn.Get("key").Scan(&result); err != nil {
21 | switch err {
22 | case redis.Nil:
23 | return nil
24 | default:
25 | return err
26 | }
27 | }
28 |
29 | fmt.Println("result =", result)
30 |
31 | return nil
32 | }
33 |
--------------------------------------------------------------------------------
/boilerplates/go-clean-architecture/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.1'
2 |
3 | services:
4 |
5 | db:
6 | image: postgres
7 | restart: always
8 | ports:
9 | - 5432:5432
10 | env_file: "./config.json"
11 | environment:
12 | POSTGRES_PASSWORD: "${POSTGRES_PASSWORD_dev}"
13 | POSTGRES_USER: "${POSTGRES_USER_dev}"
14 | POSTGRES_DB: "${POSTGRES_DB_dev}"
15 | volumes:
16 | - ./postgres-data:/var/lib/postgresql/data
17 |
18 | adminer:
19 | image: adminer
20 | restart: always
21 | ports:
22 | - 8080:8080
23 |
--------------------------------------------------------------------------------
/showcases/golang-gin-realworld-example-app/scripts/coverage.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | # http://stackoverflow.com/a/21142256/2055281
6 |
7 | echo "mode: atomic" > coverage.txt
8 |
9 | for d in $(find ./* -maxdepth 10 -type d); do
10 | if ls $d/*.go &> /dev/null; then
11 | go test -coverprofile=profile.out -covermode=atomic $d
12 | if [ -f profile.out ]; then
13 | echo "$(pwd)"
14 | cat profile.out | grep -v "mode: " >> coverage.txt
15 | rm profile.out
16 | fi
17 | fi
18 | done
19 |
20 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/eks/issuer.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: cert-manager.io/v1
2 | kind: ClusterIssuer
3 | metadata:
4 | name: letsencrypt
5 | spec:
6 | acme:
7 | email: techschool.guru@gmail.com
8 | server: https://acme-v02.api.letsencrypt.org/directory
9 | privateKeySecretRef:
10 | # Secret resource that will be used to store the account's private key.
11 | name: letsencrypt-account-private-key
12 | # Add a single challenge solver, HTTP01 using nginx
13 | solvers:
14 | - http01:
15 | ingress:
16 | ingressClassName: nginx
17 |
--------------------------------------------------------------------------------
/showcases/db/firebase/example/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 |
7 | "github.com/agtorre/go-solutions/section5/firebase"
8 | )
9 |
10 | func main() {
11 | f, err := firebase.Authenticate()
12 | if err != nil {
13 | log.Fatalf("error authenticating")
14 | }
15 | f.Set("key", []string{"val1", "val2"})
16 | res, _ := f.Get()
17 | fmt.Println(res)
18 |
19 | vals := res["key"].([]interface{})
20 | vals = append(vals, map[string][]string{"key2": []string{"val3"}})
21 | f.Set("key", vals)
22 | res, _ = f.Get()
23 | fmt.Println(res)
24 | }
25 |
--------------------------------------------------------------------------------
/showcases/go-boot/utils/encrypt/aes_test.go:
--------------------------------------------------------------------------------
1 | package encrypt
2 |
3 | import (
4 | "encoding/base64"
5 | "fmt"
6 | "testing"
7 | )
8 |
9 | func TestAES(t *testing.T) {
10 | src := "hello,你好世界"
11 | encodeBytes, err := Encrypt([]byte(src))
12 | if err != nil {
13 | t.Error(err)
14 | }
15 | fmt.Println(base64.StdEncoding.EncodeToString(encodeBytes))
16 |
17 | decodeBytes, err := Decrypt(encodeBytes)
18 | if err != nil {
19 | t.Error(err)
20 | }
21 |
22 | if string(decodeBytes) != src {
23 | t.Error(err)
24 | }
25 |
26 | fmt.Println(string(decodeBytes))
27 | }
28 |
--------------------------------------------------------------------------------
/showcases/golang-gin-realworld-example-app/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | go:
4 | - 1.7
5 | - 1.8.x
6 | - master
7 |
8 | go_import_path: github.com/gothinkster/golang-gin-realworld-example-app
9 |
10 | services:
11 | - sqlite3
12 |
13 | install:
14 | - go get -u github.com/gothinkster/golang-gin-realworld-example-app
15 | - go get -u github.com/kardianos/govendor
16 | - govendor sync
17 | script:
18 | # - go test -v ./...
19 | - bash ./scripts/gofmt.sh
20 | - bash ./scripts/coverage.sh
21 |
22 | after_success:
23 | - bash <(curl -s https://codecov.io/bash)
24 |
--------------------------------------------------------------------------------
/showcases/go-boot/plugins/debug.go:
--------------------------------------------------------------------------------
1 | package plugins
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/wxyyxc1992/go-boot/utils/encrypt"
7 | )
8 |
9 | type Debug struct {
10 | Sender bool
11 | }
12 |
13 | func (d *Debug) Handle(header, body []byte) (h, b []byte) {
14 | if d.Sender {
15 | th, _ := encrypt.Decrypt(header)
16 | tb, _ := encrypt.Decrypt(body)
17 |
18 | fmt.Println("[send packet]", "header:", string(th), "body:", string(tb))
19 | } else {
20 | fmt.Println("[receive packet]", "header:", string(header), "body:", string(body))
21 | }
22 |
23 | return header, body
24 | }
25 |
--------------------------------------------------------------------------------
/boilerplates/go-clean-architecture/pkg/errors.go:
--------------------------------------------------------------------------------
1 | package errors
2 |
3 | import (
4 | "errors"
5 | )
6 |
7 | var (
8 | ErrNotFound = errors.New("Error: Document not found")
9 | ErrNoContent = errors.New("Error: Document not found")
10 | ErrInvalidSlug = errors.New("Error: Invalid slug")
11 | ErrExists = errors.New("Error: Document already exists")
12 | ErrDatabase = errors.New("Error: Database error")
13 | ErrUnauthorized = errors.New("Error: You are not allowed to perform this action")
14 | ErrForbidden = errors.New("Error: Access to this resource is forbidden")
15 | )
16 |
--------------------------------------------------------------------------------
/showcases/db/dbinterface/example/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/agtorre/go-solutions/section5/database"
5 | "github.com/agtorre/go-solutions/section5/dbinterface"
6 | _ "github.com/go-sql-driver/mysql"
7 | )
8 |
9 | func main() {
10 | db, err := database.Setup()
11 | if err != nil {
12 | panic(err)
13 | }
14 |
15 | tx, err := db.Begin()
16 | if err != nil {
17 | panic(err)
18 | }
19 | defer tx.Rollback()
20 |
21 | if err := dbinterface.Exec(db); err != nil {
22 | panic(err)
23 | }
24 | if err := tx.Commit(); err != nil {
25 | panic(err)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/internal/README.md:
--------------------------------------------------------------------------------
1 | # `/internal`
2 |
3 | Private application and library code. This is the code you don't want others importing in their applications or libraries.
4 |
5 | You can optionally add a bit of extra structure to your internal packages to separate your shared and non-shared internal code. It's not required, but it's nice to have visual clues showing the intended package use. Your actual application code can go in the `/internal/app` directory (e.g., `/internal/app/myapp`) and the code shared by those apps in the `/internal/pkg` directory (e.g., `/internal/pkg/myprivlib`).
6 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/sqlc/exec_tx.go:
--------------------------------------------------------------------------------
1 | package db
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | )
7 |
8 | // ExecTx executes a function within a database transaction
9 | func (store *SQLStore) execTx(ctx context.Context, fn func(*Queries) error) error {
10 | tx, err := store.connPool.Begin(ctx)
11 | if err != nil {
12 | return err
13 | }
14 |
15 | q := New(tx)
16 | err = fn(q)
17 | if err != nil {
18 | if rbErr := tx.Rollback(ctx); rbErr != nil {
19 | return fmt.Errorf("tx err: %v, rb err: %v", err, rbErr)
20 | }
21 | return err
22 | }
23 |
24 | return tx.Commit(ctx)
25 | }
26 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/migration/000004_add_verify_emails.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "verify_emails" (
2 | "id" bigserial PRIMARY KEY,
3 | "username" varchar NOT NULL,
4 | "email" varchar NOT NULL,
5 | "secret_code" varchar NOT NULL,
6 | "is_used" bool NOT NULL DEFAULT false,
7 | "created_at" timestamptz NOT NULL DEFAULT (now()),
8 | "expired_at" timestamptz NOT NULL DEFAULT (now() + interval '15 minutes')
9 | );
10 |
11 | ALTER TABLE "verify_emails" ADD FOREIGN KEY ("username") REFERENCES "users" ("username");
12 |
13 | ALTER TABLE "users" ADD COLUMN "is_email_verified" bool NOT NULL DEFAULT false;
14 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/worker/distributor.go:
--------------------------------------------------------------------------------
1 | package worker
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/hibiken/asynq"
7 | )
8 |
9 | type TaskDistributor interface {
10 | DistributeTaskSendVerifyEmail(
11 | ctx context.Context,
12 | payload *PayloadSendVerifyEmail,
13 | opts ...asynq.Option,
14 | ) error
15 | }
16 |
17 | type RedisTaskDistributor struct {
18 | client *asynq.Client
19 | }
20 |
21 | func NewRedisTaskDistributor(redisOpt asynq.RedisClientOpt) TaskDistributor {
22 | client := asynq.NewClient(redisOpt)
23 | return &RedisTaskDistributor{
24 | client: client,
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/showcases/db/dbinterface/query.go:
--------------------------------------------------------------------------------
1 | package dbinterface
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/agtorre/go-solutions/section5/database"
7 | )
8 |
9 | func Query(db DB) error {
10 | name := "Aaron"
11 | rows, err := db.Query("SELECT name, created FROM example where name=?", name)
12 | if err != nil {
13 | return err
14 | }
15 | defer rows.Close()
16 | for rows.Next() {
17 | var e database.Example
18 | if err := rows.Scan(&e.Name, &e.Created); err != nil {
19 | return err
20 | }
21 | fmt.Printf("Results:\n\tName: %s\n\tCreated: %v\n", e.Name, e.Created)
22 | }
23 | return rows.Err()
24 | }
25 |
--------------------------------------------------------------------------------
/showcases/db/redis/sessions/memory.go:
--------------------------------------------------------------------------------
1 | package sessions
2 |
3 | import "errors"
4 |
5 | type memoryStore struct {
6 | sessions map[string]Session
7 | }
8 |
9 | func NewMemoryStore() Store {
10 | return &memoryStore{
11 | sessions: make(map[string]Session),
12 | }
13 | }
14 |
15 | func (m memoryStore) Get(id string) (Session, error) {
16 | session, ok := m.sessions[id]
17 | if !ok {
18 | return Session{}, errors.New("session not found")
19 | }
20 |
21 | return session, nil
22 | }
23 |
24 | func (m *memoryStore) Set(id string, session Session) error {
25 | m.sessions[id] = session
26 | return nil
27 | }
28 |
--------------------------------------------------------------------------------
/showcases/gloc/examples/files.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/hhatto/gocloc"
7 | )
8 |
9 | func main() {
10 | languages := gocloc.NewDefinedLanguages()
11 | options := gocloc.NewClocOptions()
12 | paths := []string{
13 | ".",
14 | }
15 |
16 | processor := gocloc.NewProcessor(languages, options)
17 | result, err := processor.Analyze(paths)
18 | if err != nil {
19 | fmt.Printf("gocloc fail. error: %v\n", err)
20 | return
21 | }
22 |
23 | for _, item := range result.Files {
24 | fmt.Println(item)
25 | }
26 | fmt.Println(result.Total)
27 | fmt.Printf("%+v", result)
28 | }
29 |
--------------------------------------------------------------------------------
/showcases/db/database/query.go:
--------------------------------------------------------------------------------
1 | package database
2 |
3 | import (
4 | "database/sql"
5 | "fmt"
6 |
7 | _ "github.com/go-sql-driver/mysql"
8 | )
9 |
10 | func Query(db *sql.DB) error {
11 | name := "Aaron"
12 | rows, err := db.Query("SELECT name,
13 | created FROM example where name=?", name)
14 | if err != nil {
15 | return err
16 | }
17 | defer rows.Close()
18 | for rows.Next() {
19 | var e Example
20 | if err := rows.Scan(&e.Name, &e.Created); err != nil {
21 | return err
22 | }
23 | fmt.Printf("Results:\n\tName: %s\n\tCreated: %v\n",
24 | e.Name, e.Created)
25 | }
26 | return rows.Err()
27 | }
28 |
--------------------------------------------------------------------------------
/boilerplates/standards-layout/test/README.md:
--------------------------------------------------------------------------------
1 | # `/test`
2 |
3 | Additional external test apps and test data. Feel free to structure the `/test` directory anyway you want. For bigger projects it makes sense to have a data subdirectory. For example, you can have `/test/data` or `/test/testdata` if you need Go to ignore what's in that directory. Note that Go will also ignore directories or files that begin with "." or "_", so you have more flexibility in terms of how you name your test data directory.
4 |
5 | Examples:
6 |
7 | * https://github.com/openshift/origin/tree/master/test (test data is in the `/testdata` subdirectory)
8 |
9 |
10 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/migration/000002_add_users.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "users" (
2 | "username" varchar PRIMARY KEY,
3 | "hashed_password" varchar NOT NULL,
4 | "full_name" varchar NOT NULL,
5 | "email" varchar UNIQUE NOT NULL,
6 | "password_changed_at" timestamptz NOT NULL DEFAULT('0001-01-01 00:00:00Z'),
7 | "created_at" timestamptz NOT NULL DEFAULT (now())
8 | );
9 |
10 | ALTER TABLE "accounts" ADD FOREIGN KEY ("owner") REFERENCES "users" ("username");
11 |
12 | -- CREATE UNIQUE INDEX ON "accounts" ("owner", "currency");
13 | ALTER TABLE "accounts" ADD CONSTRAINT "owner_currency_key" UNIQUE ("owner", "currency");
14 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/proto/rpc_login_user.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package pb;
4 |
5 | import "user.proto";
6 | import "google/protobuf/timestamp.proto";
7 |
8 | option go_package = "github.com/techschool/simplebank/pb";
9 |
10 | message LoginUserRequest {
11 | string username = 1;
12 | string password = 2;
13 | }
14 |
15 | message LoginUserResponse {
16 | User user = 1;
17 | string session_id = 2;
18 | string access_token = 3;
19 | string refresh_token = 4;
20 | google.protobuf.Timestamp access_token_expires_at = 5;
21 | google.protobuf.Timestamp refresh_token_expires_at = 6;
22 | }
23 |
--------------------------------------------------------------------------------
/showcases/gloc/examples/languages.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/hhatto/gocloc"
7 | )
8 |
9 | func main() {
10 | languages := gocloc.NewDefinedLanguages()
11 | options := gocloc.NewClocOptions()
12 | paths := []string{
13 | ".",
14 | }
15 |
16 | processor := gocloc.NewProcessor(languages, options)
17 | result, err := processor.Analyze(paths)
18 | if err != nil {
19 | fmt.Printf("gocloc fail. error: %v\n", err)
20 | return
21 | }
22 |
23 | for _, lang := range result.Languages {
24 | fmt.Println(lang)
25 | }
26 | fmt.Println(result.Total)
27 | fmt.Printf("%+v", result)
28 | }
29 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/sqlc/main_test.go:
--------------------------------------------------------------------------------
1 | package db
2 |
3 | import (
4 | "context"
5 | "log"
6 | "os"
7 | "testing"
8 |
9 | "github.com/jackc/pgx/v5/pgxpool"
10 | "github.com/techschool/simplebank/util"
11 | )
12 |
13 | var testStore Store
14 |
15 | func TestMain(m *testing.M) {
16 | config, err := util.LoadConfig("../..")
17 | if err != nil {
18 | log.Fatal("cannot load config:", err)
19 | }
20 |
21 | connPool, err := pgxpool.New(context.Background(), config.DBSource)
22 | if err != nil {
23 | log.Fatal("cannot connect to db:", err)
24 | }
25 |
26 | testStore = NewStore(connPool)
27 | os.Exit(m.Run())
28 | }
29 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/eks/ingress-http.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: networking.k8s.io/v1
2 | kind: Ingress
3 | metadata:
4 | name: simple-bank-ingress-http
5 | annotations:
6 | cert-manager.io/cluster-issuer: letsencrypt
7 | spec:
8 | ingressClassName: nginx
9 | rules:
10 | - host: "api.simplebanktest.com"
11 | http:
12 | paths:
13 | - pathType: Prefix
14 | path: "/"
15 | backend:
16 | service:
17 | name: simple-bank-api-service
18 | port:
19 | number: 80
20 | tls:
21 | - hosts:
22 | - api.simplebanktest.com
23 | secretName: simple-bank-api-cert
24 |
--------------------------------------------------------------------------------
/showcases/db/redis/sort.go:
--------------------------------------------------------------------------------
1 | package redis
2 |
3 | import (
4 | "fmt"
5 |
6 | redis "gopkg.in/redis.v5"
7 | )
8 |
9 | func Sort() error {
10 | conn, err := Setup()
11 | if err != nil {
12 | return err
13 | }
14 |
15 | if err := conn.LPush("list", 1).Err(); err != nil {
16 | return err
17 | }
18 | if err := conn.LPush("list", 3).Err(); err != nil {
19 | return err
20 | }
21 | if err := conn.LPush("list", 2).Err(); err != nil {
22 | return err
23 | }
24 |
25 | res, err := conn.Sort("list", redis.Sort{Order: "ASC"}).Result()
26 | if err != nil {
27 | return err
28 | }
29 | fmt.Println(res)
30 | conn.Del("list")
31 | return nil
32 | }
33 |
--------------------------------------------------------------------------------
/showcases/gloc/utils_test.go:
--------------------------------------------------------------------------------
1 | package gocloc
2 |
3 | import "testing"
4 |
5 | func TestContainComments(t *testing.T) {
6 | line := "/* hoge */"
7 | st := "/*"
8 | ed := "*/"
9 | if containComments(line, st, ed) {
10 | t.Errorf("invalid")
11 | }
12 |
13 | line = "/* comment"
14 | if !containComments(line, st, ed) {
15 | t.Errorf("invalid")
16 | }
17 | }
18 |
19 | func TestCheckMD5SumIgnore(t *testing.T) {
20 | fileCache := make(map[string]struct{})
21 |
22 | if checkMD5Sum("./utils_test.go", fileCache) {
23 | t.Errorf("invalid sequence")
24 | }
25 | if !checkMD5Sum("./utils_test.go", fileCache) {
26 | t.Errorf("invalid sequence")
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/showcases/go-boot/hook.go:
--------------------------------------------------------------------------------
1 | package go_boot
2 |
3 | import (
4 | "net"
5 | "sync"
6 |
7 | "github.com/gorilla/websocket"
8 | )
9 |
10 | // fix panic as websocket concurrency write
11 | type webSocketConn struct {
12 | mutex sync.Mutex
13 | conn *websocket.Conn
14 | }
15 |
16 | func (ws *webSocketConn) WriteMessage(messageType int, data []byte) error {
17 | ws.mutex.Lock()
18 | err := ws.conn.WriteMessage(messageType, data)
19 | ws.mutex.Unlock()
20 |
21 | return err
22 | }
23 |
24 | func (ws *webSocketConn) LocalAddr() net.Addr {
25 | return ws.conn.LocalAddr()
26 | }
27 |
28 | func (ws *webSocketConn) RemoteAddr() net.Addr {
29 | return ws.conn.RemoteAddr()
30 | }
31 |
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/api/controller/profile_controller.go:
--------------------------------------------------------------------------------
1 | package controller
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/domain"
7 | "github.com/gin-gonic/gin"
8 | )
9 |
10 | type ProfileController struct {
11 | ProfileUsecase domain.ProfileUsecase
12 | }
13 |
14 | func (pc *ProfileController) Fetch(c *gin.Context) {
15 | userID := c.GetString("x-user-id")
16 |
17 | profile, err := pc.ProfileUsecase.GetProfileByID(c, userID)
18 | if err != nil {
19 | c.JSON(http.StatusInternalServerError, domain.ErrorResponse{Message: err.Error()})
20 | return
21 | }
22 |
23 | c.JSON(http.StatusOK, profile)
24 | }
25 |
--------------------------------------------------------------------------------
/boilerplates/go-clean-architecture/pkg/user/repository.go:
--------------------------------------------------------------------------------
1 | package user
2 |
3 | import (
4 | "context"
5 | )
6 |
7 | type Repository interface {
8 | FindByID(ctx context.Context, id uint) (*User, error)
9 |
10 | BuildProfile(ctx context.Context, user *User) (*User, error)
11 |
12 | CreateMinimal(ctx context.Context, email, password, phoneNumber string) (*User, error)
13 |
14 | FindByEmailAndPassword(ctx context.Context, email, password string) (*User, error)
15 |
16 | FindByEmail(ctx context.Context, email string) (*User, error)
17 |
18 | DoesEmailExist(ctx context.Context, email string) (bool, error)
19 |
20 | ChangePassword(ctx context.Context, email, password string) error
21 | }
22 |
--------------------------------------------------------------------------------
/boilerplates/go-clean-architecture/pkg/admin/repository.go:
--------------------------------------------------------------------------------
1 | package admin
2 |
3 | import (
4 | "context"
5 | )
6 |
7 | type Repository interface {
8 | FindByID(ctx context.Context, id uint) (*Admin, error)
9 |
10 | BuildProfile(ctx context.Context, user *Admin) (*Admin, error)
11 |
12 | CreateMinimal(ctx context.Context, email, password, phoneNumber string) (*Admin, error)
13 |
14 | FindByEmailAndPassword(ctx context.Context, email, password string) (*Admin, error)
15 |
16 | FindByEmail(ctx context.Context, email string) (*Admin, error)
17 |
18 | DoesEmailExist(ctx context.Context, email string) (bool, error)
19 |
20 | ChangePassword(ctx context.Context, email, password string) error
21 | }
22 |
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/cmd/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "time"
5 |
6 | routeV1 "github.com/amitshekhariitbhu/go-backend-clean-architecture/api/route/v1"
7 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/bootstrap"
8 | "github.com/gin-gonic/gin"
9 | )
10 |
11 | func main() {
12 |
13 | app := bootstrap.App()
14 |
15 | env := app.Env
16 |
17 | db := app.Mongo.Database(env.DBName)
18 | defer app.CloseDBConnection()
19 |
20 | timeout := time.Duration(env.ContextTimeout) * time.Second
21 |
22 | gin := gin.Default()
23 |
24 | routerV1 := gin.Group("v1")
25 |
26 | routeV1.Setup(env, timeout, db, routerV1)
27 |
28 | gin.Run(env.ServerAddress)
29 | }
30 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/api/main_test.go:
--------------------------------------------------------------------------------
1 | package api
2 |
3 | import (
4 | "os"
5 | "testing"
6 | "time"
7 |
8 | "github.com/gin-gonic/gin"
9 | "github.com/stretchr/testify/require"
10 | db "github.com/techschool/simplebank/db/sqlc"
11 | "github.com/techschool/simplebank/util"
12 | )
13 |
14 | func newTestServer(t *testing.T, store db.Store) *Server {
15 | config := util.Config{
16 | TokenSymmetricKey: util.RandomString(32),
17 | AccessTokenDuration: time.Minute,
18 | }
19 |
20 | server, err := NewServer(config, store)
21 | require.NoError(t, err)
22 |
23 | return server
24 | }
25 |
26 | func TestMain(m *testing.M) {
27 | gin.SetMode(gin.TestMode)
28 |
29 | os.Exit(m.Run())
30 | }
31 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/eks/deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: simple-bank-api-deployment
5 | labels:
6 | app: simple-bank-api
7 | spec:
8 | replicas: 2
9 | selector:
10 | matchLabels:
11 | app: simple-bank-api
12 | template:
13 | metadata:
14 | labels:
15 | app: simple-bank-api
16 | spec:
17 | containers:
18 | - name: simple-bank-api
19 | image: 760486049168.dkr.ecr.eu-west-1.amazonaws.com/simplebank:latest
20 | imagePullPolicy: Always
21 | ports:
22 | - containerPort: 8080
23 | name: http-server
24 | - containerPort: 9090
25 | name: grpc-server
26 |
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/domain/login.go:
--------------------------------------------------------------------------------
1 | package domain
2 |
3 | import (
4 | "context"
5 | )
6 |
7 | type LoginRequest struct {
8 | Email string `form:"email" binding:"required,email"`
9 | Password string `form:"password" binding:"required"`
10 | }
11 |
12 | type LoginResponse struct {
13 | AccessToken string `json:"accessToken"`
14 | RefreshToken string `json:"refreshToken"`
15 | }
16 |
17 | type LoginUsecase interface {
18 | GetUserByEmail(c context.Context, email string) (User, error)
19 | CreateAccessToken(user *User, secret string, expiry int) (accessToken string, err error)
20 | CreateRefreshToken(user *User, secret string, expiry int) (refreshToken string, err error)
21 | }
22 |
--------------------------------------------------------------------------------
/boilerplates/go-backend-clean-architecture/domain/user.go:
--------------------------------------------------------------------------------
1 | package domain
2 |
3 | import (
4 | "context"
5 |
6 | "go.mongodb.org/mongo-driver/bson/primitive"
7 | )
8 |
9 | const (
10 | CollectionUser = "users"
11 | )
12 |
13 | type User struct {
14 | ID primitive.ObjectID `bson:"_id"`
15 | Name string `bson:"name"`
16 | Email string `bson:"email"`
17 | Password string `bson:"password"`
18 | }
19 |
20 | type UserRepository interface {
21 | Create(c context.Context, user *User) error
22 | Fetch(c context.Context) ([]User, error)
23 | GetByEmail(c context.Context, email string) (User, error)
24 | GetByID(c context.Context, id string) (User, error)
25 | }
26 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/db/sqlc/tx_create_user.go:
--------------------------------------------------------------------------------
1 | package db
2 |
3 | import "context"
4 |
5 | type CreateUserTxParams struct {
6 | CreateUserParams
7 | AfterCreate func(user User) error
8 | }
9 |
10 | type CreateUserTxResult struct {
11 | User User
12 | }
13 |
14 | func (store *SQLStore) CreateUserTx(ctx context.Context, arg CreateUserTxParams) (CreateUserTxResult, error) {
15 | var result CreateUserTxResult
16 |
17 | err := store.execTx(ctx, func(q *Queries) error {
18 | var err error
19 |
20 | result.User, err = q.CreateUser(ctx, arg.CreateUserParams)
21 | if err != nil {
22 | return err
23 | }
24 |
25 | return arg.AfterCreate(result.User)
26 | })
27 |
28 | return result, err
29 | }
30 |
--------------------------------------------------------------------------------
/showcases/2024~simplebank/doc/swagger/swagger-initializer.js:
--------------------------------------------------------------------------------
1 | window.onload = function() {
2 | //
This is a test message from Tech School
24 | ` 25 | to := []string{"techschool.guru@gmail.com"} 26 | attachFiles := []string{"../README.md"} 27 | 28 | err = sender.SendEmail(subject, content, to, nil, nil, attachFiles) 29 | require.NoError(t, err) 30 | } 31 | -------------------------------------------------------------------------------- /showcases/2024~simplebank/db/sqlc/store.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/jackc/pgx/v5/pgxpool" 7 | ) 8 | 9 | // Store defines all functions to execute db queries and transactions 10 | type Store interface { 11 | Querier 12 | TransferTx(ctx context.Context, arg TransferTxParams) (TransferTxResult, error) 13 | CreateUserTx(ctx context.Context, arg CreateUserTxParams) (CreateUserTxResult, error) 14 | VerifyEmailTx(ctx context.Context, arg VerifyEmailTxParams) (VerifyEmailTxResult, error) 15 | } 16 | 17 | // SQLStore provides all functions to execute SQL queries and transactions 18 | type SQLStore struct { 19 | connPool *pgxpool.Pool 20 | *Queries 21 | } 22 | 23 | // NewStore creates a new store 24 | func NewStore(connPool *pgxpool.Pool) Store { 25 | return &SQLStore{ 26 | connPool: connPool, 27 | Queries: New(connPool), 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /showcases/db/redis/cmd/pserver/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "log" 6 | 7 | redis "gopkg.in/redis.v4" 8 | ) 9 | 10 | var task string 11 | 12 | func init() { 13 | flag.StringVar(&task, "task", "", "task to be handled by client") 14 | } 15 | 16 | func main() { 17 | flag.Parse() 18 | 19 | if task == "" { 20 | log.Fatal("Task must not be empty") 21 | } 22 | 23 | client := redis.NewClient(&redis.Options{ 24 | Addr: "localhost:6379", 25 | Password: "", // no password set 26 | DB: 0, // use default DB 27 | }) 28 | 29 | _, err := client.Ping().Result() 30 | if err != nil { 31 | log.Fatalf("Failed to ping Redis: %v", err) 32 | } 33 | 34 | if err := client.Publish("pubsub-key", task).Err(); err != nil { 35 | log.Fatalf("Failed to put stuff into queue: %v", err) 36 | } 37 | log.Printf("'%v' task put into queue", task) 38 | } 39 | -------------------------------------------------------------------------------- /showcases/db/redis/cmd/qserver/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "log" 6 | 7 | redis "gopkg.in/redis.v4" 8 | ) 9 | 10 | var task string 11 | 12 | func init() { 13 | flag.StringVar(&task, "task", "", "task to be handled by client") 14 | } 15 | 16 | func main() { 17 | flag.Parse() 18 | 19 | if task == "" { 20 | log.Fatal("Task must not be empty") 21 | } 22 | 23 | client := redis.NewClient(&redis.Options{ 24 | Addr: "localhost:6379", 25 | Password: "", // no password set 26 | DB: 0, // use default DB 27 | }) 28 | 29 | _, err := client.Ping().Result() 30 | if err != nil { 31 | log.Fatalf("Failed to ping Redis: %v", err) 32 | } 33 | 34 | if err := client.RPush("queue-key", task).Err(); err != nil { 35 | log.Fatalf("Failed to put stuff into queue: %v", err) 36 | } 37 | log.Printf("'%v' task put into queue", task) 38 | } 39 | -------------------------------------------------------------------------------- /showcases/2024~simplebank/db/query/account.sql: -------------------------------------------------------------------------------- 1 | -- name: CreateAccount :one 2 | INSERT INTO accounts ( 3 | owner, 4 | balance, 5 | currency 6 | ) VALUES ( 7 | $1, $2, $3 8 | ) RETURNING *; 9 | 10 | -- name: GetAccount :one 11 | SELECT * FROM accounts 12 | WHERE id = $1 LIMIT 1; 13 | 14 | -- name: GetAccountForUpdate :one 15 | SELECT * FROM accounts 16 | WHERE id = $1 LIMIT 1 17 | FOR NO KEY UPDATE; 18 | 19 | -- name: ListAccounts :many 20 | SELECT * FROM accounts 21 | WHERE owner = $1 22 | ORDER BY id 23 | LIMIT $2 24 | OFFSET $3; 25 | 26 | -- name: UpdateAccount :one 27 | UPDATE accounts 28 | SET balance = $2 29 | WHERE id = $1 30 | RETURNING *; 31 | 32 | -- name: AddAccountBalance :one 33 | UPDATE accounts 34 | SET balance = balance + sqlc.arg(amount) 35 | WHERE id = sqlc.arg(id) 36 | RETURNING *; 37 | 38 | -- name: DeleteAccount :exec 39 | DELETE FROM accounts 40 | WHERE id = $1; 41 | -------------------------------------------------------------------------------- /showcases/go-boot/utils/codec/codec.go: -------------------------------------------------------------------------------- 1 | package codec 2 | 3 | import "fmt" 4 | 5 | const ( 6 | JSON = "text/json" 7 | PROTOBUF = "text/protobuf" 8 | String = "text/string" 9 | XML = "text/xml" 10 | ) 11 | 12 | type Coder interface { 13 | Encoder(data interface{}) ([]byte, error) 14 | Decoder(data []byte, v interface{}) error 15 | } 16 | 17 | var adapters = make(map[string]Coder) 18 | 19 | func Register(name string, adapter Coder) { 20 | if adapter == nil { 21 | panic("codec: register adapter is nil") 22 | } 23 | 24 | if _, ok := adapters["name"]; ok { 25 | panic("codec: register called twice for adapter " + name) 26 | } 27 | 28 | adapters[name] = adapter 29 | } 30 | 31 | func NewCoder(adapterName string) (Coder, error) { 32 | if v, ok := adapters[adapterName]; ok { 33 | return v, nil 34 | } 35 | 36 | return nil, fmt.Errorf("codec: unknown adapter name %q (forgot to import?)", adapterName) 37 | } 38 | -------------------------------------------------------------------------------- /boilerplates/go-backend-clean-architecture/api/route/v1/profile_route.go: -------------------------------------------------------------------------------- 1 | package route 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/api/controller" 7 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/bootstrap" 8 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/domain" 9 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/mongo" 10 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/repository" 11 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/usecase" 12 | "github.com/gin-gonic/gin" 13 | ) 14 | 15 | func NewProfileRouter(env *bootstrap.Env, timeout time.Duration, db mongo.Database, group *gin.RouterGroup) { 16 | ur := repository.NewUserRepository(db, domain.CollectionUser) 17 | pc := &controller.ProfileController{ 18 | ProfileUsecase: usecase.NewProfileUsecase(ur, timeout), 19 | } 20 | group.GET("/profile", pc.Fetch) 21 | } 22 | -------------------------------------------------------------------------------- /boilerplates/go-backend-clean-architecture/usecase/profile_usecase.go: -------------------------------------------------------------------------------- 1 | package usecase 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/domain" 8 | ) 9 | 10 | type profileUsecase struct { 11 | userRepository domain.UserRepository 12 | contextTimeout time.Duration 13 | } 14 | 15 | func NewProfileUsecase(userRepository domain.UserRepository, timeout time.Duration) domain.ProfileUsecase { 16 | return &profileUsecase{ 17 | userRepository: userRepository, 18 | contextTimeout: timeout, 19 | } 20 | } 21 | 22 | func (pu *profileUsecase) GetProfileByID(c context.Context, userID string) (*domain.Profile, error) { 23 | ctx, cancel := context.WithTimeout(c, pu.contextTimeout) 24 | defer cancel() 25 | 26 | user, err := pu.userRepository.GetByID(ctx, userID) 27 | if err != nil { 28 | return nil, err 29 | } 30 | 31 | return &domain.Profile{Name: user.Name, Email: user.Email}, nil 32 | } 33 | -------------------------------------------------------------------------------- /boilerplates/go-backend-clean-architecture/api/route/v1/login_route.go: -------------------------------------------------------------------------------- 1 | package route 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/api/controller" 7 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/bootstrap" 8 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/domain" 9 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/mongo" 10 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/repository" 11 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/usecase" 12 | "github.com/gin-gonic/gin" 13 | ) 14 | 15 | func NewLoginRouter(env *bootstrap.Env, timeout time.Duration, db mongo.Database, group *gin.RouterGroup) { 16 | ur := repository.NewUserRepository(db, domain.CollectionUser) 17 | lc := &controller.LoginController{ 18 | LoginUsecase: usecase.NewLoginUsecase(ur, timeout), 19 | Env: env, 20 | } 21 | group.POST("/login", lc.Login) 22 | } 23 | -------------------------------------------------------------------------------- /showcases/go-boot/retry.go: -------------------------------------------------------------------------------- 1 | package go_boot 2 | 3 | import ( 4 | "sync" 5 | "time" 6 | ) 7 | 8 | var ( 9 | rt *ReTry 10 | once sync.Once 11 | ) 12 | 13 | type ReTry struct { 14 | items sync.Map 15 | timeout time.Duration 16 | } 17 | 18 | type Item struct { 19 | Channel string 20 | Ctx Context 21 | Value interface{} 22 | } 23 | 24 | func NewRetry(timeout time.Duration) *ReTry { 25 | once.Do(func() { 26 | rt = &ReTry{items: sync.Map{}, timeout: timeout} 27 | }) 28 | 29 | return rt 30 | } 31 | 32 | func (rt *ReTry) Put(key interface{}, value *Item) { 33 | rt.items.Store(key, value) 34 | 35 | go func(rt *ReTry) { 36 | <-time.NewTimer(rt.timeout).C 37 | if v, ok := rt.items.Load(key); ok { 38 | if i, ok := v.(*Item); ok { 39 | i.Ctx.Write(i.Channel, i.Value) 40 | rt.Delete(key) 41 | } 42 | } 43 | 44 | return 45 | }(rt) 46 | } 47 | 48 | func (rt *ReTry) Delete(key interface{}) { 49 | rt.items.Delete(key) 50 | } 51 | -------------------------------------------------------------------------------- /boilerplates/go-backend-clean-architecture/api/route/v1/task_route.go: -------------------------------------------------------------------------------- 1 | package route 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/api/controller" 7 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/bootstrap" 8 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/domain" 9 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/mongo" 10 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/repository" 11 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/usecase" 12 | "github.com/gin-gonic/gin" 13 | ) 14 | 15 | func NewTaskRouter(env *bootstrap.Env, timeout time.Duration, db mongo.Database, group *gin.RouterGroup) { 16 | tr := repository.NewTaskRepository(db, domain.CollectionTask) 17 | tc := &controller.TaskController{ 18 | TaskUsecase: usecase.NewTaskUsecase(tr, timeout), 19 | } 20 | group.GET("/task", tc.Fetch) 21 | group.POST("/task", tc.Create) 22 | } 23 | -------------------------------------------------------------------------------- /boilerplates/go-backend-clean-architecture/api/route/v1/signup_route.go: -------------------------------------------------------------------------------- 1 | package route 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/api/controller" 7 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/bootstrap" 8 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/domain" 9 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/mongo" 10 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/repository" 11 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/usecase" 12 | "github.com/gin-gonic/gin" 13 | ) 14 | 15 | func NewSignupRouter(env *bootstrap.Env, timeout time.Duration, db mongo.Database, group *gin.RouterGroup) { 16 | ur := repository.NewUserRepository(db, domain.CollectionUser) 17 | sc := controller.SignupController{ 18 | SignupUsecase: usecase.NewSignupUsecase(ur, timeout), 19 | Env: env, 20 | } 21 | group.POST("/signup", sc.Signup) 22 | } 23 | -------------------------------------------------------------------------------- /showcases/2024~simplebank/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3.9" 2 | services: 3 | postgres: 4 | image: postgres:14-alpine 5 | environment: 6 | - POSTGRES_USER=root 7 | - POSTGRES_PASSWORD=secret 8 | - POSTGRES_DB=simple_bank 9 | ports: 10 | - "5432:5432" 11 | volumes: 12 | - data-volume:/var/lib/postgresql/data 13 | redis: 14 | image: redis:7-alpine 15 | api: 16 | build: 17 | context: . 18 | dockerfile: Dockerfile 19 | ports: 20 | - "8080:8080" 21 | - "9090:9090" 22 | environment: 23 | - DB_SOURCE=postgresql://root:secret@postgres:5432/simple_bank?sslmode=disable 24 | - REDIS_ADDRESS=redis:6379 25 | depends_on: 26 | - postgres 27 | - redis 28 | entrypoint: 29 | [ 30 | "/app/wait-for.sh", 31 | "postgres:5432", 32 | "--", 33 | "/app/start.sh" 34 | ] 35 | command: [ "/app/main" ] 36 | volumes: 37 | data-volume: 38 | -------------------------------------------------------------------------------- /showcases/2024~simplebank/gapi/error.go: -------------------------------------------------------------------------------- 1 | package gapi 2 | 3 | import ( 4 | "google.golang.org/genproto/googleapis/rpc/errdetails" 5 | "google.golang.org/grpc/codes" 6 | "google.golang.org/grpc/status" 7 | ) 8 | 9 | func fieldViolation(field string, err error) *errdetails.BadRequest_FieldViolation { 10 | return &errdetails.BadRequest_FieldViolation{ 11 | Field: field, 12 | Description: err.Error(), 13 | } 14 | } 15 | 16 | func invalidArgumentError(violations []*errdetails.BadRequest_FieldViolation) error { 17 | badRequest := &errdetails.BadRequest{FieldViolations: violations} 18 | statusInvalid := status.New(codes.InvalidArgument, "invalid parameters") 19 | 20 | statusDetails, err := statusInvalid.WithDetails(badRequest) 21 | if err != nil { 22 | return statusInvalid.Err() 23 | } 24 | 25 | return statusDetails.Err() 26 | } 27 | 28 | func unauthenticatedError(err error) error { 29 | return status.Errorf(codes.Unauthenticated, "unauthorized: %s", err) 30 | } 31 | -------------------------------------------------------------------------------- /showcases/golang-gin-realworld-example-app/MOBILE_INSTRUCTIONS.md: -------------------------------------------------------------------------------- 1 | > *Note: Delete this file before publishing your app!* 2 | 3 | # [Mobile Icons (iOS/Android)](https://github.com/gothinkster/realworld/tree/master/spec/mobile_icons) 4 | 5 | ### Using the hosted API 6 | 7 | Simply point your [API requests](https://github.com/gothinkster/realworld/tree/master/api) to `https://conduit.productionready.io/api` and you're good to go! 8 | 9 | ### Styles/Templates 10 | 11 | Unfortunately, there isn't a common way for us to reuse & share styles/templates for cross-platform mobile apps. 12 | 13 | Instead, we recommend using the Medium.com [iOS](https://itunes.apple.com/us/app/medium/id828256236?mt=8) and [Android](https://play.google.com/store/apps/details?id=com.medium.reader&hl=en) apps as a "north star" regarding general UI functionality/layout, but try not to go too overboard otherwise it will unnecessarily complicate your codebase (in other words, [KISS](https://en.wikipedia.org/wiki/KISS_principle) :) 14 | -------------------------------------------------------------------------------- /boilerplates/go-backend-clean-architecture/api/route/v1/refresh_token_route.go: -------------------------------------------------------------------------------- 1 | package route 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/api/controller" 7 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/bootstrap" 8 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/domain" 9 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/mongo" 10 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/repository" 11 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/usecase" 12 | "github.com/gin-gonic/gin" 13 | ) 14 | 15 | func NewRefreshTokenRouter(env *bootstrap.Env, timeout time.Duration, db mongo.Database, group *gin.RouterGroup) { 16 | ur := repository.NewUserRepository(db, domain.CollectionUser) 17 | rtc := &controller.RefreshTokenController{ 18 | RefreshTokenUsecase: usecase.NewRefreshTokenUsecase(ur, timeout), 19 | Env: env, 20 | } 21 | group.POST("/refresh", rtc.RefreshToken) 22 | } 23 | -------------------------------------------------------------------------------- /boilerplates/go-backend-clean-architecture/usecase/task_usecase.go: -------------------------------------------------------------------------------- 1 | package usecase 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "github.com/amitshekhariitbhu/go-backend-clean-architecture/domain" 8 | ) 9 | 10 | type taskUsecase struct { 11 | taskRepository domain.TaskRepository 12 | contextTimeout time.Duration 13 | } 14 | 15 | func NewTaskUsecase(taskRepository domain.TaskRepository, timeout time.Duration) domain.TaskUsecase { 16 | return &taskUsecase{ 17 | taskRepository: taskRepository, 18 | contextTimeout: timeout, 19 | } 20 | } 21 | 22 | func (tu *taskUsecase) Create(c context.Context, task *domain.Task) error { 23 | ctx, cancel := context.WithTimeout(c, tu.contextTimeout) 24 | defer cancel() 25 | return tu.taskRepository.Create(ctx, task) 26 | } 27 | 28 | func (tu *taskUsecase) FetchByUserID(c context.Context, userID string) ([]domain.Task, error) { 29 | ctx, cancel := context.WithTimeout(c, tu.contextTimeout) 30 | defer cancel() 31 | return tu.taskRepository.FetchByUserID(ctx, userID) 32 | } 33 | -------------------------------------------------------------------------------- /showcases/go-boot/utils/codec/string.go: -------------------------------------------------------------------------------- 1 | package codec 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type StringCoder struct{} 8 | 9 | func (c *StringCoder) Encoder(data interface{}) ([]byte, error) { 10 | switch t := data.(type) { 11 | case string: 12 | return []byte(t), nil 13 | case *string: 14 | return []byte(*t), nil 15 | case []byte: 16 | return t, nil 17 | case *[]byte: 18 | return *t, nil 19 | default: 20 | return nil, fmt.Errorf("%T can not be directly converted to []byte", t) 21 | } 22 | } 23 | 24 | func (c *StringCoder) Decoder(data []byte, v interface{}) error { 25 | switch t := v.(type) { 26 | case string: 27 | return fmt.Errorf("expect %T but %T", &t, t) 28 | case *string: 29 | *t = string(data) 30 | case []byte: 31 | return fmt.Errorf("expect %T but %T", &t, t) 32 | case *[]byte: 33 | *t = data 34 | default: 35 | return fmt.Errorf("[]byte can not be directly converted to %T", t) 36 | } 37 | 38 | return nil 39 | } 40 | 41 | func init() { 42 | Register(String, &StringCoder{}) 43 | } 44 | -------------------------------------------------------------------------------- /showcases/go-boot/cmd/server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "time" 7 | 8 | goBoot "github.com/wxyyxc1992/go-boot" 9 | "github.com/wxyyxc1992/go-boot/plugins" 10 | ) 11 | 12 | const timeout = 60 * 6 * time.Second 13 | 14 | func main() { 15 | server := goBoot.NewServer( 16 | goBoot.Config{ 17 | Timeout: timeout, 18 | PluginForPacketSender: []goBoot.PacketPlugin{ 19 | &plugins.Encryption{}, 20 | &plugins.Debug{Sender: true}, 21 | }, 22 | PluginForPacketReceiver: []goBoot.PacketPlugin{ 23 | &plugins.Decryption{}, 24 | &plugins.Debug{Sender: false}, 25 | }, 26 | }) 27 | 28 | router := goBoot.NewRouter() 29 | router.NSRouter("/v1", 30 | router.NSRoute( 31 | "/healthy", 32 | goBoot.HandlerFunc(func(ctx goBoot.Context) { 33 | fmt.Println(ctx.GetRequestProperty("sid")) 34 | ctx.Success(map[string]interface{}{"keepalive": true}) 35 | }), 36 | ), 37 | ) 38 | 39 | server.BindRouter(router) 40 | log.Fatal(server.RunTCP("tcp", "127.0.0.1:8080")) 41 | } 42 | -------------------------------------------------------------------------------- /showcases/minitask/src/logger/logger.go: -------------------------------------------------------------------------------- 1 | package logger 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "time" 7 | ) 8 | 9 | var DEBUG_LEVEL = 2 10 | var LOG_FILE = os.Args[4] + "log_" + GetTime() + ".log" 11 | 12 | /** 13 | * Logs message in a file 14 | * 15 | * @param string message Message content 16 | * @param int level Level of the message 1, 2 , 3 etc 17 | * @author Waqar Alamgir