request

package
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 7, 2025 License: BSD-3-Clause Imports: 14 Imported by: 0

README

HTTP Request Package

The HTTP Request package provides utilities for parsing, validating, and accessing HTTP request data in Go web applications, with a focus on type-safe value handling.

Features

  • JSON Body Parsing: Decode and validate JSON request bodies
  • Value Extraction: Get values from URL parameters, forms, and headers
  • Type-Safe Conversion: Fluent API for converting string values to various types
  • Validation Support: Integrated validation for request structures
  • Request Body Reading: Read and restore request body content
  • Default Values: Convenient handling of missing or empty values
  • Cross-Package Integration: Works with handler, response, and pagination packages

Quick Start

package main

import (
    "net/http"
    "github.com/alextanhongpin/core/http/request"
    "github.com/alextanhongpin/core/http/response"
)

type CreateUserRequest struct {
    Name  string `json:"name"`
    Email string `json:"email"`
    Age   int    `json:"age"`
}

func (r CreateUserRequest) Validate() error {
    // Your validation logic here
    return nil
}

func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
    var req CreateUserRequest
    if err := request.DecodeJSON(r, &req); err != nil {
        response.ErrorJSON(w, err)
        return
    }
    response.OK(w, map[string]string{"status": "success"})
}

func GetUserHandler(w http.ResponseWriter, r *http.Request) {
    userID := request.PathValue(r, "id").Int()
    page := request.QueryValue(r, "page").IntN(1)
    since := request.QueryValue(r, "since").Time("2006-01-02")
    // ...
}

API Reference

JSON Decoding
DecodeJSON(r *http.Request, v any) error

Decodes JSON body into struct.

Value Extraction
PathValue(r *http.Request, key string) Value
QueryValue(r *http.Request, key string) Value
HeaderValue(r *http.Request, key string) Value

Type-safe value extraction and conversion.

Best Practices

  • Always validate incoming request payloads.
  • Use type-safe value extraction for robust code.
  • Integrate with handler and response for full request/response lifecycle.

License

MIT

Documentation

Overview

Package request provides utilities for HTTP request parsing, validation, and manipulation.

package request handles the parsing and validation for the request body.

Package request provides utilities for HTTP request parsing, validation, and manipulation.

Index

Constants

View Source
const (
	// MaxBodySize is the default maximum request body size (10MB)
	MaxBodySize = 10 << 20
)

Variables

View Source
var (
	ErrInvalidJSON     = errors.New("request: invalid json")
	ErrInvalidFormData = errors.New("request: invalid form data")
	ErrBodyTooLarge    = errors.New("request: request body too large")
	ErrEmptyBody       = errors.New("request: empty request body")
)

Functions

func Clone

func Clone(r *http.Request) (*http.Request, error)

Clone creates a deep copy of an HTTP request, including its body.

This function is useful when you need to process the same request in multiple ways or when middleware needs to modify a request without affecting the original. The cloned request has its own copy of the body, allowing both the original and cloned requests to be read independently.

The function uses Read() internally to preserve the original request body while creating a separate copy for the clone.

Parameters:

  • r: The HTTP request to clone

Returns:

  • A new HTTP request that is an independent copy of the original
  • An error if reading the original request body fails

Example:

// Clone request for parallel processing
clonedReq, err := request.Clone(r)
if err != nil {
	return err
}

// Both original and cloned requests can now be used independently
go processOriginal(r)
go processClone(clonedReq)

Note: Like Read(), this function loads the entire request body into memory.

func DecodeForm

func DecodeForm(r *http.Request, v any) error

DecodeForm parses form data into a struct using reflection

func DecodeJSON

func DecodeJSON(r *http.Request, v any, opts ...DecodeOption) error

DecodeJSON decodes JSON request body with validation and size limits

func DecodeQuery

func DecodeQuery(r *http.Request, v any) error

DecodeQuery parses query parameters into a struct using reflection

func Read

func Read(r *http.Request) ([]byte, error)

Read reads the entire request body and restores it for subsequent reads.

This function is useful when you need to read the request body multiple times or when middleware needs to inspect the body without consuming it for the actual handler. It reads all data from the request body and then replaces the body with a new reader containing the same data.

