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 ¶
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 ¶
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] )
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
Error implements the error interface for HttpError. It returns a formatted error message including the status code and URL.
func (*HttpError) Headers ¶
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 ¶
StatusCode returns the HTTP status code from the failed response.
Example:
if httpErr, ok := err.(*HttpError); ok {
code := httpErr.StatusCode() // e.g., 404, 500
}
type ParsedMediaType ¶
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. |