This is a test project to generate the short link from the long link you already have. We want to be able to:
- get the short link from the long link
- save the result to database
- redirect from the short link to the long link destination
- get simple UI as HTML page
- check if the long link HTTP valid
We choose Monolith as system arch pattern and Rich Domain Model as software arch pattern. Let us look at some architect points:
Adapters
- HTTP transport with static file server
- SQL or NoSQL database
- JSON logger
- file + env config
Interfaces
- http
- db
- log
- service
Controllers
- http
- db
Services
- redirect from short link to long link
- search the short link if you have a long link
- search the long link if you have a short link
- get ALL link pairs presented in db (test functional)
- check if long link HTTP available
Models
- link pair (string, string)
- compute short link from long link
- unite short link and long link
- check if pair is valid
- layering and hexagonal arch
- standart go project layout (more or less)
- pre-commit hooks and github actions (CI) + docker-compose (CD) + minikube (prod🙃)
- integration tests and unit tests with mocks
- e2e tests with PLY
- HTTPfast(fiber) or HTTPnet(gin) server adapters
- logZero, logSlog or logFprintf logger adapters
- postgreSQL, redis, mongoDB or tarantool db adapters
- OpenAPI Swagger docs
http://localhost:8080/oapi
Libs (https://github.com/)
- caarlos0/env v3.5.0
- joho/godotenv v1.5.1
- rs/zerolog v1.29.0
- gin-gonic/gin v1.9.0
- gin-contrib/static v0.0.1
- gin-contrib/pprof v1.4.0
- valyala/fasthttp v1.45.0
- gofiber/fiber v2.42.0
- stretchr/testify v1.8.2
- gavv/httpexpect v2.15.0
- jackc/pgx v5.4.3
- mongodb/mongo-go-driver v1.12.1
- redis/go-redis v9.2.1
- tarantool/go-tarantool v2.0.0
Tools
- golang v1.21
- golangci-lint v1.51.2
- curl v7.68.0
- ply v3.2.14 (vscode extension)
- apache benchmark v2.3 (apache2-utils)
- docker v24.0.6 + docker-compose v2.21.0
- minikube v1.31.2
Project metrics
- Code size + Repository size
- Package graph (image_packages)
- Control-flow graph (go tool pprof)
- Unit test coverage (go tool cover)
- Lines of code (gcloc, complexity)
- Cyclomatic complexity (gocyclo, complexity)
- Cognitive Complexity (gocognit)
- Halstead complexity (complexity)
- Maintainability index (complexity)
Metrics repos (https://github.com/)
- ManyakRus/image_packages
- JoaoDanielRufino/gcloc
- fzipp/gocyclo
- uudashr/gocognit
- kselnaag/go-complexity-analysis (fork)
More details in: ./script/metrics/
- check if
docker
anddocker-compose
has been installed and works - clone the project
git clone https://github.com/kselnaag/shortlink
- dive into a folder
cd shortlink
- build all localy with
./script/cicd.sh docker-build
- check if
kselnaag/shortlink
built correctly:docker images
- run everything with
./script/cicd.sh compose-app
(mock DB) - if you want to use some DBs pick "compose-pg" or "compose-mg" or "compose-rd" or "compose-tt"
- go to
http://localhost:8080
in your browser and try it
In case of additional flexibility situation change YAML configs in ./script/
guided by ./config/shortlink.env
Kube deploy in ./script/kube/
kselnaag:~/shortlink$ ./script/cicd.sh
CI/CD COMMANDS: style lint test build run start check check-no-lint
itest-tt itest-rd itest-pg itest-mg
docker-gobuilder docker-build docker-up docker-stop
compose-app compose-pg compose-rd compose-mg compose-tt
metrics metrics-graph
EXAMLPE: ./script/cicd.sh build
kselnaag:~/shortlink$ ./script/cicd.sh check
>>_StyleChecking_<<
>>_Linting_<<
>>_UnitTests_<<
ok shortlink/internal/adapter/cfg 1.116s
ok shortlink/internal/adapter/db 1.127s
ok shortlink/internal/adapter/http 1.170s
ok shortlink/internal/adapter/log 1.087s
ok shortlink/internal/model 1.077s
ok shortlink/internal/service 1.114s
>>_Build_<<
>>_AppStart_<<
{"L":"info","T":"2023-10-28T19:21:40.706547797+03:00","H":"localhost:8080","S":"shortlink:http","M":"CfgEnv load config from file: /mnt/e/shortlink/bin/shortlink.env","E":""}
{"L":"info","T":"2023-10-28T19:21:40.706738205+03:00","H":"192.168.49.1:8080","S":"shortlink:http","M":"mock db connected","E":""}
{"L":"info","T":"2023-10-28T19:21:40.706915386+03:00","H":"192.168.49.1:8080","S":"shortlink:http","M":"net/http server opened","E":""}
{"L":"info","T":"2023-10-28T19:21:40.706925122+03:00","H":"192.168.49.1:8080","S":"shortlink:http","M":"shortlink app started","E":""}
>>_HealthCheck_<<
>>_AppClose_<<
{"L":"info","T":"2023-10-28T19:21:41.980603163+03:00","H":"192.168.49.1:8080","S":"shortlink:http","M":"net/http server closed","E":""}
{"L":"info","T":"2023-10-28T19:21:41.980706141+03:00","H":"192.168.49.1:8080","S":"shortlink:http","M":"mock db disconnected","E":""}
{"L":"info","T":"2023-10-28T19:21:41.980712531+03:00","H":"192.168.49.1:8080","S":"shortlink:http","M":"shortlink app stoped","E":""}
>>_Successfull_<<
kselnaag:~/shortlink$ ./script/cicd.sh metrics
>>_TestCoverage_<<
? shortlink/cmd [no test files]
? shortlink/internal [no test files]
ok shortlink/internal/adapter/cfg 0.043s coverage: 53.8% of statements
ok shortlink/internal/adapter/db 0.024s coverage: 0.0% of statements
? shortlink/internal/apptype [no test files]
? shortlink/internal/control [no test files]
? shortlink/web [no test files]
ok shortlink/internal/adapter/http 0.063s coverage: 58.5% of statements
ok shortlink/internal/adapter/log 0.020s coverage: 77.0% of statements
ok shortlink/internal/model 0.017s coverage: 100.0% of statements
ok shortlink/internal/service 0.039s coverage: 71.8% of statements
TOTAL: 72.2%
>>_LinesOfCode_<<
Language | Files | Lines | Blank lines | Comments | Code lines
Golang | 33 | 2515 | 279 | 43 | 2193
Bash | 1 | 362 | 40 | 3 | 319
>>_CyclomaticComplexity_<<
Average: 2.57
>>_CognitiveComplexity_<<
Average: 1.94
>>_ComplexityMetrics_<<
TOTAL LoC: 1849
TOTAL cycloAvg: 2.62609
TOTAL halstVolAvg: 432.956
TOTAL halstDiffAvg: 23.6937
TOTAL maintAvg: 61.0348
>>_Successfull_<<
Control-flow graph (for http://localhost:8080/
)
| gin | gin docs | | zerolog | | tarantool | tarantool docs | | postgres | postgres docs |
| fiber | fiber docs | | godotenv | env | | redis | redis docs | | mongoDB | mongoDB docs |