Go web application for user management with the following stack:
- Gin (web framework)
- GORM + MySQL
- Session cookie (
gin-contrib/sessions) - Embedded SQL migrations (
golang-migrate) - Register/login/logout auth + roles (
admin/user) - User dashboard with search, pagination, and admin-only CRUD
- Register & login with
bcryptpassword hashing. - The first registered user is automatically assigned as
admin. - Auto-promote fallback: if no admin exists, a logging-in user can be promoted to admin.
- Protected dashboard route (
/dashboard). - View the user list on the dashboard (all logged-in users).
- Dashboard search by
all,id,name,email,role. - Dashboard pagination (
10/25/50/100) + page jumps-100/-1000/+100/+1000. - Indexed search/list queries to reduce scan time on large user tables.
- Configurable DB connection pooling for better throughput under concurrent traffic.
- Automatic migrations at startup to keep schema/indexes aligned with expected query paths.
- Cleaner logs by filtering client-disconnect noise, helping faster performance troubleshooting.
- Add / update / delete users from dashboard (admin only).
- Prevent admins from deleting their own account.
- Go
1.25.x(based ongo.mod) - Running MySQL server (example: XAMPP MySQL)
Create the database:
CREATE DATABASE websitego CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;copy .env.example .env
go mod tidy
go run ./cmd/webThe project reads .env through godotenv (if the file exists). If values are missing, code defaults will be used.
APP_PORT=8080
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=root
DB_PASSWORD=
DB_NAME=websitego
DB_MAX_OPEN_CONNS=50
DB_MAX_IDLE_CONNS=25
DB_CONN_MAX_LIFETIME_MIN=10
SESSION_SECRET=change-this-secret
COOKIE_SECURE=false
COOKIE_SAMESITE=laxNotes:
SESSION_SECRETmust not be empty.COOKIE_SAMESITE:lax(default),strict, ornone.COOKIE_SECURE=trueis recommended for HTTPS production.
go mod tidy
go run ./cmd/webThe server runs at http://localhost:8080 (or based on APP_PORT).
Manual migration commands:
go run ./cmd/migrate up
go run ./cmd/migrate down
go run ./cmd/migrate force <version>Notes:
cmd/webautomatically runsupmigration on startup.- Migration files are in
internal/migrations/sqland embedded into the binary.
A seeder is available in cmd/seed:
go run ./cmd/seedOptional number of user role records:
go run ./cmd/seed --users=10000Seed behavior:
- Creates/updates the admin account (
admin@gmail.com/admin789, roleadmin). - Creates regular users with default password:
user12345. - Default number of users is
9,999,999if--usersis not provided.
Recommendation:
- For development, always use
--usersto avoid creating very large datasets unintentionally.
- Open
/registerto create an account. - Sign in at
/login. - After login, access
/dashboard. - Logout via
/logout.
GET /redirects to/loginor/dashboarddepending on session state.GET /register,POST /register(guest only)GET /login,POST /login(guest only)GET /logoutGET /dashboard(auth required)POST /dashboard/users(admin only)POST /dashboard/users/:id/update(admin only)POST /dashboard/users/:id/delete(admin only)
Available migration:
000004_init_schema
Notes for legacy databases:
- If you previously used incremental migration versions, align the version with
forcebeforeup(example:go run ./cmd/migrate force 4).
Indexes for dashboard/search optimization:
idx_users_dashboard_list (id, name, email, role)idx_users_name (name)idx_users_role (role)
-
Query indexing strategy
- Dashboard list and search use indexes to avoid full table scans as data grows.
- Composite index
idx_users_dashboard_list (id, name, email, role)supports common list/search patterns. - Additional single-column indexes (
name,role) help targeted filters.
-
Pagination for controlled query cost
- Dashboard limits rows per request (
10/25/50/100) so each response remains predictable. - Page jump controls help navigation without requesting excessively large payloads.
- This keeps response time and memory usage more stable on big datasets.
- Dashboard limits rows per request (
-
Database connection pool tuning
DB_MAX_OPEN_CONNScontrols max concurrent active DB connections.DB_MAX_IDLE_CONNSkeeps warm idle connections to reduce reconnect overhead.DB_CONN_MAX_LIFETIME_MINrefreshes long-lived connections to reduce stale-connection risk.- These settings help balance throughput, latency, and DB server load.
-
Runtime consistency for performance
cmd/webruns migrations automatically so required indexes/schema stay present.- This reduces risk of performance drops caused by schema mismatch across environments.
-
Operational observability
- Middleware filters expected client-disconnect errors from logs.
- Cleaner logs make real latency/errors easier to detect and fix quickly.
cmd/
web/ # web server
migrate/ # migration CLI
seed/ # seed data
internal/
config/
database/
handlers/
middleware/
migrations/
models/
templates/
assets/