Skip to main content

Framework Architecture

Developer Intermediate

Understanding EZ-Console's architecture is essential for building robust applications. This guide explains the framework's design, components, and how they interact.

High-Level Architecture​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Frontend Layer β”‚
β”‚ React + TypeScript + Ant Design + React Router β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ HTTP/HTTPS (JSON)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ API Gateway Layer β”‚
β”‚ Gin Router + Middleware (Auth, CORS, Log) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Controller Layer β”‚
β”‚ HTTP Request Handling + Input Validation β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Service Layer β”‚
β”‚ Business Logic + Transaction Management β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Data Access Layer β”‚
β”‚ GORM ORM + Database Operations β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Database β”‚
β”‚ SQLite / MySQL / PostgreSQL β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Backend Architecture​

Layered architecture​

The backend splits HTTP handling, business logic, persistence shapes, and cross-cutting behavior. Full patterns, request/response helpers, and copy-pastable examples are in Core concepts so this page stays focused on diagrams and flow.

LayerRole
ControllerRoutes, binding/validation, calls services, writes HTTP responses
ServiceRules, transactions, DB and integrations; no gin.Context
ModelGORM schema and relationships; embed model.Base for public id and soft delete
MiddlewareAuth, RBAC, CORS, logging, metricsβ€”see Middleware

The stock server ships JWT auth, permission checks, structured logging, CORS, panic recovery, and metrics. For global Gin setup that runs after that default stack (extra Use, top-level routes), use consoleserver.WithEngineOptions on NewCommandServer; timing and examples: Middleware: global middleware and Command server options.

Request Flow​

Here's how a typical request flows through the backend:

1. Client Request
↓
2. Gin Router (route matching)
↓
3. Middleware Chain
- Logging (start)
- CORS headers
- Authentication (JWT validation)
- Permission check
↓
4. Controller
- Parse request parameters
- Validate input
- Call service
↓
5. Service
- Execute business logic
- Database operations
- Call other services if needed
↓
6. Model/Repository
- GORM query execution
- Data persistence
↓
7. Controller (continued)
- Format response
- Return HTTP response
↓
8. Middleware Chain (reversed)
- Logging (end)
- Metrics collection
↓
9. Client Response

Frontend Architecture​

Component Hierarchy​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Application Shell β”‚
β”‚ (Layout, Navigation, Authentication) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚
β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
β”‚ Public β”‚ β”‚ Private β”‚
β”‚ Routes β”‚ β”‚ Routes β”‚
β”‚ β”‚ β”‚ (Protected) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚ β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β” β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”
β”‚ Page β”‚ β”‚ Page β”‚ β”‚ Page β”‚
β”‚Componentsβ”‚ β”‚Componentsβ”‚ β”‚Componentsβ”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ β””β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
β”‚ β”‚ β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”
β”‚ Shared Components β”‚
β”‚ (Tables, Forms, Modals) β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ API Service Layer β”‚
β”‚ (HTTP Client + Interceptors)β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ State Management β”‚
β”‚ (Context API + React Query) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Frontend Layers​

1. Application Shell​

The EZApp component provides:

  • Layout (header, sidebar, content)
  • Navigation menu
  • Authentication flow
  • Route protection
  • Global state providers
<EZApp
basePath='/'
extraPrivateRoutes={[
{
path: '/products',
element: withSuspense(ProductPage),
name: 'products',
}
]}
/>

2. Page Components​

Pages are lazy-loaded route components:

const ProductPage = lazy(() => import('@/pages/ProductPage'));

3. Shared Components​

Reusable UI components:

  • DataTable - Table with pagination, sorting, filtering
  • FormModal - Modal with form handling
  • FileUpload - File upload with progress
  • PermissionGuard - Component-level permission check

4. API Service Layer​

Axios-based HTTP client with interceptors:

// Request interceptor - add auth token
axios.interceptors.request.use((config) => {
const token = getToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});

// Response interceptor - handle errors
axios.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// Token expired, redirect to login
window.location.href = '/login';
}
return Promise.reject(error);
}
);

5. State Management​

Two types of state:

Server State (React Query):

const { data, loading } = useRequest(() => apiGet('/users'));

Client State (React Context):

const { user, updateUser } = useAuth();
const { siteConfig, currentOrgId } = useSite();

See React hooks & context for useAuth, useSite, usePermission, and useAI.

This page focuses on shape and flow: layers, diagrams, and how frontend and backend connect. The conventions you apply in day-to-day codeβ€”controller vs service, standard responses, resource_id, soft deletes, audit helpers, RBAC, and the middleware pipelineβ€”are documented in one place so they do not drift across pages:

  • Core concepts β€” patterns, IDs, auth flow, audit usage, middleware overview

Skim the diagrams here first; keep Core concepts open while you implement.

Built-in Modules​

EZ-Console provides several built-in modules:

1. User Management Module​

  • User CRUD operations
  • Password management
  • MFA configuration
  • Status management
  • Last login tracking

2. Authorization Module​

  • Role management
  • Permission definitions
  • Permission groups
  • Service accounts
  • Session management
  • OAuth2/OIDC integration
  • LDAP/AD integration

3. System Settings Module​

  • Password policies
  • MFA settings
  • Session timeout
  • Email/SMTP configuration
  • OAuth provider configuration

4. File Management Module​

  • File upload/download
  • Storage abstraction
  • Access control
  • File metadata

5. Audit Log Module​

  • Action logging
  • IP tracking and geolocation
  • User agent tracking
  • Searchable logs

6. Statistics Module​

  • User activity metrics
  • Login statistics
  • API usage tracking
  • System health

Extensibility​

Controllers and routes​

Register HTTP controllers from your application module (typically in init()):

func init() {
server.RegisterControllers(func(ctx context.Context, svc server.Service) server.Controller {
return NewProductController(svc)
})
}

Gin middleware​

The stock server owns the Gin *gin.Engine. For global middleware or extra top-level routes, use consoleserver.WithEngineOptions on NewCommandServer: callbacks run after the default stack (recovery, OpenTelemetry, Prometheus, request logging, CORS, delay) and before services and controller registration. Examples and ordering details: Middleware, Command server options.

User and role change hooks​

The underlying authorization layer supports RegisterUserChangeHook and RegisterUserRoleChangeHook on server.Service. The default Run path constructs the service inside the framework, so registering these hooks from a plain main + NewCommandServer app may require following the patterns in the source or a custom bootstrap. See Hooks & Events.

Next Steps​

  1. If you have not run the stock app yet, use Quick Start
  2. Keep Core concepts nearby while you implement controllers and services
  3. Explore Backend development for deeper guides

Questions about the architecture? Ask on GitHub Discussions.