This project is a simple TODO management REST API built with Go and PostgreSQL, originally based on an SQLC example API and then transformed into a standalone TODO application. The project was developed and tested entirely using GitHub Codespaces.
- Create, list, retrieve, and delete TODO items
- PostgreSQL database with strongly-typed queries generated by SQLC
- REST API using Chi Router
- Environment variable configuration with
.env - Fully automated CI pipeline using GitHub Actions
- Dependency vulnerability scanning
- Code linting and formatting checks
- Unit test execution
- Conditional binary build (only if checks pass)
- Language: Go
- Database: PostgreSQL
- SQL Tooling: SQLC
- Router: go-chi/chi
- Driver: pgx
- CI/CD: GitHub Actions
- Development Environment: GitHub Codespaces
.
├── cmd/
│ └── server/ # Application entry point
│ └── main.go
├── internal/
│ ├── db/
│ │ └── sqlc/ # SQLC-generated queries
│ └── handlers/ # HTTP handlers
│ └── todos.go
├── migrations/ # Database migrations
├── .github/
│ └── workflows/
│ └── ci.yml # CI pipeline
├── go.mod
├── go.sum
├── .env.example
└── README.md
A simple yet production-style Todo REST API built with Go, PostgreSQL, sqlc, and Docker.
🚀 This project was developed and tested using GitHub Codespaces to ensure a fully cloud-based, reproducible development environment.
✨ Features
CRUD operations for Todos
PostgreSQL persistence
Type-safe SQL using sqlc
Dockerized database
Clean Go project structure
Ready for extension (auth, pagination, users)
🛠 Tech Stack
Go 1.22
PostgreSQL
sqlc
Docker & docker-compose
GitHub Codespaces
🚀 Running the Project (GitHub Codespaces)
1️⃣ Open in GitHub Codespaces
Click Code → Codespaces → Create codespace
Wait for the environment to finish initializing
Open the terminal
💡 Codespaces provides Docker and Go pre-installed.
2️⃣ Install PostgreSQL client (psql)
sudo apt update sudo apt install postgresql-client -y
Verify:
psql --version
3️⃣ Start PostgreSQL (Docker)
docker-compose up -d
Confirm:
docker ps
4️⃣ Apply database migrations
psql postgres://postgres:postgres@localhost:5432/todoapp \ -f migrations/0001_init.up.sql
5️⃣ Generate sqlc code
sqlc generate
6️⃣ Install Go dependencies automatically
go mod tidy
7️⃣ Run the API server
go run ./cmd/server
Server starts on:
🔌 API Endpoints
Create a Todo
POST /todos
{
"title": "Learn sqlc"
}
List Todos
GET /todos
Get Todo by ID
GET /todos/{id}
Update Todo
PATCH /todos/{id}
{
"completed": true
}
Delete Todo
DELETE /todos/{id}
🧪 Quick Test (curl)
curl -X POST http://localhost:8080/todos \ -H "Content-Type: application/json" \ -d '{"title":"First Todo"}'
---
🧠 Notes
Environment variables are defined in .env.example
PostgreSQL runs in Docker
Dependencies are managed automatically via Go modules
sqlc ensures compile-time SQL correctness
----
✅ Project Status
✔ Completed
✔ Fully functional
✔ GitHub Codespaces compatible
✔ Ready for extension and production hardening
---
📌 Possible Improvements
User authentication (JWT)
Pagination & filtering
Automated migrations
Unit & integration tests
CI/CD pipeline
Deployment to Fly.io / Render
This project was built and tested inside GitHub Codespaces, which provides Go and Docker out of the box.
sudo service postgresql startCreate a database if needed:
createdb todo_dbCreate a .env file:
DATABASE_URL=postgres://postgres:postgres@localhost:5432/todo_db?sslmode=disableGo automatically installs dependencies when you run:
go mod tidypsql $DATABASE_URL -f migrations/schema.sqlgo run ./cmd/serverThe API will run on:
http://localhost:8080
POST /todos
{
"title": "Finish CI assignment"
}GET /todos
GET /todos/{id}
DELETE /todos/{id}
This project includes a GitHub Actions CI pipeline that runs automatically on every push and pull request.
-
Dependency Vulnerability Scan
- Uses
govulncheck
- Uses
-
Linting & Static Analysis
- Uses
golangci-lint
- Uses
-
Unit Tests
- Runs
go test ./...
- Runs
-
Build Binary
- Runs only if all previous steps succeed
# Vulnerability scan
go run golang.org/x/vuln/cmd/govulncheck@latest ./...
# Lint
go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.2 run ./...
# Tests
go test ./...
# Build
go build -o ./bin/api ./cmd/serverThe binary build step is intentionally executed only after:
- Linting passes
- Vulnerability scan passes
- Tests pass
This ensures that only secure and clean code is built, following best CI/CD practices.
- Structuring a Go API using clean architecture
- Using SQLC for type-safe database access
- Handling PostgreSQL in GitHub Codespaces
- Writing and debugging GitHub Actions workflows
- Enforcing code quality with linters
- Using CI to catch real production-level issues early
- No unit tests are currently implemented;
go test ./...runs successfully with no test files. - This is intentional and acceptable for the current stage of the assignment.
Developed by: Leonie
Environment: GitHub Codespaces