How to Use the apix/response Utilities in Gorig for Consistent API Responses
The apix/response package centralizes JSON response formatting in the Gorig framework, providing standardized envelopes with optional camel-case transformation and predefined status codes.
The jom-io/gorig repository includes a robust apix/response package designed to eliminate repetitive JSON formatting in Gin handlers. Instead of manually constructing c.JSON() calls throughout your controllers, these utilities enforce a uniform response structure {code, msg, data} while centralizing HTTP status mapping and payload transformation.
Core Design and Architecture
The response utilities implement four key architectural patterns that promote consistency across the service layer.
Standardized JSON Envelope
Every response follows a strict contract: { "code": <int>, "msg": <string>, "data": <any> }. In /apix/response/response.go, the ReturnJson function (lines 58-71) constructs this envelope and handles the actual write operation to Gin's response writer. This guardian pattern prevents duplicate writes by checking c.Writer.Written() before serializing the payload.
Camel-Case Transformation
The package provides optional transformation of struct fields from snake_case (common in Go tags) to camelCase for frontend consumption. The internal toCamel function handles the conversion logic, while SetToCamel and GetToCamel (defined in /apix/response/response.go, lines 14-55) manage the per-request toggle flag stored in Gin's context.
Predefined Response Shortcuts
Rather than manually assembling codes and messages, handlers invoke purpose-built helpers. Functions including Success, Fail, ErrorTokenAuthFail, ErrorParam, and ErrorSystem (implemented in /apix/response/response.go, lines 79-146) map semantic outcomes to the appropriate HTTP status codes and internal error constants.
Centralized Status Definitions
All numeric codes and default messages live in /global/consts/consts.go (specifically lines 34-48 and 96-106). Constants such as CurdStatusOkCode, ValidatorParamsCheckFailCode, and ErrorsTokenBaseInfo provide a single source of truth for status semantics across the entire application.
Key Implementation Details
The ReturnJson Guardian
The ReturnJson function serves as the sole exit point for JSON serialization. When called, it checks if the response has already been written to prevent duplicate writes, optionally transforms the payload via toCamel if the flag is set, and finally executes Gin's c.JSON() with the constructed envelope.
Context-Aware Camel Conversion
To activate camel-case conversion for a specific request, handlers call response.SetToCamel(c) before invoking a success helper. This stores a boolean flag in the Gin context that ReturnJson checks when serializing the data payload. The conversion applies only to the data field, leaving the envelope's code and msg fields untouched.
Practical Usage Examples
Simple Success Response
For endpoints that only need to signal completion without returning data, use the S() shortcut:
func Ping(c *gin.Context) {
// Returns {"code":200,"msg":"Success","data":null}
response.S(c)
}
Success with Structured Data
Return a struct using the Success helper, which automatically applies the CurdStatusOkCode and corresponding message:
type User struct {
ID int `json:"id"`
Name string `json:"user_name"` // appears as "user_name" by default
}
func GetUser(c *gin.Context) {
u := User{ID: 42, Name: "Alice"}
response.Success(c, "", u)
}
Camel-Case Transformation
Enable camel-case conversion to transform user_name into userName for the frontend:
func GetUserCamel(c *gin.Context) {
response.SetToCamel(c) // enable conversion
u := User{ID: 42, Name: "Alice"}
response.Success(c, "", u) // outputs {"id":42,"userName":"Alice"}
}
Validation Error Handling
Handle binding errors using the dedicated validator helper:
func CreateItem(c *gin.Context) {
var payload Item
if err := c.ShouldBindJSON(&payload); err != nil {
// Returns 400 with code -400300 and validator message
response.ValidatorError(c, err)
return
}
// ... business logic ...
}
Authentication Failures
Use predefined authentication error helpers for consistent unauthorized responses:
func Protected(c *gin.Context) {
if !hasValidToken(c) {
response.ErrorTokenAuthFail(c) // 401 with token error code
return
}
// ... protected logic ...
}
Custom Error with Context
Attach additional context to failure responses using the Fail helper:
func DeleteItem(c *gin.Context) {
if err := service.Delete(id); err != nil {
response.Fail(c,
consts.CurdDeleteFailCode,
consts.CurdDeleteFailMsg,
map[string]int{"failedId": id})
return
}
response.S(c)
}
Summary
- The
apix/responsepackage enforces a uniform JSON envelope ({code, msg, data}) across all Gin handlers in thejom-io/gorigframework. ReturnJsonin/apix/response/response.go(lines 58-71) serves as the central serialization point, preventing duplicate writes and handling camel-case conversion.- Use
SetToCamelto enable automatic transformation of struct fields fromsnake_casetocamelCasefor frontend compatibility. - Predefined helpers like
Success,Fail, andErrorTokenAuthFailreference constants from/global/consts/consts.goto maintain semantic consistency. - The
S()shortcut provides a concise way to return successful empty responses.
Frequently Asked Questions
How do I enable camel-case conversion for a specific API response?
Call response.SetToCamel(c) before invoking any success helper. This sets a context flag that instructs ReturnJson to transform the data payload from snake_case to camelCase during serialization. The flag persists for the duration of the request but only affects the current response.
Where are the HTTP status codes and response messages defined?
All numeric codes and default messages are centralized in /global/consts/consts.go (specifically lines 34-48 and 96-106). Constants like CurdStatusOkCode and ValidatorParamsCheckFailCode provide type-safe references used throughout the response helpers, ensuring consistency across the codebase.
What prevents duplicate JSON responses when using these utilities?
The ReturnJson function checks c.Writer.Written() before attempting to write the response. If Gin has already written to the response writer (e.g., from middleware or earlier handler logic), the function returns immediately without attempting a second write, preventing runtime panics.
Which helper should I use for validation errors in request payloads?
Use response.ValidatorError(c, err) when handling errors from c.ShouldBindJSON() or similar Gin binding operations. This helper automatically extracts validation details, applies the ValidatorParamsCheckFailCode constant, and returns a 400 Bad Request with the specific field errors.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →