A backend-focused Notes Application built with Go (Gin) and PostgreSQL, implementing authentication, secure password handling, and CRUD operations for notes. Designed with clear separation of concerns (controller → service → database).
- Language: Go
- Framework: Gin
- Database: PostgreSQL
- ORM: GORM
- Auth: bcrypt (password hashing)
- Infra: Docker (Postgres)
- Tools: Air (hot reload), Postman
- User Registration
- User Login (bcrypt password verification)
- Secure password storage (hashed, never returned)
- Notes CRUD (per authenticated user)
- Email uniqueness enforced at DB level
- Clean controller–service architecture
- Proper error handling (no silent failures)
.
├── controller/ # HTTP handlers (Gin)
├── service/ # Business logic
├── models/ # GORM models
├── dto/ # Request/response DTOs
├── validator/ # Input validation
├── db/ # Database initialization
├── middleware/ # Auth / logging middleware
├── routes/ # Route registration
├── docker-compose.yml
├── .env
└── main.go
Create a .env file:
DB_URL=postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable
PORT=8000docker-compose up -dgo run main.goOr with hot reload:
airServer will start on:
http://localhost:8000
POST /auth/registerRequest body:
{
"name": "Harsh Kharwar",
"email": "harsh@example.com",
"password": "StrongPass123"
}POST /auth/loginRequest body:
{
"email": "harsh@example.com",
"password": "StrongPass123"
}GET /notes
POST /notes
PUT /notes/:id
DELETE /notes/:idNotes are scoped per authenticated user.
- Passwords are hashed using bcrypt
- No password or hash is ever returned in responses
- Same error message for invalid email/password (prevents enumeration)
- Unique email enforced at database level
- JWT access & refresh tokens
- Auth middleware
- Rate limiting on login
- DTO-based validation everywhere
- Pagination for notes
- Unit tests for services