
The template for this project was taken from the project of Nikolay Tuzov. This project was implemented for the purpose of learning, knowledge SOLID principles and clean architecture. It encourages writing clean and idiomatic Go code.
- RESTful endpoints in the widely accepted format
- Standard CRUD operations of a database table
- JWT-based authentication
- Environment dependent application configuration management
- Structured logging with contextual information
- Error handling with proper error response generation
- Database migration
- Data validation
- Containerizing an application in Docker
- Routing: go-chi
- Database access: pgx
- Database migration: golang-migrate
- Data validation: go-playground validator
- Logging: log/slog
- JWT: jwt-go
- Config reader: cleanv
- Env reader: godotenv

Important
This project is a microservice that works in conjunction with a SSO. For full functionality, you need to have two microservices running.
If this is your first time encountering Go, please follow the instructions to install Go on your computer. The project requires Go 1.21 or above.
Docker is also needed if you want to try the kit without setting up your own database server. The project requires Docker 17.05 or higher for the multi-stage build support.
Also for simple run commands i use Taskfile.
After installing Go, Docker and TaskFile, run the following commands to start experiencing:
## RUN URL-SHORTENER
# download the project
git clone https://github.com/neepooha/url_shortener.git
cd url_shortener
# create config.env with that text:
$ nano config.env {
CONFIG_PATH=./config/local.yaml
POSTGRES_DB=url
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypass
}
# start a PostgreSQL database server in a Docker container
task db-start
# run the RESTful API server
go run ./cmd/url-shortener
## RUN SSO
# download the project
git clone [https://github.com/neepooha/url_shortener.git](https://github.com/neepooha/sso)
cd sso
# create config.env with that text:
$ nano config.env {
CONFIG_PATH=./config/local.yaml
POSTGRES_DB=url
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypass
}
# start a PostgreSQL database server in a Docker container
task db-start
# run the SSO server
go run ./cmd/sso
Also, you can start project in dev mode. For that you need rename in config.env "CONFIG_PATH=./config/local.yaml" to "CONFIG_PATH=./config/dev.yaml" in both projects and run following commads:
# run the RESTful API server with docker-compose
cd url_shortener/
docker compose up --build
# run the SSO server
cd sso/
docker compose up --build
At this time, you have a RESTful API server running at http://localhost:8080 and SSO-grpc Server running at http://localhost:44044. Restful-API server provides the following endpoints:
-
POST /urls
: shortens the link using an alias, or if the alias is not specified, then using a random 6-digit cache. Need authentication -
DELETE /urls/{alias}
: remove link by alias. You need to be an admin -
GET /{alias}
: redirect by alias (all users) -
POST /user
: creates a new admin. You need to be an creator -
DELETE /user
: deletes an admin. You need to be an creator
Project has the following project layout:
url-shortener/
├── cmd/ start of applications of the project
├── config/ configuration files for different environments
├── deployment/ configuration for create daemon in linux
├── internal/ private application and library code
│ ├── app/ application assembly
│ ├── clients/ grpc servrers(only sso) assembly
│ ├── config/ configuration library
│ ├── lib/ additional functions for logging, error handling, migration
│ ├── storage/ storage library
│ └── transport/ handlers and middlewares
│ ├── handlers/ handlres
│ │ ├── admins/ handlres to set/delete admins
│ │ └── url/ handlres to set/delete urls
│ └── middleware/ middlewares
│ ├── auth/ middleware for auth
│ ├── context/ middleware for auth
│ ├── isadmin/ middleware for check is admin user
│ └── logger/ logger for middleware
├── migrations/ migrations
├── .gitignore
└── config.env config for sercret variables
The top level directories cmd
, internal
, lib
are commonly found in other popular Go projects, as explained in
Standard Go Project Layout.
Within internal
package are structured by features in order to achieve the so-called
screaming architecture. For example,
the transport
directory contains the application logic related with the entity feature.
Within each feature package, code are organized in layers (API, service, repository), following the dependency guidelines as described in the clean architecture.
for simple migration you can use the following commands
# For up migrations
task up
# For drop migrations
task drop
# Revert the last database migration.
tasl rollback
The application configuration is represented in internal/config/config.go
. When the application starts,
it loads the configuration from a configuration environment as well as environment variables. The path to the configuration environment
should be in the project root folder.
The config
directory contains the configuration files named after different environments. For example,
config/local.yml
corresponds to the local development environment and is used when running the application
via go run ./cmd/url-shortener
You can keep secrets in local/dev confing, but do not keep secrets in the prud and in the configuration environment. For set secret variable user github secrets and deploy.yaml.