A simple task management backend application.
I hone my Go knowledge by implementing this system. The goal is to create a simple application but end-to-end. So basically, it will mimic a large scale system design, but with small application.
These are things that I want to implement here.
- Backend Endpoints
- HTTP Handler
- API docs
- Validation and Logging
- Database
- Unit Testing
- Monitoring (prometheus)
- Docker
- CI/CD
- Reverse Proxy (nginx)
- Containers Orchestration (k8s & minikube)
- GraphQL API
- gRPC Layer
- RESTful API: For creating, reading, updating, and deleting tasks.
- Go Fiber Framework: High-performance Go web framework.
- PostgreSQL Database: Robust and reliable database for storing task data.
- GORM: Developer-friendly ORM for Go.
- Swagger Documentation: Interactive API documentation.
- Prometheus & Grafana: For monitoring application metrics.
- Nginx Reverse Proxy: Manages and routes traffic to the application and monitoring services.
- Docker-Compose: For easy setup and deployment of the entire application stack.
- Live Reloading: With Air for a better development experience.
- Kubernetes Deployment: Ready for deployment in a Kubernetes environment.
- Authentication: JWT-based authentication for secure endpoints.
- User-Task Association: Tasks are associated with the user who created them, so users can only manage their own tasks.
To run the application in a development environment using air for live reloading, follow these steps:
-
Clone the repository:
git clone https://github.com/your-username/devtasker.git cd devtasker -
Set up environment variables: Create a
.envfile from the provided.env.exampleand customize it if needed.cp .env.example .env
-
Install dependencies:
go mod tidy
-
Run the application with Air: Make sure you have
airinstalled (go install github.com/cosmtrek/air@latest).air
The application will be running at
http://localhost:3000.
You can run the application in a production-like environment using either Docker Compose or Kubernetes (with Minikube).
-
Set up environment variables: Create
.devtasker.env,.grafana.env, and.postgres.envfrom the provided.env.examplefiles and customize them if needed. -
Run with Docker Compose:
docker-compose up -d
The application will be accessible at
http://localhost.
-
Start Minikube:
minikube start
-
Apply Kubernetes configurations:
kubectl apply -f k8s/
-
Get Minikube IP:
minikube ip
-
Access the services:
- Application:
http://<minikube-ip>:31000 - Swagger Docs:
http://<minikube-ip>:31000/doc - Health Check:
http://<minikube-ip>:31000/health - Grafana:
http://<minikube-ip>:31001 - Prometheus:
http://<minikube-ip>:31002
- Application:
Minikube is used to orchestrate the containerized applications (devtasker, nginx, prometheus, grafana, and postgres). It sets up a single-node Kubernetes cluster where the pods run. Each pod in this setup contains a single container.
The Kubernetes configurations in the k8s/ directory were initially generated by translating the docker-compose.yml file using kompose convert. These configurations were then manually adjusted. Specifically, the type of the nginx, prometheus, and grafana services was changed to NodePort to make them accessible externally. Additionally, the devtasker image was updated to use a public image from Docker Hub.
To easily access the services, you can run minikube service <service-name>, where <service-name> can be nginx, grafana, or prometheus. This command will automatically open the service in your web browser.
All endpoints are prefixed with /api.
| Method | Endpoint | Description |
|---|---|---|
| POST | /auth/register |
Register a new user |
| POST | /auth/login |
Login and get a JWT |
| POST | /task |
Create a new task for the authenticated user |
| GET | /task |
Get all tasks belonging to the authenticated user |
| GET | /task/:id |
Get a specific task by ID |
| PATCH | /task/:id |
Update a specific task |
| DELETE | /task/:id |
Delete a specific task |
- Swagger Docs:
http://localhost/doc - Health Check:
http://localhost/health
- Prometheus:
http://localhost:9090 - Grafana:
http://localhost:3001
Contributions are welcome! Please follow these steps:
- Fork the repository.
- Create a new branch (
git checkout -b feature/your-feature-name). - Make your changes.
- Commit your changes (
git commit -m 'Add some feature'). - Push to the branch (
git push origin feature/your-feature-name). - Open a pull request.