Fandogh is a rental home listing platform that allows users to register, list properties for rent, and browse available homes. Property owners can create listings with photos, descriptions, and rental details, while buyers can search and view available properties.
- User registration and JWT-based authentication
- Create, update, and browse home listings
- Photo upload support with S3-compatible storage (MinIO/SeaweedFS)
- Role-based access control (owner/admin permissions)
- Pagination for listing queries
- Distributed tracing with OpenTelemetry and Jaeger
- Prometheus metrics for monitoring
- Language: Go
- Web Framework: Echo v4
- Database: MongoDB
- File Storage: MinIO (S3-compatible)
- Authentication: JWT
- Dependency Injection: Uber/fx
- Logging: Uber/zap
- Tracing: OpenTelemetry + Jaeger
- Go 1.25+
- Docker and Docker Compose
- Start the infrastructure services:
docker compose -f deployments/docker-compose.yml up -d- Copy and configure the settings:
cp configs/config.example.yml configs/config.yml- Run database migrations:
go run ./cmd/fandogh migrate- Start the server:
go run ./cmd/fandogh serverThe API will be available at http://localhost:1378.
docker build -t fandogh -f build/package/Dockerfile .
docker run -p 1378:1378 fandoghConfiguration can be set via YAML file or environment variables (prefix: FANDOGH_).
| Setting | Environment Variable | Default | Description |
|---|---|---|---|
logger.level |
FANDOGH_LOGGER_LEVEL |
info |
Log level |
database.url |
FANDOGH_DATABASE_URL |
mongodb://localhost:27017 |
MongoDB connection URL |
database.name |
FANDOGH_DATABASE_NAME |
fandogh |
Database name |
fs.endpoint |
FANDOGH_FS_ENDPOINT |
localhost:8333 |
MinIO endpoint |
fs.access_key |
FANDOGH_FS_ACCESS_KEY |
- | MinIO access key |
fs.secret_key |
FANDOGH_FS_SECRET_KEY |
- | MinIO secret key |
jwt.access_secret |
FANDOGH_JWT_ACCESS_SECRET |
- | JWT signing secret |
fandogh/
βββ cmd/fandogh/ # Application entry point
βββ internal/
β βββ cmd/ # CLI commands (server, migrate)
β βββ config/ # Configuration management
β βββ db/ # MongoDB connection
β βββ fs/ # File storage (MinIO)
β βββ http/
β β βββ handler/ # HTTP request handlers
β β βββ request/ # Request DTOs with validation
β β βββ response/ # Response DTOs
β β βββ jwt/ # JWT generation/validation
β β βββ server/ # Echo server setup
β βββ model/ # Domain models (User, Home)
β βββ store/ # Data access layer
βββ deployments/ # Docker Compose files
βββ build/package/ # Dockerfile
βββ configs/ # Configuration examples
curl 127.0.0.1:1378/register -X POST \
-H 'Content-Type: application/json' \
-d '{ "email": "user@example.com", "name": "John Doe", "password": "123456" }'Note: The first registered user automatically becomes an admin.
curl 127.0.0.1:1378/login -X POST \
-H 'Content-Type: application/json' \
-d '{ "email": "user@example.com", "password": "123456" }'Response:
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"Email": "user@example.com",
"Name": "John Doe"
}All home endpoints require the Authorization: Bearer <token> header.
curl 127.0.0.1:1378/api/homes -X POST \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"title": "Cozy Apartment",
"location": "Rome, Italy",
"description": "A beautiful place in the city center",
"peoples": 3,
"room": "living room",
"bed": "single",
"rooms": 2,
"bathrooms": 1,
"smoking": false,
"guest": true,
"pet": false,
"bills_included": true,
"contract": "1 year",
"security_deposit": 1000,
"price": 800
}'curl '127.0.0.1:1378/api/homes?skip=0&limit=10' \
-H 'Authorization: Bearer <token>'Response:
{
"homes": [...],
"total": 25,
"skip": 0,
"limit": 10
}curl 127.0.0.1:1378/api/homes/<id> \
-H 'Authorization: Bearer <token>'Only the owner or an admin can update a listing.
curl 127.0.0.1:1378/api/homes/<id> -X PUT \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{ "price": 900 }'curl 127.0.0.1:1378/healthzgo test ./...golangci-lint run- Metrics: Prometheus metrics available at port 8080 (when enabled)
- Tracing: Jaeger UI available at
http://localhost:16686(when running with Docker Compose)