The original request body is consumed and replaced with a new io.ReadCloser that contains the same data, allowing the body to be read again.

Parameters:

  • r: The HTTP request whose body should be read

Returns:

  • The request body content as a byte slice
  • An error if reading the body fails

Example:

// Read body for logging while preserving it for the handler
body, err := request.Read(r)
if err != nil {
	return err
}
logger.Debug("request body", "body", string(body))
// The request body is still available for the handler to read

Note: This function loads the entire request body into memory, so it should be used with caution for large request bodies to avoid memory issues.

Types

type BodyError

type BodyError struct {
	Body []byte
	// contains filtered or unexported fields
}

func (*BodyError) Error

func (b *BodyError) Error() string

func (*BodyError) Unwrap

func (b *BodyError) Unwrap() error

type DecodeOption

type DecodeOption func(*DecodeOptions)

DecodeOption is a functional option for configuring DecodeOptions

func WithMaxBodySize

func WithMaxBodySize(size int64) DecodeOption

WithMaxBodySize sets the maximum allowed body size

func WithRequired

func WithRequired() DecodeOption

WithRequired indicates that the request body is required

type DecodeOptions

type DecodeOptions struct {
	MaxBodySize int64
	Required    bool
}

DecodeOptions configures request decoding behavior

type Value

type Value string

Value represents a string value extracted from HTTP requests with type conversion and validation utilities.

This type wraps string values from various HTTP request sources (query parameters, path values, form data, headers) and provides a rich set of methods for type conversion, validation, and transformation.

The Value type is designed to make HTTP parameter handling type-safe and convenient, reducing boilerplate code for common operations like parsing integers, validating email addresses, or checking required fields.

Example usage:

// Extract and validate query parameters
userID := request.QueryValue(r, "user_id").IntOr(0)
email := request.QueryValue(r, "email")
if err := email.Required("email"); err != nil {
	return err
}
if err := email.Email(); err != nil {
	return err
}

// Extract and convert path parameters
id := request.PathValue(r, "id").MustInt()
name := request.PathValue(r, "name").Trim().String()

func FormValue

func FormValue(r *http.Request, name string) Value

FormValue extracts a form parameter value from the HTTP request.

This function retrieves the value of a form field by name from POST form data. It works with both application/x-www-form-urlencoded and multipart/form-data.

Parameters:

  • r: The HTTP request to extract the parameter from
  • name: The name of the form field

Returns:

  • A Value containing the form field value

Example:

// POST with Content-Type: application/x-www-form-urlencoded
// Body: name=John&[email protected]
name := request.FormValue(r, "name")    // "John"
email := request.FormValue(r, "email")  // "[email protected]"

func HeaderValue

func HeaderValue(r *http.Request, name string) Value

HeaderValue extracts a header value from the HTTP request.

This function retrieves the value of an HTTP header by name. Header names are case-insensitive according to HTTP specifications.

Parameters:

  • r: The HTTP request to extract the header from
  • name: The name of the header (case-insensitive)

Returns:

  • A Value containing the header value

Example:

userAgent := request.HeaderValue(r, "User-Agent")
authToken := request.HeaderValue(r, "Authorization")
contentType := request.HeaderValue(r, "Content-Type")

func PathValue

func PathValue(r *http.Request, name string) Value

PathValue extracts a path parameter value from the HTTP request.

This function retrieves the value of a path parameter by name from the request. Path parameters are typically defined in route patterns (e.g., "/users/{id}").

Parameters:

  • r: The HTTP request to extract the parameter from
  • name: The name of the path parameter

Returns:

  • A Value containing the path parameter value

Example:

// Route: /users/{id}
// Request: GET /users/123
userID := request.PathValue(r, "id")  // "123"

func QueryValue

func QueryValue(r *http.Request, name string) Value

QueryValue extracts a query parameter value from the HTTP request.

This function retrieves the value of a query parameter by name from the request URL. If the parameter is not present, it returns an empty Value.

Parameters:

  • r: The HTTP request to extract the parameter from
  • name: The name of the query parameter

Returns:

  • A Value containing the query parameter value

Example:

// GET /users?page=2&limit=10
page := request.QueryValue(r, "page")     // "2"
limit := request.QueryValue(r, "limit")   // "10"
missing := request.QueryValue(r, "sort")  // ""

func QueryValues

func QueryValues(r *http.Request, name string) []Value

QueryValues returns all values for a query parameter (for parameters that can have multiple values).

This function is useful when a query parameter can appear multiple times in the URL, such as ?tags=go&tags=http&tags=web.

Parameters:

  • r: The HTTP request to extract the parameters from
  • name: The name of the query parameter

Returns:

  • A slice of Values containing all values for the parameter

Example:

// GET /items?tags=go&tags=http&tags=web
tags := request.QueryValues(r, "tags")  // ["go", "http", "web"]
for _, tag := range tags {
	fmt.Println(tag.String())
}

func (Value) Bool

func (v Value) Bool() bool

func (Value) BoolOr

func (v Value) BoolOr(b bool) bool

BoolOr returns the parsed bool or a default value

func (Value) CSV

func (v Value) CSV() []string

CSV parses comma-separated values and trims whitespace

func (Value) Contains

func (v Value) Contains(substr string) bool

Contains checks if the value contains the specified substring.

This method performs a case-sensitive substring search within the value.

Parameters:

  • substr: The substring to search for

Returns:

  • true if the substring is found, false otherwise

Example:

userAgent := request.HeaderValue(r, "User-Agent")
isMobile := userAgent.Contains("Mobile")

func (Value) Date

func (v Value) Date() (time.Time, error)

Date parses the value as a date (YYYY-MM-DD)

func (Value) Email

func (v Value) Email() error

Email validates that the value is a valid email format

func (Value) Float64

func (v Value) Float64() float64

Float64 parses the value as a float64

func (Value) Float64Or

func (v Value) Float64Or(n float64) float64

Float64Or returns the parsed float64 or a default value

func (Value) Float64Range

func (v Value) Float64Range(min, max float64) (float64, error)

Float64Range validates that the float64 value is within a range

func (Value) Float64RangeOr

func (v Value) Float64RangeOr(min, max, def float64) float64

Float64RangeOr returns the float64 value within a range or a default value if out of range.

func (Value) FromBase64

func (v Value) FromBase64() Value

func (Value) HasPrefix

func (v Value) HasPrefix(prefix string) bool

HasPrefix checks if the value starts with the specified prefix.

This method performs a case-sensitive prefix check, useful for validating URL schemes, token types, or other formatted values.

Parameters:

  • prefix: The prefix to check for

Returns:

  • true if the value starts with the prefix, false otherwise

Example:

auth := request.HeaderValue(r, "Authorization")
isBearer := auth.HasPrefix("Bearer ")

func (Value) HasSuffix

func (v Value) HasSuffix(suffix string) bool

HasSuffix checks if the value ends with the specified suffix.

This method performs a case-sensitive suffix check, useful for validating file extensions, domain names, or other formatted values.

Parameters:

  • suffix: The suffix to check for

Returns:

  • true if the value ends with the suffix, false otherwise

Example:

filename := request.FormValue(r, "filename")
isImage := filename.HasSuffix(".jpg") || filename.HasSuffix(".png")

func (Value) InSlice

func (v Value) InSlice(slice []string) bool

InSlice checks if the value is in a slice of strings

func (Value) InSliceOr

func (v Value) InSliceOr(slice []string, def string) string

func (Value) Int

func (v Value) Int() int

func (Value) Int32

func (v Value) Int32() int32

func (Value) Int32Or

func (v Value) Int32Or(n int32) int32

func (Value) Int32Range

func (v Value) Int32Range(min, max int32) (int32, error)

Int32Range validates that the int32 value is within a range

func (Value) Int32RangeOr

func (v Value) Int32RangeOr(min, max, def int32) int32

Int32RangeOr returns the int32 value within a range or a default value if out of range.

func (Value) Int64

func (v Value) Int64() int64

func (Value) Int64Or

func (v Value) Int64Or(n int64) int64

func (Value) Int64Range

func (v Value) Int64Range(min, max int64) (int64, error)

Int64Range validates that the int64 value is within a range

func (Value) Int64RangeOr

func (v Value) Int64RangeOr(min, max, def int64) int64

Int64RangeOr returns the int64 value within a range or a default value if out of range.

