A simple Twitter-like API built with Go, PostgreSQL, and JWT authentication.
- 🔐 JWT-based authentication with refresh tokens
- 📝 Create, read, and delete chirps (tweets)
- 👤 User management (create, update)
- 🔄 Token refresh and revocation
- 🛡️ Password hashing with Argon2id
- 📊 Admin metrics endpoint
- ✅ Integration tests
- Language: Go 1.25+
- Database: PostgreSQL
- Authentication: JWT (JSON Web Tokens)
- Password Hashing: Argon2id
- SQL Code Generation: sqlc
- Migrations: goose
chirpy/
├── internal/
│ ├── api/ # HTTP handlers and routes
│ │ ├── auth.go # Authentication handlers
│ │ ├── chirps.go # Chirp CRUD handlers
│ │ ├── users.go # User management handlers
│ │ └── ...
│ ├── auth/ # Authentication utilities
│ └── database/ # Generated database code (sqlc)
├── sql/
│ ├── schema/ # Database migrations
│ └── queries/ # SQL queries for sqlc
├── main.go # Application entry point
└── Makefile # Build and development commands
- Go 1.25 or higher
- PostgreSQL 12+
- Make (optional, for using Makefile commands)
- Clone the repository:
git clone <repository-url>
cd chirpy- Install dependencies:
go mod download- Set up PostgreSQL database:
createdb chirpy- Create a
.envfile in the root directory:
DB_URL=postgres://username:password@localhost:5432/chirpy?sslmode=disable
JWT_SECRET=your-secret-key-here
PLATFORM=development- Run database migrations:
make migration-up- Generate database code:
make genStart the server:
go run .The server will start on http://localhost:8080
GET /api/healthz- Health check endpoint
-
POST /api/users- Create a new user{ "email": "user@example.com", "password": "password123" } -
POST /api/login- Login and get tokens{ "email": "user@example.com", "password": "password123" }Returns:
token(access token) andrefresh_token -
POST /api/refresh- Refresh access token Headers:Authorization: Bearer <refresh_token>Returns: newtoken -
POST /api/revoke- Revoke refresh token Headers:Authorization: Bearer <refresh_token>
GET /api/chirps- Get all chirpsGET /api/chirps/{id}- Get a specific chirpPOST /api/chirps- Create a new chirp (requires authentication){ "body": "Your chirp text here" }DELETE /api/chirps/{chirpID}- Delete a chirp (requires authentication, owner only)
PUT /api/users- Update user (requires authentication){ "email": "newemail@example.com", "password": "newpassword123" }
GET /admin/metrics- Get server metricsPOST /admin/reset- Reset database (development only)
# Run database migrations
make migration-up
make migration-down
# Generate database code from SQL queries
make gen
# Run all tests
make test
# Run API integration tests
make test-apiIntegration tests require a test database. Set the TEST_DB_URL environment variable:
TEST_DB_URL="postgres://user:pass@localhost:5432/chirpy_test?sslmode=disable" go test -v ./internal/apiOr use the Makefile command:
make test-apiThe application uses PostgreSQL with the following main tables:
users- User accountschirps- Chirp postsrefresh_tokens- Refresh tokens for authentication
See sql/schema/ for migration files.
- Passwords are hashed using Argon2id
- JWT tokens with expiration
- Refresh token rotation
- Token revocation support
- SQL injection protection via sqlc (type-safe queries)
MIT