343 lines
8.6 KiB
Markdown
343 lines
8.6 KiB
Markdown
# Go Backend Template
|
|
|
|
> A clean, production-ready Go backend template with authentication, user management, and best practices built-in.
|
|
|
|
## Features
|
|
|
|
- **Clean Architecture** - Separation of concerns with handler → service → processor → repository layers
|
|
- **Authentication & Authorization** - JWT-based auth with role-based access control
|
|
- **Database Ready** - PostgreSQL integration with GORM
|
|
- **Middleware Stack** - CORS, logging, recovery, correlation ID tracking
|
|
- **Configuration Management** - Environment-based config with Viper
|
|
- **Structured Logging** - Zap and Logrus integration
|
|
- **Input Validation** - Request validation with go-playground/validator
|
|
- **Graceful Shutdown** - Proper cleanup on termination signals
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
.
|
|
├── cmd/
|
|
│ └── server/ # Application entry point
|
|
├── config/ # Configuration management
|
|
│ ├── configs.go # Main config loader
|
|
│ ├── db.go # Database config
|
|
│ ├── jwt.go # JWT config
|
|
│ ├── log.go # Logging config
|
|
│ ├── s3.go # S3/file storage config
|
|
│ └── server.go # Server config
|
|
├── internal/
|
|
│ ├── app/ # Application initialization
|
|
│ ├── appcontext/ # Request context utilities
|
|
│ ├── constant/ # Application constants
|
|
│ ├── constants/ # Business constants
|
|
│ ├── contract/ # API request/response DTOs
|
|
│ ├── db/ # Database connection
|
|
│ ├── entities/ # Database models (GORM)
|
|
│ ├── handler/ # HTTP handlers
|
|
│ ├── logger/ # Logging utilities
|
|
│ ├── middleware/ # HTTP middleware
|
|
│ ├── processor/ # Business logic processors
|
|
│ ├── repository/ # Data access layer
|
|
│ ├── router/ # Route definitions
|
|
│ ├── service/ # Service layer
|
|
│ ├── transformer/ # DTO transformers
|
|
│ ├── util/ # Utility functions
|
|
│ └── validator/ # Custom validators
|
|
├── migrations/ # Database migrations
|
|
├── infra/ # Infrastructure configs (YAML)
|
|
├── go.mod
|
|
├── go.sum
|
|
├── Makefile
|
|
└── README.md
|
|
```
|
|
|
|
## Architecture Layers
|
|
|
|
### 1. Handler Layer (`internal/handler/`)
|
|
- HTTP request/response handling
|
|
- Request validation
|
|
- Route definitions
|
|
- Transforms contracts to/from services
|
|
|
|
### 2. Service Layer (`internal/service/`)
|
|
- Business logic orchestration
|
|
- Coordinates between processors
|
|
- Transaction management
|
|
|
|
### 3. Processor Layer (`internal/processor/`)
|
|
- Complex business operations
|
|
- Cross-repository transactions
|
|
- Business rule enforcement
|
|
|
|
### 4. Repository Layer (`internal/repository/`)
|
|
- Data access layer
|
|
- Database operations
|
|
- GORM integration
|
|
|
|
### 5. Supporting Packages
|
|
- **Contract** - API DTOs with JSON tags
|
|
- **Entities** - Database models with GORM tags
|
|
- **Transformer** - Contract ↔ Entity conversions
|
|
- **Middleware** - Request processing pipeline
|
|
- **Validator** - Custom validation logic
|
|
|
|
## Getting Started
|
|
|
|
### Prerequisites
|
|
|
|
- Go 1.21 or higher
|
|
- PostgreSQL 12+
|
|
- Make (optional, for using Makefile commands)
|
|
|
|
### Installation
|
|
|
|
1. **Clone this template**
|
|
```bash
|
|
git clone <your-repo-url>
|
|
cd go-backend-template
|
|
```
|
|
|
|
2. **Rename the project**
|
|
|
|
Update the module name in `go.mod`:
|
|
```go
|
|
module your-project-name
|
|
```
|
|
|
|
Then update all imports:
|
|
```bash
|
|
find . -name "*.go" -type f -exec sed -i '' 's|go-backend-template|your-project-name|g' {} \;
|
|
```
|
|
|
|
3. **Install dependencies**
|
|
```bash
|
|
go mod download
|
|
```
|
|
|
|
4. **Set up configuration**
|
|
|
|
Create your environment config file in `infra/`:
|
|
```bash
|
|
cp infra/development.yaml infra/development.yaml
|
|
```
|
|
|
|
Edit `infra/development.yaml` with your settings:
|
|
```yaml
|
|
server:
|
|
port: "8080"
|
|
|
|
postgresql:
|
|
host: "localhost"
|
|
port: "5432"
|
|
user: "postgres"
|
|
password: "your-password"
|
|
database: "your-database"
|
|
sslmode: "disable"
|
|
|
|
jwt:
|
|
token:
|
|
secret: "your-secret-key"
|
|
expires_ttl: 3600
|
|
|
|
log:
|
|
log_level: "info"
|
|
log_format: "json"
|
|
```
|
|
|
|
5. **Run database migrations**
|
|
```bash
|
|
make migration-up
|
|
```
|
|
|
|
6. **Start the server**
|
|
```bash
|
|
# Set environment mode
|
|
export ENV_MODE=development
|
|
|
|
# Run the server
|
|
go run cmd/server/main.go
|
|
```
|
|
|
|
## Configuration
|
|
|
|
The application uses environment-based YAML configuration files located in the `infra/` directory:
|
|
|
|
- `infra/local.yaml` - Local development
|
|
- `infra/development.yaml` - Development environment
|
|
- `infra/production.yaml` - Production environment
|
|
|
|
Set the `ENV_MODE` environment variable to select the configuration:
|
|
```bash
|
|
export ENV_MODE=development # or local, production
|
|
```
|
|
|
|
## API Endpoints
|
|
|
|
### Health Check
|
|
- `GET /health` - Health check endpoint
|
|
|
|
### Authentication
|
|
- `POST /api/v1/auth/login` - User login
|
|
- `POST /api/v1/auth/refresh` - Refresh access token
|
|
- `GET /api/v1/auth/profile` - Get authenticated user profile
|
|
|
|
### Users (Protected)
|
|
- `POST /api/v1/users` - Create user
|
|
- `GET /api/v1/users` - List users
|
|
- `PUT /api/v1/users/:id` - Update user
|
|
- `DELETE /api/v1/users/:id` - Delete user
|
|
- `GET /api/v1/users/profile` - Get current user profile
|
|
- `PUT /api/v1/users/profile` - Update current user profile
|
|
- `PUT /api/v1/users/:id/password` - Change user password
|
|
|
|
## Development
|
|
|
|
### Running with Air (Hot Reload)
|
|
|
|
Install Air:
|
|
```bash
|
|
go install github.com/cosmtrek/air@latest
|
|
```
|
|
|
|
Run with hot reload:
|
|
```bash
|
|
air
|
|
```
|
|
|
|
### Database Migrations
|
|
|
|
Create a new migration:
|
|
```bash
|
|
make migration-create name=create_your_table
|
|
```
|
|
|
|
Run migrations:
|
|
```bash
|
|
make migration-up
|
|
```
|
|
|
|
Rollback last migration:
|
|
```bash
|
|
make migration-down
|
|
```
|
|
|
|
### Code Formatting
|
|
|
|
```bash
|
|
make fmt
|
|
```
|
|
|
|
### Running Tests
|
|
|
|
```bash
|
|
make test
|
|
```
|
|
|
|
## Building for Production
|
|
|
|
Build the binary:
|
|
```bash
|
|
make build-http
|
|
```
|
|
|
|
The binary will be created in `./bin/http-server`.
|
|
|
|
Run the production binary:
|
|
```bash
|
|
./bin/http-server
|
|
```
|
|
|
|
## Docker Support
|
|
|
|
Build Docker image:
|
|
```bash
|
|
docker build -t your-app-name .
|
|
```
|
|
|
|
Run with Docker Compose:
|
|
```bash
|
|
docker-compose up
|
|
```
|
|
|
|
## Customization Guide
|
|
|
|
### Adding a New Feature
|
|
|
|
1. **Define the entity** in `internal/entities/`
|
|
2. **Create migration** for the database table
|
|
3. **Add repository** in `internal/repository/`
|
|
4. **Create processor** in `internal/processor/` for business logic
|
|
5. **Add service** in `internal/service/` for orchestration
|
|
6. **Define contracts** in `internal/contract/` for API DTOs
|
|
7. **Create handler** in `internal/handler/` for HTTP endpoints
|
|
8. **Register routes** in `internal/router/router.go`
|
|
9. **Wire dependencies** in `internal/app/app.go`
|
|
|
|
### Example: Adding a "Product" Feature
|
|
|
|
```go
|
|
// 1. Entity (internal/entities/product.go)
|
|
type Product struct {
|
|
ID string `gorm:"primaryKey"`
|
|
Name string `gorm:"not null"`
|
|
Price float64 `gorm:"not null"`
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
// 2. Repository (internal/repository/product_repository.go)
|
|
type ProductRepository interface {
|
|
Create(ctx context.Context, product *entities.Product) error
|
|
FindByID(ctx context.Context, id string) (*entities.Product, error)
|
|
}
|
|
|
|
// 3. Service (internal/service/product_service.go)
|
|
type ProductService interface {
|
|
CreateProduct(ctx context.Context, req *contract.CreateProductRequest) error
|
|
}
|
|
|
|
// 4. Handler (internal/handler/product_handler.go)
|
|
func (h *ProductHandler) CreateProduct(c *gin.Context) {
|
|
// Handle HTTP request
|
|
}
|
|
|
|
// 5. Register in router (internal/router/router.go)
|
|
products := v1.Group("/products")
|
|
products.Use(r.authMiddleware.RequireAuth())
|
|
{
|
|
products.POST("", r.productHandler.CreateProduct)
|
|
products.GET("/:id", r.productHandler.GetProduct)
|
|
}
|
|
```
|
|
|
|
## Environment Variables
|
|
|
|
- `ENV_MODE` - Environment mode (local, development, production)
|
|
|
|
## Dependencies
|
|
|
|
Key dependencies:
|
|
- **Gin** - HTTP web framework
|
|
- **GORM** - ORM library
|
|
- **Viper** - Configuration management
|
|
- **Zap/Logrus** - Structured logging
|
|
- **JWT** - JSON Web Token authentication
|
|
- **Validator** - Struct validation
|
|
- **AWS SDK** - S3 file storage (optional)
|
|
|
|
## License
|
|
|
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
|
|
## Contributing
|
|
|
|
1. Fork the repository
|
|
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
5. Open a Pull Request
|
|
|
|
## Support
|
|
|
|
For issues and questions, please open an issue on GitHub.
|