Go backend API template using Base Framework for building admin applications with CRUD operations, authentication, file storage, and more.
Before starting, ensure you have the following installed:
# Install Go (1.21 or higher)
brew install go
# Install image processing libraries (required for media handling)
brew install webp libheif
# Install PostgreSQL (or use Docker)
brew install postgresql@15# Install Go (1.21 or higher)
sudo apt update
sudo apt install golang-go
# Install image processing libraries (required for media handling)
sudo apt install libwebp-dev libheif-dev
# Install PostgreSQL
sudo apt install postgresql postgresql-contrib# Check Go version
go version # Should be 1.21 or higher
# Check webp installation
pkg-config --modversion libwebp
# Check heif installation
pkg-config --modversion libheifWhy webp and heif?
- The Base Framework's media module uses these libraries for image processing
libwebp- WebP image format support for optimized web imageslibheif- HEIF/HEIC image format support (iPhone photos)- Without these libraries, the build will fail with linker errors
# Copy environment template
cp .env.example .env
# Edit .env with your database credentials
nano .envKey environment variables:
APP_PORT=8000
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=your_password
DB_NAME=admin_db
JWT_SECRET=your-secret-key-change-in-production# Create database
createdb admin_db
# Or using psql
psql -U postgres -c "CREATE DATABASE admin_db;"# Install Go dependencies
go mod tidy
# Run with Swagger docs generation (first time)
bui start --docs
# Or run directly with Go
go run main.goThe API will be available at:
- API: http://localhost:8000/api
- Swagger Docs: http://localhost:8000/swagger/
# Build binary
go build -o admin main.go
# Or use Bui CLI
bui build backend
# Run binary
./adminadmin-api-template/
├── app/ # Your application modules
│ ├── models/ # GORM models (generated by Bui)
│ ├── [module]/ # Module directories (service, controller, validator)
│ └── init.go # Module registration and authentication extension
├── core/ # Base Framework core (DO NOT EDIT)
│ ├── app/ # Core modules (auth, profile, media, etc.)
│ ├── database/ # Database connection and migrations
│ ├── router/ # HTTP routing and middleware
│ ├── storage/ # File upload handling
│ ├── email/ # Email sending
│ ├── websocket/ # WebSocket support
│ ├── logger/ # Structured logging
│ └── ...
├── logs/ # Application logs
│ └── app.log # JSON structured logs
├── main.go # Application entry point
├── .env # Environment configuration
└── go.mod
# Generate backend module with Bui CLI
bui generate backend product name:string price:float stock:int
# This creates:
# - app/products/model.go # GORM model
# - app/products/service.go # Business logic
# - app/products/controller.go # HTTP handlers
# - app/products/module.go # Route registration
# - app/products/validator.go # Input validationAfter generating, manually register in app/init.go:
func GetAppModules() map[string]module.Module {
modules := make(map[string]module.Module)
// Register your modules here
modules["products"] = products.Init(deps)
return modules
}string- Text fieldtext- Long text (textarea)int,uint- Integer numbersfloat- Decimal numbersbool- Boolean valuetime- Timestampjson- JSON data
translation- Translatable field (multi-language support)media:image- Image upload fieldmedia:file- File upload field
category:belongsTo:Category- Foreign key (many-to-one)tags:manyToMany:Tag- Many-to-many relationship
bui g backend product \
name:translation \
sku:string \
description:text \
price:float \
stock:int \
category:belongsTo:Category \
is_active:bool \
thumbnail:media:imageExtend JWT claims in app/init.go:
func Extend(user_id uint) any {
// Add custom claims to JWT token
var user models.User
db.First(&user, user_id)
return map[string]any{
"user_id": user_id,
"role_id": user.RoleID,
"company_id": user.CompanyID,
}
}The application uses structured logging with file and console output:
- Location:
logs/app.log - Format: JSON (structured logging)
- Rotation: Automatic (configurable)
# Show detailed logs
go run main.go -v
# or
go run main.go --verbose- INFO: General information (blue)
- WARN: Warning messages (yellow)
- ERROR: Error messages (red)
- DEBUG: Debug information (purple)
- FATAL: Fatal errors (bold red)
- Authentication:
/api/auth/login,/api/auth/register - Profile:
/api/profile - Media:
/api/media/upload - Settings:
/api/settings - Employees:
/api/employees - Search:
/api/search
For each generated module (e.g., products):
GET /api/products- List with pagination/filtersGET /api/products/all- Simplified list for dropdownsGET /api/products/:id- Get single itemPOST /api/products- Create new itemPUT /api/products/:id- Update itemDELETE /api/products/:id- Delete item
STORAGE_DRIVER=local
STORAGE_LOCAL_PATH=./storage
STORAGE_BASE_URL=http://localhost:8000/storageSTORAGE_DRIVER=s3
STORAGE_S3_BUCKET=your-bucket
STORAGE_S3_REGION=us-east-1
STORAGE_S3_KEY=your-access-key
STORAGE_S3_SECRET=your-secret-keySTORAGE_DRIVER=gcs
STORAGE_GCS_BUCKET=your-bucket
STORAGE_GCS_PROJECT=your-project-id
STORAGE_GCS_CREDENTIALS=/path/to/credentials.jsonEMAIL_DRIVER=postmark
EMAIL_FROM=noreply@yourdomain.com
EMAIL_FROM_NAME=Your App
POSTMARK_SERVER_TOKEN=your-tokenEMAIL_DRIVER=sendgrid
EMAIL_FROM=noreply@yourdomain.com
EMAIL_FROM_NAME=Your App
SENDGRID_API_KEY=your-api-keyUse air for hot reloading during development:
# Install air
go install github.com/cosmtrek/air@latest
# Run with hot reload
airModels are auto-migrated on startup. To disable:
AUTO_MIGRATE=falseGenerate Swagger docs before starting:
# Install swag
go install github.com/swaggo/swag/cmd/swag@latest
# Generate docs
swag init
# Or use Bui CLI
bui start --docs# Build optimized binary
go build -ldflags="-s -w" -o admin main.goAPP_ENV=production
DEBUG=false
SWAGGER_ENABLED=false# Run with verbose logging
./admin -v
# Or use systemd/supervisor for process managementld: library not found for -lwebp
ld: library not found for -lheif
Solution: Install image processing libraries (see Prerequisites section)
failed to connect to database
Solution: Check database credentials in .env and ensure PostgreSQL is running
bind: address already in use
Solution: Change APP_PORT in .env or stop the process using port 8000
MIT