func (Value) IntOr

func (v Value) IntOr(n int) int

func (Value) IntRange

func (v Value) IntRange(min, max int) (int, error)

IntRange validates that the int value is within a range

func (Value) IntRangeOr

func (v Value) IntRangeOr(min, max, def int) int

func (Value) IsEmpty

func (v Value) IsEmpty() bool

IsEmpty returns true if the value is empty or contains only whitespace.

This method is useful for validation where both empty strings and whitespace-only strings should be considered invalid.

Returns:

  • true if the value is empty or whitespace-only, false otherwise

Example:

Value("").IsEmpty()       // true
Value("   ").IsEmpty()    // true
Value("hello").IsEmpty()  // false

func (Value) Length

func (v Value) Length(min, max int) error

Length validates that the string length is within the specified range.

This method checks that the trimmed length of the value falls within the specified minimum and maximum bounds (inclusive).

Parameters:

  • min: The minimum allowed length (inclusive)
  • max: The maximum allowed length (inclusive)

Returns:

  • An error if the length is outside the valid range, nil if valid

Example:

name := request.FormValue(r, "name")
if err := name.Length(2, 50); err != nil {
	return fmt.Errorf("invalid name: %w", err)
}

func (Value) Lower

func (v Value) Lower() Value

Lower returns a new Value with all Unicode letters mapped to their lower case.

This method is useful for case-insensitive comparisons and normalization of user input.

Returns:

  • A new Value with all characters converted to lowercase

Example:

value := Value("Hello World")
lower := value.Lower()  // "hello world"

func (Value) Match

func (v Value) Match(pattern string) bool

Match checks if the value matches a pattern (simple glob-style matching)

func (Value) RFC3339

func (v Value) RFC3339() (time.Time, error)

RFC3339 parses the value as RFC3339 formatted time

func (Value) Required

func (v Value) Required(fieldName string) error

Required returns an error if the value is empty or whitespace-only.

This method provides a standard way to validate required fields with consistent error messages that include the field name.

Parameters:

  • fieldName: The name of the field being validated (used in error messages)

Returns:

  • An error if the value is empty, nil if the value is present

Example:

email := request.QueryValue(r, "email")
if err := email.Required("email"); err != nil {
	return fmt.Errorf("validation failed: %w", err)
}

func (Value) Split

func (v Value) Split(sep string) []string

Split splits the value by a separator

func (Value) String

func (v Value) String() string

String returns the underlying string value.

This is the most basic conversion method, returning the Value as a string without any processing or validation.

Returns:

  • The string representation of the value

func (Value) StringOr

func (v Value) StringOr(str string) string

StringOr returns the string value or a default string if the value is empty.

This method provides a convenient way to handle optional parameters with default values, using Go's generic cmp.Or function for clean null-coalescing.

Parameters:

  • str: The default value to return if the Value is empty

Returns:

  • The Value's string if non-empty, otherwise the default string

Example:

page := request.QueryValue(r, "page").StringOr("1")
sort := request.QueryValue(r, "sort").StringOr("created_at")

func (Value) Time

func (v Value) Time(layout string) (time.Time, error)

Time parses the value as time using the provided layout

func (Value) TimeOr

func (v Value) TimeOr(layout string, defaultTime time.Time) time.Time

TimeOr parses the value as time or returns a default value

func (Value) ToBase64

func (v Value) ToBase64() Value

func (Value) Trim

func (v Value) Trim() Value

Trim returns a new Value with leading and trailing whitespace removed.

This method is commonly used to clean up user input from forms and query parameters where users might accidentally include leading or trailing spaces.

Returns:

  • A new Value with whitespace trimmed

Example:

value := Value("  hello world  ")
trimmed := value.Trim()  // "hello world"

func (Value) URL

func (v Value) URL() (*url.URL, error)

URL parses the value as a URL

func (Value) Upper

func (v Value) Upper() Value

Upper returns a new Value with all Unicode letters mapped to their upper case.

This method is useful for normalization of codes, identifiers, or other values that should be stored in uppercase.

Returns:

  • A new Value with all characters converted to uppercase

Example:

value := Value("hello world")
upper := value.Upper()  // "HELLO WORLD"

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL