http

package
v2.0.0 Latest Latest
Warning

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

Go to latest
Published: Dec 18, 2025 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package http provides functional programming utilities for working with HTTP requests and responses. It offers type-safe abstractions, validation functions, and utilities for handling HTTP operations in a functional style.

The package includes:

  • Type definitions for HTTP responses with bodies
  • Validation functions for HTTP responses
  • JSON content type validation
  • Error handling with detailed HTTP error information
  • Functional utilities for accessing response components

Types:

FullResponse represents a complete HTTP response including both the response object and the body as a byte array. It's implemented as a Pair for functional composition:

type FullResponse = Pair[*http.Response, []byte]

The Response and Body functions provide lens-like access to the components:

resp := Response(fullResponse)  // Get *http.Response
body := Body(fullResponse)      // Get []byte

Validation:

ValidateResponse checks if an HTTP response has a successful status code (2xx):

result := ValidateResponse(response)
// Returns Either[error, *http.Response]

ValidateJSONResponse validates both the status code and Content-Type header:

result := ValidateJSONResponse(response)
// Returns Either[error, *http.Response]

Error Handling:

HttpError provides detailed information about HTTP failures:

err := StatusCodeError(response)
if httpErr, ok := err.(*HttpError); ok {
    code := httpErr.StatusCode()
    headers := httpErr.Headers()
    body := httpErr.Body()
    url := httpErr.URL()
}

Index

Constants

View Source
const (
	// HeaderContentType is the standard HTTP Content-Type header name.
	// It indicates the media type of the resource or data being sent.
	//
	// Example values:
	//   - "application/json"
	//   - "text/html; charset=utf-8"
	//   - "application/xml"
	HeaderContentType = "Content-Type"
)

Variables

View Source
var (
	// Response is a lens-like accessor that extracts the *http.Response
	// from a FullResponse. It provides functional access to the response
	// metadata including status code, headers, and other HTTP response fields.
	//
	// Example:
	//   fullResp := MakePair(response, bodyBytes)
	//   resp := Response(fullResp)
	//   statusCode := resp.StatusCode
	Response = P.Head[*H.Response, []byte]

	// Body is a lens-like accessor that extracts the response body bytes
	// from a FullResponse. It provides functional access to the raw body
	// content without needing to read from an io.Reader.
	//
	// Example:
	//   fullResp := MakePair(response, bodyBytes)
	//   body := Body(fullResp)
	//   content := string(body)
	Body = P.Tail[*H.Response, []byte]

	// FromResponse creates a function that constructs a FullResponse from
	// a given *http.Response. It returns a function that takes a body byte
	// slice and combines it with the response to create a FullResponse.
	//
	// This is useful for functional composition where you want to partially
	// apply the response and later provide the body.
	//
	// Example:
	//   makeFullResp := FromResponse(response)
	//   fullResp := makeFullResp(bodyBytes)
	FromResponse = P.FromHead[[]byte, *H.Response]

	// FromBody creates a function that constructs a FullResponse from
	// a given body byte slice. It returns a function that takes an
	// *http.Response and combines it with the body to create a FullResponse.
	//
	// This is useful for functional composition where you want to partially
	// apply the body and later provide the response.
	//
	// Example:
	//   makeFullResp := FromBody(bodyBytes)
	//   fullResp := makeFullResp(response)
	FromBody = P.FromTail[*H.Response, []byte]
)
View Source
var (

	// ValidateResponse validates an HTTP response and returns an Either.
	// It checks if the response has a successful status code (2xx range).
	//
	// Returns:
	//   - Right(*http.Response) if status code is 2xx
	//   - Left(error) with HttpError if status code is not 2xx
	//
	// Example:
	//   result := ValidateResponse(response)
	//   E.Fold(
	//       func(err error) { /* handle error */ },
	//       func(resp *http.Response) { /* handle success */ },
	//   )(result)
	ValidateResponse = E.FromPredicate(isValidStatus, StatusCodeError)

	// ValidateJSONResponse validates that an HTTP response is a valid JSON response.
	// It checks both the status code (must be 2xx) and the Content-Type header
	// (must be a JSON media type like "application/json").
	//
	// Returns:
	//   - Right(*http.Response) if response is valid JSON with 2xx status
	//   - Left(error) if status is not 2xx or Content-Type is not JSON
	//
	// Example:
	//   result := ValidateJSONResponse(response)
	//   E.Fold(
	//       func(err error) { /* handle non-JSON or error response */ },
	//       func(resp *http.Response) { /* handle valid JSON response */ },
	//   )(result)
	ValidateJSONResponse = F.Flow2(
		E.Of[error, *H.Response],
		E.ChainFirst(F.Flow5(
			GetHeader,
			R.Lookup[H.Header](HeaderContentType),
			O.Chain(A.First[string]),
			E.FromOption[string](errors.OnNone("unable to access the [%s] header", HeaderContentType)),
			E.ChainFirst(validateJSONContentTypeString),
		)))

	// ValidateJsonResponse checks if an HTTP response is a valid JSON response.
	//
	// Deprecated: use ValidateJSONResponse instead (note the capitalization).
	ValidateJsonResponse = ValidateJSONResponse
)

Functions

func GetBody

func GetBody(resp *H.Response) io.ReadCloser

