Documentation
¶
Index ¶
- Constants
- Variables
- func CopyRequestBody(c *gin.Context) (any, error)
- func CopyRequestBodyAsBytes(c *gin.Context) ([]byte, error)
- func GetIDFromContext(c *gin.Context, key string) (entigo.ID, error)
- func GetQueryParamInt(c *gin.Context, key string, defaultValue int) int
- func GetUrlParamID(c *gin.Context, key string) (entigo.ID, error)
- func GetUrlParamInt(c *gin.Context, key string, defaultValue int) int
- func HandleDBError(err error) error
- func IsAdmin(c *gin.Context) bool
- func IsAdminOrCurrentUser(c *gin.Context, userId entigo.ID) bool
- func IsCurrentUser(c *gin.Context, userId entigo.ID) bool
- func IsErrDuplicateKey(err error) bool
- func IsErrNotFound(err error) bool
- func QueryParamsToQueryMap(c *gin.Context) entigo.QueryMap
- func RequireContext(c *gin.Context) context.Context
- func SendError(c *gin.Context, httpStatus int, errorCode int, errorMsg string)
- func SendOK(c *gin.Context, message string, data any, args ...any)
- func ToCSV(entity any, opts ...CSVOption) ([]byte, error)
- func WriteError(c *gin.Context, err error)
- type BaseHandler
- func (h *BaseHandler[S, T]) BuildFiltersFromContext(c *gin.Context) map[string]any
- func (h *BaseHandler[S, T]) Create(c *gin.Context)
- func (h *BaseHandler[S, T]) CreateOrUpdate(c *gin.Context, keyColumn string)
- func (h *BaseHandler[S, T]) Delete(c *gin.Context)
- func (h *BaseHandler[S, T]) Error(c *gin.Context, err error)
- func (h *BaseHandler[S, T]) Export(c *gin.Context)
- func (h *BaseHandler[S, T]) Get(c *gin.Context)
- func (h *BaseHandler[S, T]) GetID(c *gin.Context, idParamName string) (entigo.ID, error)
- func (h *BaseHandler[S, T]) GetIDParam(c *gin.Context, idParamName string) (entigo.ID, error)
- func (h *BaseHandler[S, T]) GetResponseData(data any) (any, error)
- func (h *BaseHandler[S, T]) GetResponseDataAsSlice(data any) ([]any, error)
- func (h *BaseHandler[S, T]) IsAdminRequest(c *gin.Context) bool
- func (h *BaseHandler[S, T]) List(c *gin.Context)
- func (h *BaseHandler[S, T]) ListWith(c *gin.Context, args ...any)
- func (h *BaseHandler[S, T]) Patch(c *gin.Context)
- func (h *BaseHandler[S, T]) Success(c *gin.Context, message string, data any, args ...any)
- func (h *BaseHandler[S, T]) Update(c *gin.Context)
- type CSVOption
- type CSVOptions
- type CustomError
- func NewBadRequestError(message string) *CustomError
- func NewConflictError(message string) *CustomError
- func NewCustomError(message string, errorCode int, httpStatus int) *CustomError
- func NewForbiddenError(message string) *CustomError
- func NewInternalServerError(message string) *CustomError
- func NewNotFoundError(message string) *CustomError
- func NewRequestTimeoutError(message string) *CustomError
- func NewTooManyRequestsError(message string) *CustomError
- func NewUnauthorizedError(message string) *CustomError
- type Date
- type HandlerHooks
- type Response
Constants ¶
const ( CommaSeparator = ',' SemicolonSeparator = ';' TabSeparator = '\t' )
Common CSV delimiters.
const ( ErrCodeBadRequest = 40000 ErrCodeForbidden = 40300 ErrCodeNotFound = 40400 ErrCodeRequestTimeout = 40800 ErrCodeTooManyRequests = 42900 ErrCodeConflict = 40900 ErrCodeInternalServerError = 50000 )
Commonly used error codes.
Variables ¶
var ( ErrBadRequest = NewCustomError("Bad request", ErrCodeBadRequest, http.StatusBadRequest) ErrForbidden = NewCustomError("Forbidden", ErrCodeForbidden, http.StatusForbidden) ErrNotFound = NewCustomError("Not found", ErrCodeNotFound, http.StatusNotFound) ErrTooManyRequests = NewCustomError("Too many requests", ErrCodeTooManyRequests, http.StatusTooManyRequests) ErrInternalServer = NewCustomError("Internal server error", ErrCodeInternalServerError, http.StatusInternalServerError) ErrRequestTimeout = NewCustomError("Request timed out", ErrCodeRequestTimeout, http.StatusRequestTimeout) )
Predefined errors for common HTTP error responses.
Functions ¶
func CopyRequestBody ¶
CopyRequestBody reads the request body and returns it as the appropriate type based on the Content-Type header: map[string]any for JSON, string for plain text, or raw bytes for other types. The body is restored for subsequent reads.
func CopyRequestBodyAsBytes ¶
CopyRequestBodyAsBytes reads the request body into a byte slice and restores the body so it can be read again by subsequent handlers.
func GetIDFromContext ¶
GetIDFromContext retrieves an entigo.ID from the Gin context by key.
func GetQueryParamInt ¶
GetQueryParamInt extracts an integer query parameter, returning defaultValue on error.
func GetUrlParamID ¶
GetUrlParamID extracts an entigo.ID from a URL parameter.
func GetUrlParamInt ¶
GetUrlParamInt extracts an integer URL parameter, returning defaultValue on error.
func HandleDBError ¶
HandleDBError translates database-related errors into user-friendly CustomErrors. It handles context cancellation, GORM errors, and PostgreSQL-specific errors.
func IsAdminOrCurrentUser ¶
IsAdminOrCurrentUser reports whether the caller is an admin or the specified user.
func IsCurrentUser ¶
IsCurrentUser reports whether the given userId matches the authenticated user ID, or whether the caller is an admin.
func IsErrDuplicateKey ¶
IsErrDuplicateKey reports whether the error is a PostgreSQL unique violation (code 23505).
func IsErrNotFound ¶
IsErrNotFound reports whether the error is a GORM record-not-found error.
func QueryParamsToQueryMap ¶
QueryParamsToQueryMap converts Gin request query parameters to an entigo.QueryMap.
func RequireContext ¶
RequireContext creates a context.Context from the Gin request context, populated with common request metadata (user ID, IP, role flags, etc.). Keys use entigo.CtxKey* typed constants to ensure correct retrieval in the service layer.
func SendError ¶
SendError sends a JSON error response with the given HTTP status, error code, and message.
func SendOK ¶
SendOK sends a JSON success response with HTTP 200 OK status. Additional key-value pairs can be provided via args (must be string key followed by value).
Example:
SendOK(c, "Success", users, "total", 100, "page", 1)
Produces:
{"ok": true, "message": "Success", "data": users, "total": 100, "page": 1}
func ToCSV ¶
ToCSV converts a slice of structs (or a single struct) to CSV bytes.
Usage:
type User struct {
ID int `csv:"id"`
Name string `csv:"name"`
}
users := []User{{ID: 1, Name: "John"}}
data, err := ToCSV(users, WithComma(SemicolonSeparator))
func WriteError ¶
WriteError translates an error into an appropriate HTTP error response. It checks for gin.Error, gorm.ErrRecordNotFound, and CustomError types to determine the correct HTTP status and error code. Unrecognized errors result in a 500 Internal Server Error.
Types ¶
type BaseHandler ¶
type BaseHandler[S entigo.EntityService[T], T entigo.Entity] struct { Logger *slog.Logger Hooks HandlerHooks[T] // contains filtered or unexported fields }
BaseHandler provides generic CRUD HTTP handler methods for any entity type. It uses the entigo.EntityService for data access and the entigo.Converter for automatic DTO transformation.
func NewBaseHandler ¶
func NewBaseHandler[S entigo.EntityService[T], T entigo.Entity](service S, logger ...*slog.Logger) BaseHandler[S, T]
NewBaseHandler creates a new BaseHandler for the given entity service. An optional logger can be provided; otherwise slog.Default() is used. The tracer is obtained from the service.
func (*BaseHandler[S, T]) BuildFiltersFromContext ¶
func (h *BaseHandler[S, T]) BuildFiltersFromContext(c *gin.Context) map[string]any
BuildFiltersFromContext builds entity filters from the request query parameters.
func (*BaseHandler[S, T]) Create ¶
func (h *BaseHandler[S, T]) Create(c *gin.Context)
Create handles POST requests to create a new entity.
func (*BaseHandler[S, T]) CreateOrUpdate ¶
func (h *BaseHandler[S, T]) CreateOrUpdate(c *gin.Context, keyColumn string)
CreateOrUpdate handles requests to create or update an entity based on a key column. If an entity with the given key value exists, it is updated; otherwise a new one is created.
func (*BaseHandler[S, T]) Delete ¶
func (h *BaseHandler[S, T]) Delete(c *gin.Context)
Delete handles DELETE requests to remove an entity by ID.
func (*BaseHandler[S, T]) Error ¶
func (h *BaseHandler[S, T]) Error(c *gin.Context, err error)
Error logs the error and sends an appropriate HTTP error response.
func (*BaseHandler[S, T]) Export ¶
func (h *BaseHandler[S, T]) Export(c *gin.Context)
Export handles requests to export entities as a CSV file.
func (*BaseHandler[S, T]) Get ¶
func (h *BaseHandler[S, T]) Get(c *gin.Context)
Get handles GET requests to retrieve a single entity by ID.
func (*BaseHandler[S, T]) GetID ¶
GetID retrieves an entity ID by checking the URL parameter, query parameter, and context value in that order.
func (*BaseHandler[S, T]) GetIDParam ¶
GetIDParam retrieves an entity ID from a URL path parameter.
func (*BaseHandler[S, T]) GetResponseData ¶
func (h *BaseHandler[S, T]) GetResponseData(data any) (any, error)
GetResponseData converts entity data to its response DTO representation. It handles both single entities and slices of entities.
func (*BaseHandler[S, T]) GetResponseDataAsSlice ¶
func (h *BaseHandler[S, T]) GetResponseDataAsSlice(data any) ([]any, error)
GetResponseDataAsSlice converts entity data to a slice of response DTOs. Single entities are wrapped in a one-element slice.
func (*BaseHandler[S, T]) IsAdminRequest ¶
func (h *BaseHandler[S, T]) IsAdminRequest(c *gin.Context) bool
IsAdminRequest reports whether the current request is from an admin user, based on the role stored in the Gin context.
func (*BaseHandler[S, T]) List ¶
func (h *BaseHandler[S, T]) List(c *gin.Context)
List handles GET requests to list entities with pagination, filtering, and ordering.
func (*BaseHandler[S, T]) ListWith ¶
func (h *BaseHandler[S, T]) ListWith(c *gin.Context, args ...any)
ListWith handles GET requests to list entities with additional WHERE conditions. The args parameter is passed to entigo.WithWhereArgs for extra filtering.
func (*BaseHandler[S, T]) Patch ¶
func (h *BaseHandler[S, T]) Patch(c *gin.Context)
Patch handles PATCH requests to partially update an entity.
func (*BaseHandler[S, T]) Success ¶
Success converts the data to its response DTO and sends a success response.
func (*BaseHandler[S, T]) Update ¶
func (h *BaseHandler[S, T]) Update(c *gin.Context)
Update handles PUT requests to update an existing entity.
type CSVOption ¶
type CSVOption func(*CSVOptions)
CSVOption defines the function type for the options pattern.
func WithComma ¶
WithComma sets a custom delimiter for CSV fields. Common delimiters: CommaSeparator, SemicolonSeparator, TabSeparator.
func WithUseCRLF ¶
WithUseCRLF sets line ending to CRLF instead of LF.
type CSVOptions ¶
type CSVOptions struct {
UseCRLF bool // Use CRLF as line terminator
Comma rune // CSV field separator
}
CSVOptions holds all configurable CSV options.
type CustomError ¶
CustomError represents an HTTP-aware error with a message, error code, and HTTP status.
func NewBadRequestError ¶
func NewBadRequestError(message string) *CustomError
NewBadRequestError creates a 400 Bad Request error with a custom message.
func NewConflictError ¶
func NewConflictError(message string) *CustomError
NewConflictError creates a 409 Conflict error with a custom message.
func NewCustomError ¶
func NewCustomError(message string, errorCode int, httpStatus int) *CustomError
NewCustomError creates a new CustomError with the given message, error code, and HTTP status.
func NewForbiddenError ¶
func NewForbiddenError(message string) *CustomError
NewForbiddenError creates a 403 Forbidden error with a custom message.
func NewInternalServerError ¶
func NewInternalServerError(message string) *CustomError
NewInternalServerError creates a 500 Internal Server Error with a custom message.
func NewNotFoundError ¶
func NewNotFoundError(message string) *CustomError
NewNotFoundError creates a 404 Not Found error with a custom message.
func NewRequestTimeoutError ¶
func NewRequestTimeoutError(message string) *CustomError
NewRequestTimeoutError creates a 408 Request Timeout error with a custom message.
func NewTooManyRequestsError ¶
func NewTooManyRequestsError(message string) *CustomError
NewTooManyRequestsError creates a 429 Too Many Requests error with a custom message.
func NewUnauthorizedError ¶
func NewUnauthorizedError(message string) *CustomError
NewUnauthorizedError creates a 401 Unauthorized error with a custom message.
func (CustomError) Error ¶
func (e CustomError) Error() string
Error implements the error interface.
type Date ¶
type Date string
Date is a string type representing a date in "2006-01-02" format.
func (Date) AsTimeOrZero ¶
AsTimeOrZero parses the Date into a time.Time value, returning the zero time on error.
type HandlerHooks ¶
type HandlerHooks[T entigo.Entity] struct { BeforeCreate func(c *gin.Context, entity T) error AfterCreate func(c *gin.Context, entity T) error BeforeUpdate func(c *gin.Context, entity T) error AfterUpdate func(c *gin.Context, entity T) error BeforePatch func(c *gin.Context, input any) error AfterPatch func(c *gin.Context, input any) error }
HandlerHooks provides lifecycle hooks for BaseHandler CRUD operations. Each hook receives the Gin context and the entity being processed.