Documentation
¶
Overview ¶
Package utils provides general-purpose helper utilities used across different parts of the application. Includes tools for working with context, type-safe keys, hashing, HTTP response writing, HTTP client initialization, JWT token generation and validation, and other common operations.
Index ¶
- Variables
- func GenerateJWTToken(issuer string, userID int64, tokenDuration time.Duration, signKey string) (models.Token, error)
- func GetUserIDFromContext(ctx context.Context) (int64, bool)
- func Hash(data []byte) []byte
- func HashJSONToString(data any) (string, error)
- func HashString(data string, hashKey string) string
- func InitHasherPool(hashKey string)
- func ParseBearerToken(authorizationHeader string) (string, error)
- func ParseUserIDFromJWT(tokenString string) (int64, error)
- func ValidateAndParseJWTToken(tokenString, tokenSignKey, tokenIssuer string) (models.Token, error)
- func WriteJSON(w http.ResponseWriter, data any, statusCode int) (int, error)
- type HTTPClient
- type Hasher
- type UUIDGenerator
Constants ¶
This section is empty.
Variables ¶
var UserIDCtxKey = contextKey("userID")
UserIDCtxKey is the key used to store the user identifier in the context. Used together with GetUserIDFromContext for type-safe retrieval of the user ID from context.Context.
Example of writing a value to the context:
ctx := context.WithValue(ctx, utils.UserIDCtxKey, int64(42))
Functions ¶
func GenerateJWTToken ¶
func GenerateJWTToken(issuer string, userID int64, tokenDuration time.Duration, signKey string) (models.Token, error)
GenerateJWTToken creates a signed HMAC-SHA256 JWT token with the given parameters.
The token includes the following standard claims:
- Issuer (iss): identifies the service that issued the token
- Subject (sub): the user ID encoded as a string
- IssuedAt (iat): the current time
- ExpiresAt (exp): the current time plus tokenDuration
All parameters are required. Returns an error if any of them are empty or zero.
Parameters:
issuer - identifier of the token issuer (e.g. service name) userID - ID of the user the token is issued for tokenDuration - how long the token remains valid signKey - secret key used to sign the token with HMAC-SHA256
Returns:
models.Token - contains the signed token string and the jwt.Token object error - non-nil if parameters are invalid or signing fails
Example usage:
token, err := utils.GenerateJWTToken("my-service", 42, time.Hour, "secret")
func GetUserIDFromContext ¶
GetUserIDFromContext retrieves the user identifier from the context.
Returns the user ID of type int64 and an ok flag:
- ok == true — value is found and has the correct int64 type
- ok == false — value is missing or has an unexpected type
Example usage:
userID, ok := utils.GetUserIDFromContext(ctx)
if !ok {
// handle missing user in context
}
func Hash ¶
Hash computes an HMAC-SHA256 signature over the given byte slice using a hasher pulled from the global hasher pool.
Behavior:
- Retrieves a hash.Hash instance from sync.Pool
- Resets it, writes the data, computes the sum
- Resets again and returns it to the pool
Parameters:
data - arbitrary byte slice to be hashed
Returns:
[]byte - HMAC-SHA256 digest
Example usage:
digest := utils.Hash([]byte("some data"))
func HashJSONToString ¶
func HashString ¶
HashString computes an HMAC-SHA256 signature over the given string using the provided hash key and returns the result as a hex-encoded string.
Unlike Hash, this function does not use the global hasher pool and creates a new HMAC instance on each call. Suitable for one-off hashing where pool initialization is not desired.
Parameters:
data - string to be hashed hashKey - secret key used for the HMAC operation
Returns:
string - hex-encoded HMAC-SHA256 digest
Example usage:
signature := utils.HashString("some data", "my-secret-key")
func InitHasherPool ¶
func InitHasherPool(hashKey string)
InitHasherPool initializes a sync.Pool of HMAC-SHA256 hashers. Each hasher in the pool is configured with the provided hash key.
Purpose:
- Avoid repeated allocations of new hash.Hash instances
- Reduce GC pressure in high-throughput hashing paths
Parameters:
hashKey - key used for all HMAC operations
Example usage:
utils.InitHasherPool("my-secret-key")
func ParseBearerToken ¶
func ParseUserIDFromJWT ¶
func ValidateAndParseJWTToken ¶
ValidateAndParseJWTToken validates the given JWT token string and extracts its claims.
Validation includes:
- Signature verification using the provided sign key
- Issuer (iss) claim check against the provided tokenIssuer
- Expiration (exp) claim check
- Subject (sub) claim presence and conversion to int64 UserID
Parameters:
tokenString - the raw signed JWT string to validate and parse tokenSignKey - secret key used to verify the token signature tokenIssuer - expected issuer value to validate against the iss claim
Returns:
models.Token - contains the parsed jwt.Token object and the extracted UserID error - non-nil if validation fails, claims are missing, or subject cannot be parsed
Example usage:
token, err := utils.ValidateAndParseJWTToken(rawToken, "secret", "my-service")
if err != nil {
// handle invalid or expired token
}
func WriteJSON ¶
WriteJSON serializes the given data to JSON and writes it to the HTTP response.
It sets the "Content-Type" header to "application/json" and writes the provided HTTP status code before sending the response body.
If marshaling fails, it responds with 500 Internal Server Error and returns a wrapped error.
Parameters:
w - the HTTP response writer to write the response to data - any value to be serialized as JSON (struct, map, slice, nil, etc.) statusCode - HTTP status code to set in the response (e.g. http.StatusOK)
Returns:
int - number of bytes written to the response body error - non-nil if JSON marshaling fails
Example usage:
WriteJSON(w, map[string]string{"status": "ok"}, http.StatusOK)
WriteJSON(w, map[string]string{"error": "not found"}, http.StatusNotFound)
Types ¶
type HTTPClient ¶
HTTPClient is a wrapper around the resty.Client HTTP client. It embeds *resty.Client to expose all of its methods directly, while allowing extension with additional application-specific behavior.
Example usage:
client := utils.NewHTTPClient()
resp, err := client.R().Get("https://example.com")
func NewHTTPClient ¶
func NewHTTPClient() *HTTPClient
NewHTTPClient creates and returns a new HTTPClient instance with a default-configured underlying resty.Client.
Each call returns an independent client instance with its own configuration, connection pool, and state.
Returns:
*HTTPClient - a ready-to-use HTTP client
Example usage:
client := utils.NewHTTPClient()
resp, err := client.R().
SetHeader("Accept", "application/json").
Get("https://api.example.com/users")
type Hasher ¶
type Hasher struct {
// contains filtered or unexported fields
}
Hasher provides keyed HMAC-SHA256 hashing for metrics. It stores the hash key as a byte slice to avoid repeated conversions.
type UUIDGenerator ¶
type UUIDGenerator struct{}
UUIDGenerator creates string UUID values for application identifiers.
The generator is stateless and safe to reuse across goroutines. Its [Generate] method prefers UUID version 7 (time-ordered) and falls back to a random UUID if v7 generation fails.
func NewUUIDGenerator ¶
func NewUUIDGenerator() *UUIDGenerator
NewUUIDGenerator returns a new UUIDGenerator instance.
The returned generator has no internal mutable state; creating multiple instances is inexpensive.
func (*UUIDGenerator) Generate ¶
func (g *UUIDGenerator) Generate() string
Generate returns a UUID string suitable for use as a client-side identifier.
It first attempts to create UUID v7 via uuid.NewV7. If that operation fails, it falls back to uuid.NewString (random UUID) to preserve availability and still return a valid UUID-formatted value.