Documentation
¶
Index ¶
- Variables
- type Cache
- type ControllerConfig
- type ControllerContext
- type Database
- type DatabaseContext
- type DatabaseOption
- type DistributedCache
- type ESDocumenter
- type Event
- type Initializer
- type Logger
- type Model
- type ModelContext
- type Module
- type QueryConfig
- type RBAC
- type Request
- type Response
- type Service
- type ServiceContext
- func (sc *ServiceContext) Context() context.Context
- func (sc *ServiceContext) Cookie(name string) (string, error)
- func (sc *ServiceContext) Data(code int, contentType string, data []byte)
- func (sc *ServiceContext) DatabaseContext() *DatabaseContext
- func (sc *ServiceContext) Encode(w io.Writer, event Event) error
- func (sc *ServiceContext) FormFile(name string) (*multipart.FileHeader, error)
- func (sc *ServiceContext) GetPhase() consts.Phase
- func (sc *ServiceContext) HTML(code int, name string, obj any)
- func (sc *ServiceContext) PostForm(key string) string
- func (sc *ServiceContext) Redirect(code int, location string)
- func (sc *ServiceContext) RequiresAuth() bool
- func (sc *ServiceContext) SSE() *sseBuilder
- func (sc *ServiceContext) SSEvent(name string, message any)
- func (sc *ServiceContext) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)
- func (sc *ServiceContext) SetPhase(phase consts.Phase)
- func (sc *ServiceContext) Stream(step func(io.Writer) bool)
- func (sc *ServiceContext) WithPhase(phase consts.Phase) *ServiceContext
- type ServiceError
- type StandardLogger
- type StructuredLogger
- type ZapLogger
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrEntryNotFound = errors.New("cache entry not found")
ErrEntryNotFound is returned when a cache entry is not found.
Functions ¶
This section is empty.
Types ¶
type Cache ¶
type Cache[T any] interface { // Get retrieves a value from the cache by key. // Returns ErrEntryNotFound if the key does not exist. Get(key string) (T, error) // Peek retrieves a value from the cache by key without affecting its position or access time. // Returns ErrEntryNotFound if the key does not exist. Peek(key string) (T, error) // Set stores a value in the cache with the specified TTL. // A zero TTL means the entry will not expire. Set(key string, value T, ttl time.Duration) error // Delete removes a key from the cache. // Returns ErrEntryNotFound if the key does not exist. Delete(key string) error // Exists checks if a key exists in the cache. // Returns true if the key exists, false otherwise. Exists(key string) bool // Len returns the number of entries currently stored in the cache. Len() int // Clear removes all entries from the cache. Clear() // WithContext replaces the cache internal context that used to propagate span context. WithContext(ctx context.Context) Cache[T] }
Cache provides a unified caching abstraction with consistent error handling. Supports TTL, context-aware operations, and distributed tracing.
Type Parameters:
- T: Serializable data type
Error Handling:
- Get/Peek return ErrEntryNotFound when key doesn't exist
- All operations return errors for proper error handling
type ControllerConfig ¶
type ControllerContext ¶
type ControllerContext struct {
Username string // currrent login user.
UserID string // currrent login user id
Route string
Params map[string]string
Query url.Values
RequestID string
TraceID string
PSpanID string
SpanID string
Seq int
}
func NewControllerContext ¶
func NewControllerContext(c *gin.Context) *ControllerContext
NewControllerContext creates a ControllerContext from gin.Context
type Database ¶
type Database[M Model] interface { // Create inserts one or multiple records into the database. Create(objs ...M) error // Delete removes one or multiple records from the database. Delete(objs ...M) error // Update modifies one or multiple records in the database. Update(objs ...M) error // UpdateByID updates a single field of a record by its ID. UpdateByID(id string, key string, value any) error // List retrieves multiple records matching the query conditions. List(dest *[]M) error // Get retrieves a single record by its ID. Get(dest M, id string) error // First retrieves the first record ordered by primary key. First(dest M) error // Last retrieves the last record ordered by primary key. Last(dest M) error // Take retrieves the first record in no specified order. Take(dest M) error // Count returns the total number of records matching the query conditions. Count(*int64) error // Cleanup permanently deletes all soft-deleted records. Cleanup() error // Health checks the database connectivity and basic operations. Health() error // Transaction executes a function within a transaction (single-model, recommended). Transaction(fn func(txDB Database[M]) error) error // TransactionFunc executes a function within a transaction (multi-model, requires WithTx). TransactionFunc(fn func(tx any) error) error DatabaseOption[M] }
Database provides comprehensive database operations for any model type. Supports CRUD operations, flexible querying, transactions, and advanced features.
Type Parameters:
- M: Model type that implements Model interface
Features:
- CRUD operations with automatic timestamp management
- Flexible querying with various finder methods
- Transaction support for single and multi-model operations
- Health monitoring and cleanup capabilities
- Optional caching support for improved performance
The interface embeds DatabaseOption[M] to provide chainable query building.
type DatabaseContext ¶
type DatabaseContext struct {
Username string // currrent login user.
UserID string // currrent login user id
Route string
Params map[string]string
Query url.Values
RequestID string
TraceID string
PSpanID string
SpanID string
Seq int
// contains filtered or unexported fields
}
func NewDatabaseContext ¶
func NewDatabaseContext(c *gin.Context, ctxs ...context.Context) *DatabaseContext
NewDatabaseContext creates a DatabaseContext from gin.Context
You can pass the custom context.Context to propagate span tracing, otherwise use the c.Request.Context().
func (*DatabaseContext) Context ¶
func (dc *DatabaseContext) Context() context.Context
Context converts *DatabaseContext to context.Context. It starts from the underlying ctx.context and conditionally injects extra metadata.
type DatabaseOption ¶
type DatabaseOption[M Model] interface { // WithDB sets a custom database instance for operations. WithDB(any) Database[M] // WithTx sets transaction context for operations (used with TransactionFunc). WithTx(tx any) Database[M] // WithTable sets a custom table name for operations. WithTable(name string) Database[M] // WithDebug enables debug mode to show detailed SQL queries. WithDebug() Database[M] // WithQuery sets query conditions based on model fields or raw SQL. WithQuery(query M, config ...QueryConfig) Database[M] // WithCursor enables cursor-based pagination for efficient large dataset traversal. WithCursor(string, bool, ...string) Database[M] // WithTimeRange applies a time range filter to the query. WithTimeRange(columnName string, startTime time.Time, endTime time.Time) Database[M] // WithSelect specifies fields to select in queries. WithSelect(columns ...string) Database[M] // WithSelectRaw specifies raw SQL for field selection. WithSelectRaw(query any, args ...any) Database[M] // WithIndex specifies database index hints for query optimization (MySQL only). WithIndex(indexName string, hint ...consts.IndexHintMode) Database[M] // WithRollback configures a rollback function for manual transaction control. WithRollback(rollbackFunc func()) Database[M] // WithJoinRaw adds a raw JOIN clause to the query. WithJoinRaw(query string, args ...any) Database[M] // WithLock adds row-level locking to SELECT queries (must be used within a transaction). WithLock(mode ...consts.LockMode) Database[M] // WithBatchSize sets the batch size for bulk operations. WithBatchSize(size int) Database[M] // WithPagination applies pagination parameters (page, size) to the query. WithPagination(page, size int) Database[M] // WithLimit restricts the number of returned records. WithLimit(limit int) Database[M] // WithExclude excludes records matching specified conditions. WithExclude(map[string][]any) Database[M] // WithOrder adds ORDER BY clause to sort query results. WithOrder(order string) Database[M] // WithExpand enables eager loading of specified associations. WithExpand(expand []string, order ...string) Database[M] // WithPurge controls whether to permanently delete records (hard delete). WithPurge(...bool) Database[M] // WithCache enables query result caching. WithCache(...bool) Database[M] // WithOmit excludes specified fields from operations. WithOmit(...string) Database[M] // WithDryRun enables dry-run mode to preview SQL without executing. WithDryRun() Database[M] // WithoutHook disables model hooks for the operation. WithoutHook() Database[M] }
DatabaseOption provides chainable query building methods for database operations. All methods return Database[M] to support method chaining.
type DistributedCache ¶
type DistributedCache[T any] interface { Cache[T] // SetWithSync stores a value in both local and distributed cache with synchronization. SetWithSync(key string, value T, localTTL time.Duration, remoteTTL time.Duration) error // GetWithSync retrieves a value from local cache first, then from distributed cache if not found. GetWithSync(key string, localTTL time.Duration) (T, error) // DeleteWithSync removes a value from both local and distributed cache with synchronization. DeleteWithSync(key string) error }
DistributedCache provides a two-level distributed caching system combining local memory cache with Redis backend for synchronized caching across multiple nodes.
Type Parameters:
- T: Serializable data type
Features:
- Automatic cache synchronization across multiple application instances
- Configurable TTL for both local and distributed cache layers
- Event-driven cache invalidation using Kafka messaging
- Thread-safe concurrent operations
type ESDocumenter ¶
type ESDocumenter interface {
// Document returns a map representing an Elasticsearch document.
// The returned map should contain all fields to be indexed, where:
// - keys are field names (string type)
// - values are field values (any type)
//
// Implementation notes:
// 1. The returned map should only contain JSON-serializable values.
// 2. Field names should match those defined in the Elasticsearch mapping.
// 3. Complex types (like nested objects or arrays) should be correctly
// represented in the returned map.
//
// Example:
// return map[string]any{
// "id": "1234",
// "title": "Sample Document",
// "tags": []string{"tag1", "tag2"},
// }
Document() map[string]any
// GetID returns a string that uniquely identifies the document.
// This ID is typically used as the Elasticsearch document ID.
//
// Implementation notes:
// 1. The ID should be unique within the index.
// 2. If no custom ID is needed, consider returning an empty string
// to let Elasticsearch auto-generate an ID.
// 3. The ID should be a string, even if it's originally a numeric value.
//
// Example:
// return "user_12345"
GetID() string
}
ESDocumenter represents a document that can be indexed into Elasticsearch. Types implementing this interface should be able to convert themselves into a document format suitable for Elasticsearch indexing.
type Event ¶ added in v0.10.2
Event is an alias for sse.Event. This allows users to use types.Event instead of importing internal/sse directly.
type Initializer ¶ added in v0.9.2
type Initializer interface {
Init() error
}
Initializer defines components that perform one-time application setup. Typical implementations include config loaders, logger setup, and resource init.
type Logger ¶
type Logger interface {
With(fields ...string) Logger
WithObject(name string, obj zapcore.ObjectMarshaler) Logger
WithArray(name string, arr zapcore.ArrayMarshaler) Logger
WithControllerContext(*ControllerContext, consts.Phase) Logger
WithServiceContext(*ServiceContext, consts.Phase) Logger
WithDatabaseContext(*DatabaseContext, consts.Phase) Logger
StandardLogger
StructuredLogger
ZapLogger
}
Logger combines standard, structured, and zap logging with context helpers. With* methods attach fields, objects/arrays, and request/service/db context.
type Model ¶
type Model interface {
GetTableName() string // GetTableName returns the table name.
GetID() string
SetID(id ...string) // SetID method will automatically set the id if id is empty.
ClearID() // ClearID always set the id to empty.
GetCreatedBy() string
GetUpdatedBy() string
GetCreatedAt() time.Time
GetUpdatedAt() time.Time
SetCreatedBy(string)
SetUpdatedBy(string)
SetCreatedAt(time.Time)
SetUpdatedAt(time.Time)
Expands() []string // Expands returns the foreign keys should preload.
Excludes() map[string][]any
Purge() bool // Purge indicates whether to permanently delete records (hard delete). Default is false (soft delete).
MarshalLogObject(zapcore.ObjectEncoder) error // MarshalLogObject implement zap.ObjectMarshaler
CreateBefore(*ModelContext) error
CreateAfter(*ModelContext) error
DeleteBefore(*ModelContext) error
DeleteAfter(*ModelContext) error
UpdateBefore(*ModelContext) error
UpdateAfter(*ModelContext) error
ListBefore(*ModelContext) error
ListAfter(*ModelContext) error
GetBefore(*ModelContext) error
GetAfter(*ModelContext) error
}
Model defines the contract for all data models in the framework. Provides database operations, audit trail, lifecycle hooks, and logging support.
Type Requirements:
- Must be a pointer to struct (e.g., *User)
- Must have an "ID" field as primary key
- Should embed model.Base for common functionality
type ModelContext ¶
type ModelContext struct {
// contains filtered or unexported fields
}
func NewModelContext ¶
func NewModelContext(dbctx *DatabaseContext, ctx context.Context) *ModelContext
func (*ModelContext) Context ¶
func (mc *ModelContext) Context() context.Context
func (*ModelContext) DatabaseContext ¶
func (mc *ModelContext) DatabaseContext() *DatabaseContext
type Module ¶ added in v0.10.0
type Module[M Model, REQ Request, RSP Response] interface { // Service returns the service instance that handles business logic for this module. Service() Service[M, REQ, RSP] // Route returns the base API path for this module's endpoints. Route() string // Pub determines whether the API endpoints are public or require authentication. Pub() bool // Param returns the URL parameter name used for resource identification. Param() string }
Module defines a module system for creating modular API endpoints with automatic CRUD operations, routing, and service layer integration.
Type Parameters:
- M: Model type that implements Model interface
- REQ: Request type for API operations
- RSP: Response type for API operations
Features:
- Automatic route registration
- Service layer integration
- Configurable authentication
type QueryConfig ¶ added in v0.9.7
type QueryConfig struct {
FuzzyMatch bool // Enable fuzzy matching (LIKE/REGEXP). Default: false
AllowEmpty bool // Allow empty query conditions. Default: false
UseOr bool // Use OR logic to combine query conditions. Default: false (uses AND)
RawQuery string // Raw SQL query string for custom WHERE conditions
RawQueryArgs []any // Arguments for the raw SQL query parameters
}
QueryConfig configures the behavior of WithQuery method.
Fields:
FuzzyMatch: Enable fuzzy matching (LIKE/REGEXP queries). Default: false (exact match with IN clause)
Single value: Uses LIKE pattern (WHERE name LIKE '%value%')
Multiple values (comma-separated): Uses REGEXP pattern (WHERE name REGEXP '.*value1.*|.*value2.*')
Empty strings in comma-separated values are automatically skipped
REGEXP special characters are automatically escaped
Note: REGEXP may not be available in all databases (e.g., SQLite requires extension)
AllowEmpty: Allow empty query conditions to match all records. Default: false (blocked for safety)
When false: Empty queries are blocked (adds WHERE 1 = 0)
When true: Empty queries match all records (full table scan)
Empty query cases: nil, empty struct, all fields are zero values, all field values are empty strings
Critical: Use with caution, especially for Delete operations
UseOr: Use OR logic to combine query conditions. Default: false (uses AND logic)
When false: Multiple fields use AND logic (WHERE name IN ('John') AND age IN (18))
When true: Multiple fields use OR logic (WHERE name IN ('John') OR age IN (18))
First condition always uses WHERE, subsequent conditions use OR
Works with both exact match and fuzzy match
RawQuery: Raw SQL query string for custom WHERE conditions. When provided, model fields are ignored
Works even when query is nil
Supports parameterized queries with RawQueryArgs
Example: "age > ? AND status = ?"
RawQueryArgs: Arguments for the raw SQL query, used with RawQuery for parameterized queries
Can be nil or empty slice if RawQuery has no placeholders
Example: []any{18, "active"}
CRITICAL SAFETY FEATURE: Empty query conditions (all fields are zero values) are blocked by default to prevent catastrophic data loss scenarios, especially when the result is used for Delete operations.
Empty Query Examples:
- WithQuery(&User{}) → all fields are zero values
- WithQuery(&User{Name: "", Email: ""}) → all field values are empty strings
- WithQuery(&KV{Key: ""}) → happens when removed slice is empty
Usage Examples:
// Exact match (default)
WithQuery(&User{Name: "John"})
WithQuery(&User{Name: "John"}, QueryConfig{})
// Exact match with multiple values (comma-separated)
WithQuery(&User{Name: "John,Jack"}) // WHERE name IN ('John', 'Jack')
WithQuery(&User{ID: "id1,id2,id3"}) // WHERE id IN ('id1', 'id2', 'id3')
// Fuzzy match - single value (LIKE)
WithQuery(&User{Name: "John"}, QueryConfig{FuzzyMatch: true}) // WHERE name LIKE '%John%'
// Fuzzy match - multiple values (REGEXP)
WithQuery(&User{Name: "John,Jack"}, QueryConfig{FuzzyMatch: true}) // WHERE name REGEXP '.*John.*|.*Jack.*'
// Allow empty query (ListFactory with pagination)
WithQuery(&User{}, QueryConfig{AllowEmpty: true}) // Returns all records
// Fuzzy match + Allow empty
WithQuery(&User{}, QueryConfig{FuzzyMatch: true, AllowEmpty: true})
// Use OR logic to combine conditions
WithQuery(&User{Name: "John", Email: "john@example.com"}, QueryConfig{UseOr: true})
// WHERE name IN ('John') OR email IN ('john@example.com')
// OR logic with fuzzy match
WithQuery(&User{Name: "John", Email: "example"}, QueryConfig{UseOr: true, FuzzyMatch: true})
// WHERE name LIKE '%John%' OR email LIKE '%example%'
// Raw SQL query (can be combined with model fields using AND logic)
WithQuery(&User{}, QueryConfig{RawQuery: "age > ? AND status = ?", RawQueryArgs: []any{18, "active"}})
WithQuery(nil, QueryConfig{RawQuery: "created_at BETWEEN ? AND ?", RawQueryArgs: []any{startDate, endDate}})
// Raw SQL with complex conditions
WithQuery(&User{}, QueryConfig{RawQuery: "created_at BETWEEN ? AND ? OR priority IN (?)", RawQueryArgs: []any{startDate, endDate, priorities}})
// Raw SQL combined with model fields
WithQuery(&User{Name: "John"}, QueryConfig{RawQuery: "age > ?", RawQueryArgs: []any{18}}) // WHERE age > ? AND name IN ('John')
// Combined options
WithQuery(&User{Name: "John"}, QueryConfig{
FuzzyMatch: true,
UseOr: true,
AllowEmpty: false,
})
type RBAC ¶
type RBAC interface {
AddRole(name string) error
RemoveRole(name string) error
GrantPermission(role string, resource string, action string) error
// RevokePermission removes policies for the given role with flexible behaviors:
// - resource=="" && action=="" : remove all policies for the role
// - resource=="" && action!="" : remove policies matching the role and action
// - resource!="" && action=="" : remove policies matching the role and resource
// - resource!="" && action!="" : remove the exact (role, resource, action, "allow") policy
RevokePermission(role string, resource string, action string) error
AssignRole(subject string, role string) error
UnassignRole(subject string, role string) error
}
RBAC provides role-based access control operations. Supports roles, permissions, and subject assignments with flexible resource and action management.
RBAC Model:
- Subject: Users or entities that need access
- Role: Named collection of permissions
- Resource: Protected objects or endpoints
- Action: Operations on resources
type Service ¶
type Service[M Model, REQ Request, RSP Response] interface { Create(*ServiceContext, REQ) (RSP, error) Delete(*ServiceContext, REQ) (RSP, error) Update(*ServiceContext, REQ) (RSP, error) Patch(*ServiceContext, REQ) (RSP, error) List(*ServiceContext, REQ) (RSP, error) Get(*ServiceContext, REQ) (RSP, error) CreateMany(*ServiceContext, REQ) (RSP, error) DeleteMany(*ServiceContext, REQ) (RSP, error) UpdateMany(*ServiceContext, REQ) (RSP, error) PatchMany(*ServiceContext, REQ) (RSP, error) CreateBefore(*ServiceContext, M) error CreateAfter(*ServiceContext, M) error DeleteBefore(*ServiceContext, M) error DeleteAfter(*ServiceContext, M) error UpdateBefore(*ServiceContext, M) error UpdateAfter(*ServiceContext, M) error PatchBefore(*ServiceContext, M) error PatchAfter(*ServiceContext, M) error ListBefore(*ServiceContext, *[]M) error ListAfter(*ServiceContext, *[]M) error GetBefore(*ServiceContext, M) error GetAfter(*ServiceContext, M) error CreateManyBefore(*ServiceContext, ...M) error CreateManyAfter(*ServiceContext, ...M) error DeleteManyBefore(*ServiceContext, ...M) error DeleteManyAfter(*ServiceContext, ...M) error UpdateManyBefore(*ServiceContext, ...M) error UpdateManyAfter(*ServiceContext, ...M) error PatchManyBefore(*ServiceContext, ...M) error PatchManyAfter(*ServiceContext, ...M) error Import(*ServiceContext, io.Reader) ([]M, error) Export(*ServiceContext, ...M) ([]byte, error) Filter(*ServiceContext, M) M FilterRaw(*ServiceContext) string Logger }
Service provides business logic operations for model types. Defines the service layer between controllers and database operations.
Type Parameters:
- M: Model type that implements Model interface
- REQ: Request type (typically DTOs or request structures)
- RSP: Response type (typically DTOs or response structures)
Features:
- CRUD and batch operations
- Lifecycle hooks (Before/After methods)
- Data import/export
- Custom filtering logic
type ServiceContext ¶
type ServiceContext struct {
Method string // http method
Request *http.Request // http request
URL *url.URL // request url
Header http.Header // http request header
WriterHeader http.Header // http writer header
ClientIP string // client ip
UserAgent string // user agent
Writer http.ResponseWriter
// route parameters,
//
// eg: PUT /api/gists/:id/star
// Params: map[string]string{"id": "xxxxx-mygistid-xxxxx"}
//
// eg: DELETE /api/user/:userid/shelf/:shelfid/book
// Params: map[string]string{"userid": "xxxxx-myuserid-xxxxx", "shelfid": "xxxxx-myshelfid-xxxxx"}
Params map[string]string
Query url.Values
SessionID string // session id
Username string // currrent login user.
UserID string // currrent login user id
Route string
RequestID string
TraceID string
PSpanID string
SpanID string
Seq int
// contains filtered or unexported fields
}
func NewServiceContext ¶
func NewServiceContext(c *gin.Context, ctxs ...context.Context) *ServiceContext
NewServiceContext creates ServiceContext from gin.Context. Including request details, headers and user information.
You can pass the custom context.Context to propagate span tracing, otherwise use the c.Request.Context().
func (*ServiceContext) Context ¶
func (sc *ServiceContext) Context() context.Context
Context converts *ServiceContex to context.Context. It starts from the underlying ctx.context and conditionally injects extra metadata.
func (*ServiceContext) Data ¶
func (sc *ServiceContext) Data(code int, contentType string, data []byte)
func (*ServiceContext) DatabaseContext ¶
func (sc *ServiceContext) DatabaseContext() *DatabaseContext
func (*ServiceContext) Encode ¶ added in v0.10.2
func (sc *ServiceContext) Encode(w io.Writer, event Event) error
Encode writes an SSE event to the given writer. This is a convenience method that wraps sse.Encode for use within SSE stream callbacks.
The event is formatted according to the SSE specification:
- Fields are written in recommended order: id, event, retry, data
- Each field is written as "field: value\n"
- Multiple data fields are concatenated (for multi-line data)
- Events are separated by a blank line (\n\n)
If Data is a complex type (map, struct, slice), it will be JSON-encoded. If Data is a primitive type, it will be converted to string. If Data is nil, no data field will be written.
Example:
ctx.SSE().WithInterval(1*time.Second).Stream(func(w io.Writer) bool {
_ = ctx.Encode(w, types.Event{
Event: "message",
Data: "Hello",
})
return true
})
Parameters:
- w: Writer to write the event to (typically from SSE stream callback)
- event: SSE event to encode
Returns:
- error: Any error that occurred during encoding
func (*ServiceContext) FormFile ¶ added in v0.10.5
func (sc *ServiceContext) FormFile(name string) (*multipart.FileHeader, error)
func (*ServiceContext) GetPhase ¶
func (sc *ServiceContext) GetPhase() consts.Phase
func (*ServiceContext) PostForm ¶ added in v0.10.5
func (sc *ServiceContext) PostForm(key string) string
func (*ServiceContext) Redirect ¶
func (sc *ServiceContext) Redirect(code int, location string)
func (*ServiceContext) RequiresAuth ¶ added in v0.9.6
func (sc *ServiceContext) RequiresAuth() bool
RequiresAuth returns whether the current API requires authentication
func (*ServiceContext) SSE ¶ added in v0.10.2
func (sc *ServiceContext) SSE() *sseBuilder
SSE returns a new SSE builder for chaining SSE operations. This provides a fluent interface for sending SSE events and streams.
Example usage:
// Start a stream
ctx.SSE().Stream(func(w io.Writer) bool {
_ = ctx.Encode(w, types.Event{Data: "chunk"})
return true
})
// Stream with interval
ctx.SSE().WithInterval(1*time.Second).Stream(func(w io.Writer) bool {
_ = ctx.Encode(w, types.Event{Data: "chunk"})
return true
})
// Send [DONE] marker
_ = ctx.SSE().Done()
Example (CompleteFlow) ¶
ExampleServiceContext_SSE_completeFlow demonstrates a complete SSE flow using the chainable API. This pattern is commonly used in AI chat completions and similar streaming APIs.
package main
import (
"io"
"github.com/forbearing/gst/types"
)
func main() {
var sc *types.ServiceContext
// Stream data chunks using the chainable API
sc.SSE().Stream(func(w io.Writer) bool {
// Send chat completion chunks
_ = sc.Encode(w, types.Event{
Data: map[string]any{
"content": "Hello",
},
})
// Continue streaming...
return true
})
// Send [DONE] marker to indicate stream completion
// This is required by protocols like OpenAI's chat completion API
_ = sc.SSE().Done()
}
Example (Done) ¶
ExampleServiceContext_SSE_done demonstrates using the chainable API to send a [DONE] marker.
package main
import (
"github.com/forbearing/gst/types"
)
func main() {
var sc *types.ServiceContext
// Send [DONE] marker using the chainable API
_ = sc.SSE().Done()
}
Example (Stream) ¶
ExampleServiceContext_SSE_stream demonstrates using the chainable API for streaming.
package main
import (
"io"
"time"
"github.com/forbearing/gst/types"
)
func main() {
var sc *types.ServiceContext
// Stream events using the chainable API
sc.SSE().Stream(func(w io.Writer) bool {
_ = sc.Encode(w, types.Event{
Event: "message",
Data: time.Now().String(),
})
return true
})
}
Example (StreamWithInterval) ¶
ExampleServiceContext_SSE_streamWithInterval demonstrates using the chainable API for interval-based streaming.
package main
import (
"fmt"
"io"
"time"
"github.com/forbearing/gst/types"
)
func main() {
var sc *types.ServiceContext
// Stream with interval using the chainable API
counter := 0
sc.SSE().WithInterval(1 * time.Second).Stream(func(w io.Writer) bool {
counter++
// Send event
_ = sc.Encode(w, types.Event{
ID: fmt.Sprintf("event-%d", counter),
Event: "message",
Data: map[string]any{
"number": counter,
"message": fmt.Sprintf("Event %d of 3", counter),
},
})
// Return true to continue (will wait 1 second), false to stop
// This will send 3 events: at 0s, 1s, 2s, then stop
return counter < 3
})
// Send [DONE] marker if required by your protocol
_ = sc.SSE().Done()
}
func (*ServiceContext) SSEvent ¶ added in v0.10.5
func (sc *ServiceContext) SSEvent(name string, message any)
func (*ServiceContext) SetCookie ¶
func (sc *ServiceContext) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)
func (*ServiceContext) SetPhase ¶
func (sc *ServiceContext) SetPhase(phase consts.Phase)
func (*ServiceContext) Stream ¶ added in v0.10.5
func (sc *ServiceContext) Stream(step func(io.Writer) bool)
func (*ServiceContext) WithPhase ¶
func (sc *ServiceContext) WithPhase(phase consts.Phase) *ServiceContext
type ServiceError ¶
ServiceError represents an error with a custom HTTP status code that can be returned from service layer methods
func NewServiceError ¶
func NewServiceError(statusCode int, message string) *ServiceError
NewServiceError creates a new ServiceError with the given status code and message
func NewServiceErrorWithCause ¶
func NewServiceErrorWithCause(statusCode int, message string, err error) *ServiceError
NewServiceErrorWithCause creates a new ServiceError with the given status code, message and underlying error
func (*ServiceError) Error ¶
func (e *ServiceError) Error() string
Error implements the error interface
func (*ServiceError) Unwrap ¶
func (e *ServiceError) Unwrap() error
Unwrap returns the underlying error for error unwrapping
type StandardLogger ¶
type StandardLogger interface {
Debug(args ...any)
Info(args ...any)
Warn(args ...any)
Error(args ...any)
Fatal(args ...any)
Debugf(format string, args ...any)
Infof(format string, args ...any)
Warnf(format string, args ...any)
Errorf(format string, args ...any)
Fatalf(format string, args ...any)
}
StandardLogger provides leveled logging and formatted variants. Fatal/Fatalf should exit after logging.
type StructuredLogger ¶
type StructuredLogger interface {
Debugw(msg string, keysAndValues ...any)
Infow(msg string, keysAndValues ...any)
Warnw(msg string, keysAndValues ...any)
Errorw(msg string, keysAndValues ...any)
Fatalw(msg string, keysAndValues ...any)
}
StructuredLogger logs with key-value pairs (msg plus fields). Methods with suffix 'w' mean "with fields".
type ZapLogger ¶
type ZapLogger interface {
Debugz(msg string, fields ...zap.Field)
Infoz(msg string, fields ...zap.Field)
Warnz(msg string, fields ...zap.Field)
Errorz(msg string, fields ...zap.Field)
Fatalz(msg string, fields ...zap.Field)
}
ZapLogger logs with typed zap fields. Methods with suffix 'z' use zap.Field values.