Documentation
¶
Index ¶
- Constants
- Variables
- func Clean()
- func Create[M types.Model, REQ types.Request, RSP types.Response](c *gin.Context)
- func CreateFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
- func CreateMany[M types.Model, REQ types.Request, RSP types.Response](c *gin.Context)
- func CreateManyFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
- func Delete[M types.Model, REQ types.Request, RSP types.Response](c *gin.Context)
- func DeleteFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
- func DeleteMany[M types.Model, REQ types.Request, RSP types.Response](c *gin.Context)
- func DeleteManyFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
- func Export[M types.Model, REQ types.Request, RSP types.Response](c *gin.Context)
- func ExportFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
- func Get[M types.Model, REQ types.Request, RSP types.Response](c *gin.Context)
- func GetFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
- func Import[M types.Model, REQ types.Request, RSP types.Response](c *gin.Context)
- func ImportFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
- func Init() (err error)
- func List[M types.Model, REQ types.Request, RSP types.Response](c *gin.Context)
- func ListFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
- func PageID(c *gin.Context)
- func Patch[M types.Model, REQ types.Request, RSP types.Response](c *gin.Context)
- func PatchFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
- func PatchMany[M types.Model, REQ types.Request, RSP types.Response](c *gin.Context)
- func PatchManyFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
- func Redoc(c *gin.Context)
- func Scalar(c *gin.Context)
- func SliderCaptchaGen(c *gin.Context)
- func SliderCaptchaVerify(c *gin.Context)
- func Stoplight(c *gin.Context)
- func Update[M types.Model, REQ types.Request, RSP types.Response](c *gin.Context)
- func UpdateFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
- func UpdateMany[M types.Model, REQ types.Request, RSP types.Response](c *gin.Context)
- func UpdateManyFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
Constants ¶
const ( MAX_AVATAR_SIZE = 1024 * 1024 * 2 //nolint:staticcheck // 2M MAX_IMPORT_SIZE = 5 * 1024 * 1024 //nolint:staticcheck // 5M MAX_UPLOAD_SIZE = 1024 * 1024 * 100 //nolint:staticcheck // 100M )
const ( TOKEN = "token" //nolint:staticcheck ACCESS_TOKEN = "access_token" //nolint:staticcheck REFRESH_TOKEN = "refresh_token" //nolint:staticcheck NAME = "name" //nolint:staticcheck ID = "id" //nolint:staticcheck SESSION_ID = "session_id" //nolint:staticcheck )
const ErrRequestBodyEmpty = "request body is empty"
Variables ¶
var PAGE_ID = time.Now().Unix() //nolint:staticcheck
var Portal = new(portal)
var Probe = new(probe)
var Upload = new(upload)
var User = new(user)
Functions ¶
func Create ¶
Create is a generic function to product gin handler to create one resource. The resource type depends on the type of interface types.Model.
func CreateFactory ¶
func CreateFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
CreateFactory is a factory function that produces a gin handler for creating one resource. It supports two different processing modes based on the type relationship between M, REQ, and RSP:
Mode 1: Unified Types (M == REQ == RSP) When all three generic types are identical, the factory enables automatic resource management:
- Controller layer automatically handles resource creation in database
- Service hooks (CreateBefore/CreateAfter) are executed for business logic
- Processing flow: Request -> ServiceBefore -> ModelBefore -> Database -> ModelAfter -> ServiceAfter -> Response
- The request body is directly bound to the model type M
- Automatic setting of CreatedBy/UpdatedBy fields from context
Mode 2: Custom Types (M != REQ or REQ != RSP) When types differ, the factory delegates full control to the service layer:
- Service layer has complete control over resource creation
- No automatic database operations or service hooks
- Processing flow: Request -> Service.Create -> Response
- The request body is bound to the REQ type
- Service must handle all business logic and database operations
Type Parameters:
- M: Model type that implements types.Model interface (must be pointer to struct, e.g., *User)
- REQ: Request type that implements types.Request interface
- RSP: Response type that implements types.Response interface
Parameters:
- cfg: Optional controller configuration for customizing database handler
Returns:
- gin.HandlerFunc: A gin handler function for HTTP POST requests
HTTP Response:
- Success: 201 Created with the created resource data
- Error: 400 Bad Request for invalid parameters, 500 Internal Server Error for other failures
Examples:
Unified types (automatic mode):
CreateFactory[*model.User, *model.User, *model.User]()
Custom types (manual mode):
CreateFactory[*model.User, *CreateUserRequest, *CreateUserResponse]()
func CreateMany ¶
func CreateManyFactory ¶
func CreateManyFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
CreateManyFactory is a factory function that produces a gin handler for batch creating multiple resources. It supports two different processing modes based on the type relationship between M, REQ, and RSP:
Mode 1: Unified Types (M == REQ == RSP) When all three generic types are identical, the factory enables automatic resource management:
- Controller layer automatically handles batch resource creation in database
- Service hooks (CreateManyBefore/CreateManyAfter) are executed for business logic
- Processing flow: Request -> ServiceBefore -> Database -> ServiceAfter -> Response
- The request body is bound to requestData[M] structure containing Items slice
- Automatic setting of CreatedBy/UpdatedBy fields from context for each item
- Supports atomic operations through options configuration
- Operation logging is automatically recorded to database
Mode 2: Custom Types (M != REQ or REQ != RSP) When types differ, the factory delegates full control to the service layer:
- Service layer has complete control over batch resource creation
- No automatic database operations or service hooks
- Processing flow: Request -> Service.CreateMany -> Response
- The request body is bound to the REQ type
- Service must handle all business logic and database operations
Type Parameters:
- M: Model type that implements types.Model interface (must be pointer to struct, e.g., *User)
- REQ: Request type that implements types.Request interface
- RSP: Response type that implements types.Response interface
Parameters:
- cfg: Optional controller configuration for customizing database handler
Returns:
- gin.HandlerFunc: A gin handler function for HTTP POST requests
HTTP Response:
- Success: 201 Created with batch operation summary and created resources
- Error: 400 Bad Request for invalid parameters, 500 Internal Server Error for other failures
Request Body Format (Unified Types):
{
"items": [/* array of resources to create */],
"options": {
"atomic": true // optional: whether to perform atomic operation
}
}
Response Format (Unified Types):
{
"items": [/* array of created resources */],
"summary": {
"total": 10,
"succeeded": 10,
"failed": 0
}
}
Examples:
Unified types (automatic mode):
CreateManyFactory[*model.User, *model.User, *model.User]()
Custom types (manual mode):
CreateManyFactory[*model.User, *CreateManyUsersRequest, *CreateManyUsersResponse]() // Service layer controls all batch creation logic
func Delete ¶
Delete is a generic function to product gin handler to delete one or multiple resources. The resource type depends on the type of interface types.Model.
Resource id must be specify and all resources that id matched will be deleted in database.
Delete one resource: - specify resource `id` in "router parameter", eg: localhost:9000/api/myresource/myid - specify resource `id` in "query parameter", eg: localhost:9000/api/myresource?id=myid
Delete multiple resources: - specify resource `id` slice in "http body data".
func DeleteFactory ¶
func DeleteFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
DeleteFactory is a factory function that produces a gin handler for deleting one or multiple resources. It supports two different processing modes based on the type relationship between M, REQ, and RSP:
Mode 1: Unified Types (M == REQ == RSP) When all three generic types are identical, the factory enables automatic resource management:
- Controller layer automatically handles resource deletion from database
- Service hooks (DeleteBefore/DeleteAfter) are executed for business logic
- Processing flow: Request -> ServiceBefore -> ModelBefore -> Database -> ModelAfter -> ServiceAfter -> Response
- Supports multiple deletion methods:
- Route parameter: DELETE /api/users/123
- Query parameter: DELETE /api/users?id=123
- Request body: DELETE /api/users with JSON array ["id1", "id2", "id3"]
- Automatic deduplication of resource IDs
Mode 2: Custom Types (M != REQ or REQ != RSP) When types differ, the factory delegates full control to the service layer:
- Service layer has complete control over resource deletion logic
- No automatic database operations or service hooks
- Processing flow: Request -> Service.Delete -> Response
- The request body is bound to the REQ type
- Service must handle all business logic and database operations
Type Parameters:
- M: Model type that implements types.Model interface (must be pointer to struct, e.g., *User)
- REQ: Request type that implements types.Request interface
- RSP: Response type that implements types.Response interface
Parameters:
- cfg: Optional controller configuration for customizing database handler
Returns:
- gin.HandlerFunc: A gin handler function for HTTP DELETE requests
HTTP Response:
- Success: 204 No Content (unified types) or 200 OK (custom types) with optional response data
- Error: 400 Bad Request for invalid parameters, 404 Not Found if resource doesn't exist, 500 Internal Server Error for other failures
Examples:
Unified types (automatic mode):
DeleteFactory[*model.User, *model.User, *model.User]() // Supports: DELETE /users/123, DELETE /users?id=123, DELETE /users with ["id1", "id2"]
Custom types (manual mode):
DeleteFactory[*model.User, *DeleteUserRequest, *DeleteUserResponse]() // Service layer controls all deletion logic
func DeleteMany ¶
DeleteMany
func DeleteManyFactory ¶
func DeleteManyFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
DeleteManyFactory is a factory function that produces a gin handler for batch deleting multiple resources. It supports two different processing modes based on the type relationship between M, REQ, and RSP:
Mode 1: Unified Types (M == REQ == RSP) When all three generic types are identical, the factory enables automatic resource management:
- Controller layer automatically handles batch resource deletion from database
- Service hooks (DeleteManyBefore/DeleteManyAfter) are executed for business logic
- Processing flow: Request -> ServiceBefore -> Database -> ServiceAfter -> Response
- The request body is bound to requestData[M] structure containing Ids slice
- Resources are identified by their IDs and converted to model instances for processing
- Supports soft delete and hard delete (purge) through options configuration
- Operation logging is automatically recorded to database
Mode 2: Custom Types (M != REQ or REQ != RSP) When types differ, the factory delegates full control to the service layer:
- Service layer has complete control over batch resource deletion
- No automatic database operations or service hooks
- Processing flow: Request -> Service.DeleteMany -> Response
- The request body is bound to the REQ type
- Service must handle all business logic and database operations
Type Parameters:
- M: Model type that implements types.Model interface (must be pointer to struct, e.g., *User)
- REQ: Request type that implements types.Request interface
- RSP: Response type that implements types.Response interface
Parameters:
- cfg: Optional controller configuration for customizing database handler
Returns:
- gin.HandlerFunc: A gin handler function for HTTP DELETE requests
HTTP Response:
- Success: 204 No Content (unified types) or 200 OK (custom types) with optional response data
- Error: 400 Bad Request for invalid parameters, 404 Not Found if resource doesn't exist, 500 Internal Server Error for other failures
Request Body Format (Unified Types):
{
"ids": ["id1", "id2", "id3"], // array of resource IDs to delete
"options": {
"purge": false // optional: true for hard delete, false for soft delete (default)
}
}
Response Format (Unified Types):
HTTP 204 No Content (empty response body)
Examples:
Unified types (automatic mode):
DeleteManyFactory[*model.User, *model.User, *model.User]()
// DELETE /users with {"ids": ["user1", "user2"], "options": {"purge": false}}
Custom types (manual mode):
DeleteManyFactory[*model.User, *DeleteManyUsersRequest, *DeleteManyUsersResponse]() // Service layer controls all batch deletion logic
func Export ¶
Export is a generic function to product gin handler to export resources to frontend. The resource type deponds on the type of interface types.Model.
If you want make a structure field as query parameter, you should add a "schema" tag for it. for example: schema:"name"
TODO:combine query parameter 'page' and 'size' into decoded types.Model FIX: retrieve records recursive (current not support in gorm.) https://stackoverflow.com/questions/69395891/get-recursive-field-values-in-gorm DB.Preload("Category.Category.Category").Find(&Category) its works for me.
Query parameters:
- All feilds of types.Model's underlying structure but excluding some special fields, such as "password", field value too large, json tag is "-", etc.
- `_expand`: strings (multiple items separated by ","). The responsed data to frontend will expanded(retrieve data from external table accoding to foreign key) For examples: /department/myid?_expand=children /department/myid?_expand=children,parent
- `_depth`: strings or interger. How depth to retrieve records from datab recursively, default to 1, value scope is [1,99]. For examples: /department/myid?_expand=children&_depth=3 /department/myid?_expand=children,parent&_depth=10
- `_fuzzy`: bool fuzzy match records in database, default to fase. For examples: /department/myid?_fuzzy=true
func ExportFactory ¶
func ExportFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
ExportFactory is a factory function to export resources to frontend.
func Get ¶
Get is a generic function to product gin handler to list resource in backend. The resource type deponds on the type of interface types.Model.
Query parameters:
- `_expand`: strings (multiple items separated by ","). The responsed data to frontend will expanded(retrieve data from external table accoding to foreign key) For examples: /department/myid?_expand=children /department/myid?_expand=children,parent
- `_depth`: strings or interger. How depth to retrieve records from datab recursively, default to 1, value scope is [1,99]. For examples: /department/myid?_expand=children&_depth=3 /department/myid?_expand=children,parent&_depth=10
Route parameters: - id: string or integer.
func GetFactory ¶
func GetFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
GetFactory is a factory function that produces a gin handler for retrieving a single resource. It supports two different processing modes based on the type relationship between M, REQ, and RSP:
Mode 1: Unified Types (M == REQ == RSP) When all three generic types are identical, the factory enables automatic resource management:
- Controller layer automatically handles resource retrieval from database
- Service hooks (GetBefore/GetAfter) are executed for business logic
- Processing flow: RouteParam -> ServiceBefore -> Database -> ServiceAfter -> Response
- Supports comprehensive query parameters for field expansion, caching, and selection
- Automatic caching support with configurable cache control
- Advanced features: deep recursive expansion, field selection, cache bypass
- Resource ID must be provided via route parameter (e.g., /api/users/123)
Mode 2: Custom Types (M != REQ or REQ != RSP) When types differ, the factory delegates full control to the service layer:
- Service layer has complete control over resource retrieval logic
- No automatic database operations or service hooks
- Processing flow: Request -> Service.Get -> Response
- The request body is bound to the REQ type
- Service must handle all business logic and database operations
Supported Query Parameters (Mode 1):
- _expand: Comma-separated list of fields to expand (foreign key relationships) Special value "all" expands all available fields defined in model's Expands() method
- _depth: Expansion depth for recursive relationships (1-99, default: 1) Controls how many levels deep to expand nested relationships
- _select: Comma-separated list of fields to select from database
- _nocache: Disable caching for this request (true/false, default: true - cache disabled)
- _index: Database index hint for query optimization
Type Parameters:
- M: Model type that implements types.Model interface (must be pointer to struct, e.g., *User)
- REQ: Request type that implements types.Request interface
- RSP: Response type that implements types.Response interface
Parameters:
- cfg: Optional controller configuration for customizing database handler
Returns:
- gin.HandlerFunc: A gin handler function for HTTP GET requests
HTTP Response (Mode 1):
- Success: 200 OK with resource data or cached byte response
- Not Found: 404 Not Found when resource doesn't exist or has empty ID/CreatedAt
- Error: 400 Bad Request for missing route parameter, 500 Internal Server Error for other failures
HTTP Response (Mode 2):
- Success: 200 OK with service-defined response structure
- Error: 400 Bad Request for invalid parameters, 500 Internal Server Error for other failures
Examples:
Unified types (automatic retrieval with expansion and caching):
GetFactory[*model.User, *model.User, *model.User]() // GET /users/123?_expand=department,roles&_depth=2&_nocache=false
Custom types (manual mode):
GetFactory[*model.User, *GetUserRequest, *GetUserResponse]() // Service layer controls all retrieval logic
Advanced Query Examples:
// Expand all relationships with depth GET /departments/123?_expand=all&_depth=3 // Select specific fields only GET /users/123?_select=id,name,email // Bypass cache for fresh data GET /users/123?_nocache=true // Combine expansion with field selection GET /users/123?_expand=department&_select=id,name,department&_depth=1
func ImportFactory ¶
func ImportFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
ImportFactory
func List ¶
List is a generic function to product gin handler to list resources in backend. The resource type deponds on the type of interface types.Model.
If you want make a structure field as query parameter, you should add a "schema" tag for it. for example: schema:"name"
TODO:combine query parameter 'page' and 'size' into decoded types.Model FIX: retrieve records recursive (current not support in gorm.) https://stackoverflow.com/questions/69395891/get-recursive-field-values-in-gorm DB.Preload("Category.Category.Category").Find(&Category) its works for me.
Query parameters:
- All feilds of types.Model's underlying structure but excluding some special fields, such as "password", field value too large, json tag is "-", etc.
- `_expand`: strings (multiple items separated by ","). The responsed data to frontend will expanded(retrieve data from external table accoding to foreign key) For examples: /department/myid?_expand=children /department/myid?_expand=children,parent
- `_depth`: strings or interger. How depth to retrieve records from datab recursively, default to 1, value scope is [1,99]. For examples: /department/myid?_expand=children&_depth=3 /department/myid?_expand=children,parent&_depth=10
- `_fuzzy`: bool fuzzy match records in database, default to fase. For examples: /department/myid?_fuzzy=true
func ListFactory ¶
func ListFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
ListFactory is a factory function that produces a gin handler for listing multiple resources. It supports two different processing modes based on the type relationship between M, REQ, and RSP:
Mode 1: Unified Types (M == REQ == RSP) When all three generic types are identical, the factory enables automatic resource management:
- Controller layer automatically handles resource listing from database
- Service hooks (ListBefore/ListAfter) are executed for business logic
- Processing flow: QueryParams -> ServiceBefore -> Database -> ServiceAfter -> Response
- Supports comprehensive query parameters for filtering, pagination, sorting, and expansion
- Automatic caching support with configurable cache control
- Built-in pagination with total count calculation
- Advanced features: cursor-based pagination, fuzzy search, field expansion, time range filtering
Mode 2: Custom Types (M != REQ or REQ != RSP) When types differ, the factory delegates full control to the service layer:
- Service layer has complete control over resource listing logic
- No automatic database operations or service hooks
- Processing flow: Request -> Service.List -> Response
- The request body is bound to the REQ type
- Service must handle all business logic, filtering, and database operations
Supported Query Parameters (Mode 1):
- Model fields: All fields with "schema" tag can be used as query parameters
- _page: Page number for pagination (starts from 1)
- _size: Number of items per page
- _expand: Comma-separated list of fields to expand (foreign key relationships)
- _depth: Expansion depth for recursive relationships (1-99, default: 1)
- _fuzzy: Enable fuzzy matching for string fields (true/false)
- _or: Use OR logic instead of AND for multiple conditions (true/false)
- _sortby: Field name for sorting (append " desc" for descending order)
- _select: Comma-separated list of fields to select
- _nocache: Disable caching for this request (true/false)
- _nototal: Skip total count calculation for better performance (true/false)
- _cursor_value: Cursor value for cursor-based pagination
- _cursor_fields: Fields to use for cursor-based pagination
- _cursor_next: Direction for cursor pagination (true for next, false for previous)
- _start_time: Start time for time range filtering (format: YYYY-MM-DD HH:mm:ss)
- _end_time: End time for time range filtering (format: YYYY-MM-DD HH:mm:ss)
- _column_name: Column name for time range filtering
- _index: Database index hint for query optimization
Type Parameters:
- M: Model type that implements types.Model interface (must be pointer to struct, e.g., *User)
- REQ: Request type that implements types.Request interface
- RSP: Response type that implements types.Response interface
Parameters:
- cfg: Optional controller configuration for customizing database handler
Returns:
- gin.HandlerFunc: A gin handler function for HTTP GET requests
HTTP Response (Mode 1):
- Success: 200 OK with {"items": [...], "total": count} or cached byte response
- Without total: 200 OK with {"items": [...]} when _nototal=true
- Error: 400 Bad Request for invalid parameters, 500 Internal Server Error for other failures
HTTP Response (Mode 2):
- Success: 200 OK with service-defined response structure
- Error: 400 Bad Request for invalid parameters, 500 Internal Server Error for other failures
Examples:
Unified types (automatic listing with rich query features):
ListFactory[*model.User, *model.User, *model.User]() // GET /users?name=john&_page=1&_size=10&_expand=department&_sortby=created_at desc
Custom types (manual mode):
ListFactory[*model.User, *ListUsersRequest, *ListUsersResponse]() // Service layer controls all listing logic
Advanced Query Examples:
// Fuzzy search with pagination GET /users?name=john&_fuzzy=true&_page=1&_size=20 // Expand relationships with depth GET /departments?_expand=children,parent&_depth=3 // Cursor-based pagination GET /users?_cursor_value=123&_cursor_next=true&_size=10 // Time range filtering GET /logs?_start_time=2024-01-01 00:00:00&_end_time=2024-01-31 23:59:59&_column_name=created_at
func Patch ¶
Patch is a generic function to product gin handler to partial update one resource. The resource type depends on the type of interface types.Model.
resource id must be specified. - specified in "query parameter `id`". - specified in "router parameter `id`".
which one or multiple resources desired modify. - specified in "query parameter". - specified in "http body data".
func PatchFactory ¶
func PatchFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
PatchFactory is a factory function that produces a gin handler for partially updating one resource. It supports two different processing modes based on the type relationship between M, REQ, and RSP:
Mode 1: Unified Types (M == REQ == RSP) When all three generic types are identical, the factory enables automatic resource management:
- Controller layer automatically handles partial resource update in database
- Service hooks (PatchBefore/PatchAfter) are executed for business logic
- Processing flow: Request -> ServiceBefore -> ModelBefore -> Database -> ModelAfter -> ServiceAfter -> Response
- Resource ID can be specified in two ways (route parameter has higher priority):
- Route parameter: PATCH /api/users/123
- Request body: PATCH /api/users with JSON {"id": "123", "name": "new name"}
- Only non-zero fields from request are applied to existing resource (partial update)
- Automatic setting of updated_by field to current user
- Validates resource existence before update
- Preserves original created_at and created_by fields automatically
Mode 2: Custom Types (M != REQ or REQ != RSP) When types differ, the factory delegates full control to the service layer:
- Service layer has complete control over partial resource update logic
- No automatic database operations or service hooks
- Processing flow: Request -> Service.Patch -> Response
- The request body is bound to the REQ type
- Service must handle all business logic, validation, and database operations
Partial Update Logic (Mode 1):
- Retrieves existing resource from database using provided ID
- Uses reflection to copy only non-zero fields from request to existing resource
- Maintains original timestamps and audit fields
- Updates only the modified fields in database
Type Parameters:
- M: Model type that implements types.Model interface (must be pointer to struct, e.g., *User)
- REQ: Request type that implements types.Request interface
- RSP: Response type that implements types.Response interface
Parameters:
- cfg: Optional controller configuration for customizing database handler
Returns:
- gin.HandlerFunc: A gin handler function for HTTP PATCH requests
HTTP Response:
- Success: 200 OK with the updated resource data
- Error: 400 Bad Request for invalid parameters, 404 Not Found if resource doesn't exist, 500 Internal Server Error for other failures
Resource ID Priority:
- Route parameter (/api/users/123) - highest priority
- Request body ID field - fallback if route parameter is empty
- Error if neither is provided
Examples:
Unified types (automatic partial update):
PatchFactory[*model.User, *model.User, *model.User]()
// Request: PATCH /users/123 with {"name": "John"} - only updates name field
Custom types (manual mode):
PatchFactory[*model.User, *PatchUserRequest, *PatchUserResponse]() // Service layer controls all partial update logic
func PatchManyFactory ¶
func PatchManyFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
PatchManyFactory is a generic factory function that creates a Gin handler for batch partial updating resources. It supports two processing modes based on type relationships:
1. **Unified Types Mode** (M == REQ == RSP):
- All type parameters represent the same underlying type
- Automatic database operations and service hooks are executed
- Request body is parsed as requestData[M] containing Items array
- Performs field-level partial updates by comparing existing and new values
- Four-phase processing: pre-patch hooks → database update → post-patch hooks → operation logging
2. **Custom Types Mode** (M != REQ or REQ != RSP):
- Different types for Model, Request, and Response
- Service layer controls all patch logic through PatchMany method
- No automatic database operations - service handles everything
- Custom request/response type handling
Type Parameters:
- M: Model type implementing types.Model interface (database entity)
- REQ: Request type implementing types.Request interface (input data structure)
- RSP: Response type implementing types.Response interface (output data structure)
Request Format (Unified Types Mode):
- Content-Type: application/json
- Body: {"items": [M, M, ...], "options": {"atomic": bool}}
- Empty body is allowed (treated as no-op)
- Only non-zero fields in request items will be updated (partial update behavior)
Response Format:
- Success (200): Updated resource data with operation summary
- Error (400): Invalid request parameters
- Error (500): Internal server error
Automatic Features (Unified Types Mode):
- Service hooks: PatchManyBefore/PatchManyAfter for business logic
- Field-level partial update logic with existing record retrieval
- Database batch update operations
- Operation logging with request/response capture
- Error handling and logging throughout all phases
- Request validation and empty body handling
The function handles both empty and non-empty request bodies gracefully, with comprehensive error handling and detailed operation logging for audit purposes. Unlike UpdateMany, this function performs partial updates by only modifying non-zero fields.
func Update ¶
Update is a generic function to product gin handler to update one resource. The resource type depends on the type of interface types.Model.
Update will update one resource and resource "ID" must be specified, which can be specify in "router parameter `id`" or "http body data".
"router parameter `id`" has more priority than "http body data". It will skip decode id from "http body data" if "router parameter `id`" not empty.
func UpdateFactory ¶
func UpdateFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
UpdateFactory is a factory function that produces a gin handler for updating one resource. It supports two different processing modes based on the type relationship between M, REQ, and RSP:
Mode 1: Unified Types (M == REQ == RSP) When all three generic types are identical, the factory enables automatic resource management:
- Controller layer automatically handles resource update in database
- Service hooks (UpdateBefore/UpdateAfter) are executed for business logic
- Processing flow: Request -> ServiceBefore -> ModelBefore -> Database -> ModelAfter -> ServiceAfter -> Response
- Resource ID can be specified in two ways (route parameter has higher priority):
- Route parameter: PUT /api/users/123
- Request body: PUT /api/users with JSON {"id": "123", "name": "new name"}
- Automatic preservation of original created_at and created_by fields
- Automatic setting of updated_by field to current user
- Validates resource existence before update
Mode 2: Custom Types (M != REQ or REQ != RSP) When types differ, the factory delegates full control to the service layer:
- Service layer has complete control over resource update logic
- No automatic database operations or service hooks
- Processing flow: Request -> Service.Update -> Response
- The request body is bound to the REQ type
- Service must handle all business logic, validation, and database operations
Type Parameters:
- M: Model type that implements types.Model interface (must be pointer to struct, e.g., *User)
- REQ: Request type that implements types.Request interface
- RSP: Response type that implements types.Response interface
Parameters:
- cfg: Optional controller configuration for customizing database handler
Returns:
- gin.HandlerFunc: A gin handler function for HTTP PUT requests
HTTP Response:
- Success: 200 OK with the updated resource data
- Error: 400 Bad Request for invalid parameters, 404 Not Found if resource doesn't exist, 500 Internal Server Error for other failures
Resource ID Priority:
- Route parameter (/api/users/123) - highest priority
- Request body ID field - fallback if route parameter is empty
- Error if neither is provided
Examples:
Unified types (automatic mode):
UpdateFactory[*model.User, *model.User, *model.User]()
// Supports: PUT /users/123 or PUT /users with {"id": "123", "name": "John"}
Custom types (manual mode):
UpdateFactory[*model.User, *UpdateUserRequest, *UpdateUserResponse]() // Service layer controls all update logic
func UpdateMany ¶
UpdateMany
func UpdateManyFactory ¶
func UpdateManyFactory[M types.Model, REQ types.Request, RSP types.Response](cfg ...*types.ControllerConfig[M]) gin.HandlerFunc
UpdateManyFactory is a generic factory function that creates a Gin handler for batch updating resources. It supports two processing modes based on type relationships:
1. **Unified Types Mode** (M == REQ == RSP):
- All type parameters represent the same underlying type
- Automatic database operations and service hooks are executed
- Request body is parsed as requestData[M] containing Items array
- Automatic field population (UpdatedBy) and operation logging
- Four-phase processing: pre-update hooks → database update → post-update hooks → operation logging
2. **Custom Types Mode** (M != REQ or REQ != RSP):
- Different types for Model, Request, and Response
- Service layer controls all update logic through UpdateMany method
- No automatic database operations - service handles everything
- Custom request/response type handling
Type Parameters:
- M: Model type implementing types.Model interface (database entity)
- REQ: Request type implementing types.Request interface (input data structure)
- RSP: Response type implementing types.Response interface (output data structure)
Request Format (Unified Types Mode):
- Content-Type: application/json
- Body: {"items": [M, M, ...], "options": {"atomic": bool}}
- Empty body is allowed (treated as no-op)
Response Format:
- Success (200): Updated resource data with operation summary
- Error (400): Invalid request parameters
- Error (500): Internal server error
Automatic Features (Unified Types Mode):
- Service hooks: UpdateManyBefore/UpdateManyAfter for business logic
- Database batch update operations
- Operation logging with request/response capture
- Error handling and logging throughout all phases
- Request validation and empty body handling
The function handles both empty and non-empty request bodies gracefully, with comprehensive error handling and detailed operation logging for audit purposes.
Types ¶
This section is empty.