GetBody extracts the response body reader from an http.Response. This is a functional accessor for the Body field.

Parameters:

  • resp: The HTTP response

Returns:

  • The io.ReadCloser for reading the response body

Example:

body := GetBody(response)
defer body.Close()
data, err := io.ReadAll(body)

func GetHeader

func GetHeader(resp *H.Response) H.Header

GetHeader extracts the HTTP headers from an http.Response. This is a functional accessor for the Header field.

Parameters:

  • resp: The HTTP response

Returns:

  • The http.Header map from the response

Example:

headers := GetHeader(response)
contentType := headers.Get("Content-Type")

func ParseMediaType

func ParseMediaType(mediaType string) E.Either[error, ParsedMediaType]

ParseMediaType parses a MIME media type string into its components. It returns a ParsedMediaType (Pair) containing the media type and its parameters.

Parameters:

  • mediaType: A media type string (e.g., "application/json; charset=utf-8")

Returns:

  • Right(ParsedMediaType) with the parsed media type and parameters
  • Left(error) if the media type string is invalid

Example:

result := ParseMediaType("application/json; charset=utf-8")
E.Map(func(parsed ParsedMediaType) {
    mediaType := P.Head(parsed)  // "application/json"
    params := P.Tail(parsed)     // map[string]string{"charset": "utf-8"}
})(result)

func StatusCodeError

func StatusCodeError(resp *H.Response) error

StatusCodeError creates an HttpError from an http.Response with a non-successful status code. It reads the response body and captures all relevant information for debugging.

The function:

  • Reads and stores the response body
  • Clones the response headers
  • Captures the request URL
  • Creates a comprehensive error with all this information

Parameters:

  • resp: The HTTP response with a non-successful status code

Returns:

  • An error (specifically *HttpError) with detailed information

Example:

if !isValidStatus(response) {
    err := StatusCodeError(response)
    return err
}

Types

type FullResponse

type FullResponse = P.Pair[*H.Response, []byte]

FullResponse represents a complete HTTP response including both the *http.Response object and the response body as a byte slice.

It's implemented as a Pair to enable functional composition and transformation of HTTP responses. This allows you to work with both the response metadata (status, headers) and body content together.

Example:

fullResp := MakePair(response, bodyBytes)
resp := Response(fullResp)  // Extract *http.Response
body := Body(fullResp)      // Extract []byte

type HttpError

type HttpError struct {
	// contains filtered or unexported fields
}

HttpError represents an HTTP error with detailed information about the failed request. It includes the status code, response headers, response body, and the URL that was accessed.

This error type is created by StatusCodeError when an HTTP response has a non-successful status code (not 2xx).

Example:

if httpErr, ok := err.(*HttpError); ok {
    fmt.Printf("Status: %d\n", httpErr.StatusCode())
    fmt.Printf("URL: %s\n", httpErr.URL())
    fmt.Printf("Body: %s\n", string(httpErr.Body()))
}

func (*HttpError) Body

func (r *HttpError) Body() []byte

Body returns the response body bytes from the failed response. This can be useful for debugging or displaying error messages from the server.

Example:

if httpErr, ok := err.(*HttpError); ok {
    body := httpErr.Body()
    fmt.Printf("Error response: %s\n", string(body))
}

func (*HttpError) Error

func (r *HttpError) Error() string

Error implements the error interface for HttpError. It returns a formatted error message including the status code and URL.

func (*HttpError) Headers

func (r *HttpError) Headers() H.Header

Headers returns a clone of the HTTP headers from the failed response. The headers are cloned to prevent modification of the original response.

Example:

if httpErr, ok := err.(*HttpError); ok {
    headers := httpErr.Headers()
    contentType := headers.Get("Content-Type")
}

func (*HttpError) StatusCode

func (r *HttpError) StatusCode() int

StatusCode returns the HTTP status code from the failed response.

Example:

if httpErr, ok := err.(*HttpError); ok {
    code := httpErr.StatusCode()  // e.g., 404, 500
}

func (*HttpError) String

func (r *HttpError) String() string

String returns the string representation of the HttpError. It's equivalent to calling Error().

func (*HttpError) URL

func (r *HttpError) URL() *url.URL

URL returns the URL that was accessed when the error occurred.

Example:

if httpErr, ok := err.(*HttpError); ok {
    url := httpErr.URL()
    fmt.Printf("Failed to access: %s\n", url)
}

type ParsedMediaType

type ParsedMediaType = P.Pair[string, map[string]string]

ParsedMediaType represents a parsed MIME media type as a Pair. The first element is the media type string (e.g., "application/json"), and the second element is a map of parameters (e.g., {"charset": "utf-8"}).

Example:

parsed := ParseMediaType("application/json; charset=utf-8")
mediaType := P.Head(parsed)      // "application/json"
params := P.Tail(parsed)         // map[string]string{"charset": "utf-8"}

Directories

Path Synopsis
Package builder provides a functional, immutable HTTP request builder with composable operations.
Package builder provides a functional, immutable HTTP request builder with composable operations.
Package headers provides constants and utilities for working with HTTP headers in a functional programming style.
Package headers provides constants and utilities for working with HTTP headers in a functional programming style.

Jump to

Keyboard shortcuts

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