request_builder

package module
v0.2.3 Latest Latest
Warning

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

Go to latest
Published: Mar 12, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package request_builder provides a fluent HTTP request builder for constructing and executing HTTP requests with automatic response body loading.

Overview

The central type is RequestBuilder, which wraps net/http.Request and net/http.Client and exposes a method-chaining-friendly API for configuring the method, URL, headers, and body before executing the request with RequestBuilder.Do.

The response is returned as a BuilderResponse, which reads the entire body into memory and exposes it as a plain string pointer. For structured payloads the response can be decoded directly with BuilderResponse.DecodeJSON or BuilderResponse.DecodeXML.

Basic usage

rb := request_builder.NewRequestBuilder()
rb.SetHostnameAndPort("api.example.com")
rb.SetURLPath("/v1/users")
rb.Headers().Set("Authorization", "Bearer my-token")

res, err := rb.Do()
if err != nil {
    log.Fatal(err)
}
fmt.Println(*res.Body)

Decoding a JSON response

type User struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

var u User
if err := res.DecodeJSON(&u); err != nil {
    log.Fatal(err)
}
fmt.Println(u.Name)

Index

Examples

Constants

View Source
const (
	POST   = "POST"
	GET    = "GET"
	DELETE = "DELETE"
	PUT    = "PUT"
	HEAD   = "HEAD"
)

HTTP method constants for use with RequestBuilder.

View Source
const (
	HTTP  = "http"
	HTTPS = "https"
)

URL scheme constants.

View Source
const (
	// NOT_IMPLEMENTED_ERROR is returned as a panic message for features that
	// have not been implemented yet.
	NOT_IMPLEMENTED_ERROR = "ERROR: Not implemented yet!"
)

errors

View Source
const (
	RESPONSE_LOADER_BUFFER_SIZE = 1_000_000
)

RESPONSE_LOADER_BUFFER_SIZE is the size in bytes of the read buffer used when loading the HTTP response body into memory.

Variables

This section is empty.

Functions

This section is empty.

Types

type BuilderResponse

type BuilderResponse struct {
	// StatusCode is the HTTP status code of the response (e.g. 200, 404).
	StatusCode int
	// Response is the underlying [net/http.Response]. Note that Body has already
	// been read and closed; do not attempt to read it again.
	Response http.Response
	// Body contains the full response body as a string. It is nil only when the
	// response itself was nil.
	Body *string
}

BuilderResponse is returned by RequestBuilder.Do and holds the HTTP status code, the original net/http.Response, and the response body pre-loaded as a plain string.

func (*BuilderResponse) DecodeJSON

func (this *BuilderResponse) DecodeJSON(v any) error

DecodeJSON parses the response body as JSON and stores the result in the value pointed to by v. It is a convenience wrapper around encoding/json.Unmarshal.

var result MyStruct
if err := res.DecodeJSON(&result); err != nil {
    log.Fatal(err)
}
Example

ExampleBuildResponse_DecodeJSON demonstrates unmarshalling a JSON response body into a Go struct.

package main

import (
	"fmt"
	"log"
	"net/http"
	"net/http/httptest"

	request_builder "github.com/Xmajk/RequestBuilder"
)

func main() {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, `{"id":1,"name":"Alice"}`)
	}))
	defer srv.Close()

	rb := request_builder.NewRequestBuilder()
	rb.Request.URL.Scheme = "http"
	rb.SetHostnameAndPort(srv.Listener.Addr().String())

	res, err := rb.Do()
	if err != nil {
		log.Fatal(err)
	}

	type User struct {
		ID   int    `json:"id"`
		Name string `json:"name"`
	}

	var u User
	if err := res.DecodeJSON(&u); err != nil {
		log.Fatal(err)
	}

	fmt.Printf("ID=%d Name=%s\n", u.ID, u.Name)
}
Output:
ID=1 Name=Alice

func (*BuilderResponse) DecodeXML

func (this *BuilderResponse) DecodeXML(v any) error

DecodeXML parses the response body as XML and stores the result in the value pointed to by v. It is a convenience wrapper around encoding/xml.Unmarshal.

var result MyStruct
if err := res.DecodeXML(&result); err != nil {
    log.Fatal(err)
}
Example

ExampleBuildResponse_DecodeXML demonstrates unmarshalling an XML response body into a Go struct.

package main

import (
	"fmt"
	"log"
	"net/http"
	"net/http/httptest"

	request_builder "github.com/Xmajk/RequestBuilder"
)

func main() {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/xml")
		fmt.Fprintln(w, `<user><id>2</id><name>Bob</name></user>`)
	}))
	defer srv.Close()

	rb := request_builder.NewRequestBuilder()
	rb.Request.URL.Scheme = "http"
	rb.SetHostnameAndPort(srv.Listener.Addr().String())

	res, err := rb.Do()
	if err != nil {
		log.Fatal(err)
	}

	type User struct {
		ID   int    `xml:"id"`
		Name string `xml:"name"`
	}

	var u User
	if err := res.DecodeXML(&u); err != nil {
		log.Fatal(err)
	}

	fmt.Printf("ID=%d Name=%s\n", u.ID, u.Name)
}
Output:
ID=2 Name=Bob

