Quotes server is an example of how I normally build an HTTP server.
It started as a solution for a technical assignment and later turned into a showcase. Currently I enhance it ad-hoc, see the list of the project issues for the planned improvements and add your own to challenge me.
For more details on the initial technical requirements, see docs/000_Requirements.md
Please also consult docs/003_Potential_questions_and_answers_to_them.md for additional information on the project.
- Go 1.19+ installed (to run tests, start server or client without Docker)
- Docker installed (to run docker)
- Docker Compose installed (to run docker-compose), v2.0+ is required
- GolangCI-Lint installed (to run linter)
- GNU Make installed (to run Makefile)
NB: make commands tested to work both on GNU Make 3.81 (comes with the latest macOS) and 4.4.1 (the latest version at the moment of writing).
To avoid overcomplicating testing the solution of the project, I used envconfig with some reasonable defaults. You can find them in the config/config.go file for server and in the pkg/client/config.go file for client.
If you would like to set them manually, you can do it via environment variables:
Name | Description | Default Value | Possible Values |
---|---|---|---|
LOG_LEVEL | Log level to use | debug | debug, info, warn, error, fatal |
LOG_FORMAT | Log format to use | console | console, json |
GIN_MODE | Gin mode to use | release | release, debug |
SERVER_PORT | Port to listen on | 8080 | any port you find reasonable |
RATELIMITER_RATE | Rate at which requests are allowed | second | second, minute |
RATELIMITER_LIMIT | Maximum number of requests allowed | 5 | |
RATELIMITER_KEY | Key to use for the ratelimiter | client_ip | client_ip |
CHALLENGE_DIFFICULTY | Difficulty of the proof of work challenge | 20 | 1 to 30 (recommended) |
SALT_LENGTH | Length of the salt | 8 |
Name | Description | Default Value | Possible Values |
---|---|---|---|
LOG_LEVEL | Log level to use | debug | debug, info, warn, error, fatal |
LOG_FORMAT | Log format to use | console | console, json |
SERVER_HOST | Host of the server to connect to | localhost | wherever server is hosted |
SERVER_PORT | Port of the server to connect to | 8080 | whichever port server is listebing on |
REQUEST_PATH | Path of the request to send to the server | /v1/quotes/random | whichever endpoint you want to hit on server |
REQUEST_RATE_PER_SECOND | Number of requests per second to send | 100 | |
REQUEST_COUNT | Number of requests to send to the server | 0 | 0 means "run indefinetily", any positive number would limit that |
make start
make run-server
make run-client
make test
The structure of the project is inspired by Standard Go Project Layout. For more information on the architectural thinking behind this structure, see docs/002_Project_architecture.md.
/ quotes-server
/ .github
/ workflows - GitHub Actions workflows for running CI/CD pipelines
/ build - Dockerfiles for building images
/ cmd - entrypoints for server and client
/ configs - configuration file for server (the client one is in the
/pkg/client
directory)/ deploy - docker-compose file for running server and client
/ docs - documentation files
/ internal - internal packages
/ domain - domain entities, such as models and services, containing business logic
/ storage - storage layer, containing repositories and database models
/ transport - transport layer, containing handlers and middlewares
/ pkg - public packages
/ test/integration - integration tests
I used Conventional Commits for commit messages. I also recommend adhering to TDD (Red-Green-Refactor) principle when contributing.
To run linter, use the following command:
make lint-host
To run tests, use the following command:
make test
For more information, please, refer to /docs directory.
The project is hosted on GitHub and uses GitHub Actions for CI/CD pipelines. For actual infrastructure, see infrastructure repository - link, WIP