type RequestBuilder

type RequestBuilder struct {
	// Request is the underlying HTTP request being built.
	Request http.Request
	// Client is the HTTP client used to execute the request.
	Client *http.Client
}

RequestBuilder wraps an net/http.Request and its associated net/http.Client, providing a convenient API for building and executing HTTP requests.

Use NewRequestBuilder to obtain a properly initialised instance.

func NewRequestBuilder

func NewRequestBuilder() *RequestBuilder

NewRequestBuilder returns a new RequestBuilder with sensible defaults: the HTTP method is set to GET, the scheme to HTTPS, and the client to net/http.DefaultClient.

Example

ExampleNewRequestBuilder demonstrates creating a builder and performing a simple GET request.

package main

import (
	"fmt"
	"log"
	"net/http"
	"net/http/httptest"

	request_builder "github.com/Xmajk/RequestBuilder"
)

func main() {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "hello")
	}))
	defer srv.Close()

	rb := request_builder.NewRequestBuilder()
	rb.SetHostnameAndPort(srv.Listener.Addr().String())
	rb.SetSchema(request_builder.HTTP)
	rb.Request.URL.Scheme = "http"

	res, err := rb.Do()
	if err != nil {
		log.Fatal(err)
	}

	fmt.Print(*res.Body)
}
Output:
hello

func (*RequestBuilder) Do

func (this *RequestBuilder) Do() (*BuilderResponse, error)

Do executes the HTTP request and returns a BuilderResponse whose body has been fully read into memory.

An error is returned if the request fails or if the response body cannot be read.

func (*RequestBuilder) Headers

func (this *RequestBuilder) Headers() http.Header

Headers returns the net/http.Header map of the underlying request, allowing callers to add, set, or delete headers directly.

rb.Headers().Set("Accept", "application/json")
rb.Headers().Add("X-Request-ID", "abc123")
Example

ExampleRequestBuilder_Headers shows how to add custom headers before sending the request.

package main

import (
	"fmt"
	"log"
	"net/http"
	"net/http/httptest"

	request_builder "github.com/Xmajk/RequestBuilder"
)

func main() {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, r.Header.Get("X-Custom"))
	}))
	defer srv.Close()

	rb := request_builder.NewRequestBuilder()
	rb.Request.URL.Scheme = "http"
	rb.SetHostnameAndPort(srv.Listener.Addr().String())
	rb.Headers().Set("X-Custom", "my-value")

	res, err := rb.Do()
	if err != nil {
		log.Fatal(err)
	}

	fmt.Print(*res.Body)
}
Output:
my-value

func (*RequestBuilder) SetBody

func (this *RequestBuilder) SetBody(body *string)

SetBody sets the request body to the content of the provided string. Passing nil results in an empty body.

Example

ExampleRequestBuilder_SetBody shows how to attach a request body for a POST request.

package main

import (
	"fmt"
	"log"
	"net/http"
	"net/http/httptest"

	request_builder "github.com/Xmajk/RequestBuilder"
)

func main() {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		buf := make([]byte, 512)
		n, _ := r.Body.Read(buf)
		fmt.Fprintf(w, "received: %s", buf[:n])
	}))
	defer srv.Close()

	rb := request_builder.NewRequestBuilder()
	rb.Request.URL.Scheme = "http"
	rb.Request.Method = request_builder.POST
	rb.SetHostnameAndPort(srv.Listener.Addr().String())

	payload := `{"action":"ping"}`
	rb.SetBody(&payload)

	res, err := rb.Do()
	if err != nil {
		log.Fatal(err)
	}

	fmt.Print(*res.Body)
}
Output:
received: {"action":"ping"}

func (*RequestBuilder) SetClient

func (this *RequestBuilder) SetClient(client *http.Client) error

SetClient replaces the HTTP client used to execute requests. Pass a custom net/http.Client to control timeouts, redirects, or transport.

func (*RequestBuilder) SetDefaultClient

func (this *RequestBuilder) SetDefaultClient() error

SetDefaultClient resets the HTTP client to net/http.DefaultClient.

func (*RequestBuilder) SetHostnameAndPort

func (this *RequestBuilder) SetHostnameAndPort(hostname string)

SetHostnameAndPort sets the host (and optional port) of the request URL. The value is passed directly to net/url.URL.Host, e.g. "example.com" or "example.com:8080".

func (*RequestBuilder) SetSchema

func (this *RequestBuilder) SetSchema(schema string) error

SetSchema sets the URL scheme of the request. Currently always sets the scheme to HTTPS regardless of the provided value.

func (*RequestBuilder) SetURLPath

func (this *RequestBuilder) SetURLPath(path string)

SetURLPath sets the path component of the request URL, e.g. "/v1/users".

Jump to

Keyboard shortcuts

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