qst

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Jun 27, 2025 License: MIT Imports: 12 Imported by: 4

README

qst

Go Reference Go Report Card codecov gosec

qst is an *http.Request builder. "qst" is short for "quest", which is part of the word "request".

Installation

go get github.com/broothie/qst

Documentation

Detailed documentation can be found at pkg.go.dev.

A list of all available options can be found here.

Usage

qst uses an options pattern to build *http.Request objects:

request, err := qst.NewPatch("https://breakfast.com/api", // New PATCH request
    qst.WithBearerAuth("c0rNfl@k3s"),                         // Authorization header
    qst.WithPath("/cereals", cerealID),                       // Query param
    qst.WithBodyJSON(map[string]string{"name": "Life"}),      // JSON body
)

It can also be used to fire requests:

response, err := qst.Patch("https://breakfast.com/api", // Send PATCH request
    qst.WithBearerAuth("c0rNfl@k3s"),                       // Authorization header
    qst.WithPath("/cereals", cerealID),                     // Query param
    qst.WithBodyJSON(map[string]string{"name": "Life"}),    // JSON body
)

The options pattern makes it easy to define custom options:

func createdSinceYesterday() option.Option[*http.Request] {
    yesterday := time.Now().Add(-24 * time.Hour)
    return qst.WithQuery("created_at", fmt.Sprintf(">%s", yesterday.Format(time.RFC3339)))
}

func main() {
    response, err := qst.Get("https://breakfast.com/api",
        qst.WithBearerAuth("c0rNfl@k3s"),
        qst.WithPath("/cereals"),
        createdSinceYesterday(),
    )
}

You can also combine multiple options using option.NewOptions() to create reusable defaults:

func myDefaults() option.Option[*http.Request] {
    return option.NewOptions(
        qst.WithURL("https://breakfast.com/api"),
        qst.WithBearerAuth("c0rNfl@k3s"),
    )
}

All Available Options

request, err := qst.New(
    // Use a *url.URL
    qst.WithRawURL(parsedURL),

    // Use a URL string
    qst.WithURL("https://api.example.com"),

    // Set scheme
    qst.WithScheme("https"),

    // Set host
    qst.WithHost("api.example.com"),

    // Build path from segments
    qst.WithPath("/users", userID, "/posts"),

    // Use *url.Userinfo
    qst.WithUser(userInfo),

    // Username only
    qst.WithUsername("admin"),

    // Username and password
    qst.WithUserPassword("admin", "secret"),

    // Single query param
    qst.WithQuery("page", "1"),

    // Multiple query params
    qst.WithQueries(qst.Queries{
        "page":  {"1"},
        "limit": {"10"},
    }),

    // Single header
    qst.WithHeader("X-API-Key", "secret"),

    // Multiple headers
    qst.WithHeaders(qst.Headers{
        "X-API-Key":    {"secret"},
        "X-Client-ID":  {"app123"},
    }),

    // Accept header
    qst.WithAcceptHeader("application/json"),

    // Content-Type header
    qst.WithContentTypeHeader("application/xml"),

    // Referer header
    qst.WithRefererHeader("https://example.com"),

    // User-Agent header
    qst.WithUserAgentHeader("MyApp/1.0"),

    // Authorization header
    qst.WithAuthorizationHeader("Custom token"),

    // Basic auth
    qst.WithBasicAuth("user", "pass"),

    // Token auth
    qst.WithTokenAuth("abc123"),

    // Bearer token
    qst.WithBearerAuth("jwt_token_here"),

    // Add cookie
    qst.WithCookie(&http.Cookie{
        Name:  "session",
        Value: "abc123",
    }),

    // Set context
    qst.WithContext(ctx),

    // Add context value
    qst.WithContextValue("userID", 123),

    // io.ReadCloser
    qst.WithBody(readCloser),

    // io.Reader
    qst.WithBodyReader(reader),

    // Byte slice
    qst.WithBodyBytes([]byte("data")),

    // String
    qst.WithBodyString("plain text"),

    // URL-encoded form
    qst.WithBodyForm(qst.Form{
        "username": {"john"},
        "email":    {"[email protected]"},
    }),

    // JSON body
    qst.WithBodyJSON(map[string]interface{}{
        "name": "John",
        "age":  30,
    }),

    // XML body
    qst.WithBodyXML(struct{
        Name string `xml:"name"`
        Age  int    `xml:"age"`
    }{
        Name: "John",
        Age:  30,
    }),

    // Dump request to writer
    qst.WithDump(os.Stdout),
)

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Connect

func Connect(url string, options ...option.Option[*http.Request]) (*http.Response, error)

Connect makes a CONNECT request and returns the *http.Response.

func Delete

func Delete(url string, options ...option.Option[*http.Request]) (*http.Response, error)

Delete makes a DELETE request and returns the *http.Response.

func Do

func Do(method, url string, options ...option.Option[*http.Request]) (*http.Response, error)

Do makes an *http.Request using the global client and returns the *http.Response.

Example
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"

	"github.com/broothie/qst"
)

func main() {
	server := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) {
		fmt.Println(r.Method)
		fmt.Println(r.URL)
		fmt.Println(r.Header.Get("Authorization"))
		body, _ := ioutil.ReadAll(r.Body)
		fmt.Println(string(body))
	}))
	defer server.Close()

	qst.Do(http.MethodPost, server.URL,
		qst.WithPath("api", "/cereals", "1234"),
		qst.WithBearerAuth("c0rnfl@k3s"),
		qst.WithBodyJSON(map[string]string{"name": "Honey Bunches of Oats"}),
	)

}
Output:

POST
/api/cereals/1234
Bearer c0rnfl@k3s
{"name":"Honey Bunches of Oats"}

func Get

func Get(url string, options ...option.Option[*http.Request]) (*http.Response, error)

Get makes a GET request and returns the *http.Response.

func Head(url string, options ...option.Option[*http.Request]) (*http.Response, error)

Head makes a HEAD request and returns the *http.Response.

func New

func New(method, url string, options ...option.Option[*http.Request]) (*http.Request, error)

New builds a new *http.Request.

Example
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"

	"github.com/broothie/qst"
)

func main() {
	req, _ := qst.New(http.MethodPost, "http://bfast.com/api",
		qst.WithScheme("https"),
		qst.WithHost("breakfast.com"),
		qst.WithPath("/cereals", "1234"),
		qst.WithBearerAuth("c0rnfl@k3s"),
		qst.WithBodyJSON(map[string]string{"name": "Honey Bunches of Oats"}),
	)

	fmt.Println(req.Method)
	fmt.Println(req.URL)
	fmt.Println(req.Header.Get("Authorization"))
	body, _ := ioutil.ReadAll(req.Body)
	fmt.Println(string(body))

}
Output:

POST
https://breakfast.com/api/cereals/1234
Bearer c0rnfl@k3s
{"name":"Honey Bunches of Oats"}

func NewConnect

func NewConnect(url string, options ...option.Option[*http.Request]) (*http.Request, error)

NewConnect builds a new *http.Request with method CONNECT.

func NewDelete

func NewDelete(url string, options ...option.Option[*http.Request]) (*http.Request, error)

NewDelete builds a new *http.Request with method DELETE.

func NewGet

func NewGet(url string, options ...option.Option[*http.Request]) (*http.Request, error)

NewGet builds a new *http.Request with method GET.

func NewHead

func NewHead(url string, options ...option.Option[*http.Request]) (*http.Request, error)

NewHead builds a new *http.Request with method HEAD.

func NewOptions

func NewOptions(url string, options ...option.Option[*http.Request]) (*http.Request, error)

NewOptions builds a new *http.Request with method OPTIONS.

func NewPatch

func NewPatch(url string, options ...option.Option[*http.Request]) (*http.Request, error)

NewPatch builds a new *http.Request with method PATCH.

func NewPost

func NewPost(url string, options ...option.Option[*http.Request]) (*http.Request, error)

NewPost builds a new *http.Request with method POST.

func NewPut

func NewPut(url string, options ...option.Option[*http.Request]) (*http.Request, error)

NewPut builds a new *http.Request with method PUT.

func NewTrace

func NewTrace(url string, options ...option.Option[*http.Request]) (*http.Request, error)

NewTrace builds a new *http.Request with method TRACE.

func Options

func Options(url string, options ...option.Option[*http.Request]) (*http.Response, error)

Options makes a OPTIONS request and returns the *http.Response.

func Patch

func Patch(url string, options ...option.Option[*http.Request]) (*http.Response, error)

Patch makes a PATCH request and returns the *http.Response.

func Post

func Post(url string, options ...option.Option[*http.Request]) (*http.Response, error)

Post makes a POST request and returns the *http.Response.

func Put

func Put(url string, options ...option.Option[*http.Request]) (*http.Response, error)

Put makes a PUT request and returns the *http.Response.

func SetClient added in v0.1.2

func SetClient(c *http.Client)

SetClient sets the global HTTP client used by the Do function.

func Trace

func Trace(url string, options ...option.Option[*http.Request]) (*http.Response, error)

Trace makes a TRACE request and returns the *http.Response.

func WithAcceptHeader added in v0.1.2

func WithAcceptHeader(accept string) option.Option[*http.Request]

WithAcceptHeader applies an "Accept" header to the *http.Request.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithAcceptHeader("application/json"),
	)

	fmt.Println(request.Header.Get("Accept"))
}
Output:

application/json

func WithAuthorizationHeader added in v0.1.2

func WithAuthorizationHeader(authorization string) option.Option[*http.Request]

WithAuthorizationHeader applies an "Authorization" header to the *http.Request.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithAuthorizationHeader("c0rnfl@k3s"),
	)

	fmt.Println(request.Header.Get("Authorization"))
}
Output:

c0rnfl@k3s

func WithBasicAuth added in v0.1.2

func WithBasicAuth(username, password string) option.Option[*http.Request]

WithBasicAuth applies a username and password basic auth header.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithBasicAuth("TonyTheTiger", "grrreat"),
	)

	fmt.Println(request.Header.Get("Authorization"))
}
Output:

Basic VG9ueVRoZVRpZ2VyOmdycnJlYXQ=

func WithBearerAuth added in v0.1.2

func WithBearerAuth(token string) option.Option[*http.Request]

WithBearerAuth applies an "Authorization: Bearer <token>" header to the *http.Request.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithBearerAuth("c0rnfl@k3s"),
	)

	fmt.Println(request.Header.Get("Authorization"))
}
Output:

Bearer c0rnfl@k3s

func WithBody added in v0.1.2

func WithBody(body io.ReadCloser) option.Option[*http.Request]

WithBody applies an io.ReadCloser to the *http.Request body.

Example
package main

import (
	"bytes"
	"fmt"
	"io/ioutil"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewPost("https://breakfast.com/api/cereals",
		qst.WithBody(ioutil.NopCloser(bytes.NewBufferString("Part of a complete breakfast."))),
	)

	body, _ := ioutil.ReadAll(request.Body)
	fmt.Println(string(body))
}
Output:

Part of a complete breakfast.

func WithBodyBytes added in v0.1.2

func WithBodyBytes(body []byte) option.Option[*http.Request]

WithBodyBytes applies a slice of bytes to the *http.Request body.

Example
package main

import (
	"fmt"
	"io/ioutil"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewPost("https://breakfast.com/api/cereals",
		qst.WithBodyBytes([]byte("Part of a complete breakfast.")),
	)

	body, _ := ioutil.ReadAll(request.Body)
	fmt.Println(string(body))
}
Output:

Part of a complete breakfast.

func WithBodyJSON added in v0.1.2

func WithBodyJSON(v interface{}) option.Option[*http.Request]

WithBodyJSON encodes an object as JSON and applies it to the *http.Request body.

Example
package main

import (
	"fmt"
	"io/ioutil"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewPost("https://breakfast.com/api/cereals",
		qst.WithBodyJSON(map[string]string{"name": "Rice Krispies"}),
	)

	body, _ := ioutil.ReadAll(request.Body)
	fmt.Println(string(body))
}
Output:

{"name":"Rice Krispies"}

func WithBodyReader added in v0.1.2

func WithBodyReader(body io.Reader) option.Option[*http.Request]

WithBodyReader applies an io.Reader to the *http.Request body.

func WithBodyString added in v0.1.2

func WithBodyString(body string) option.Option[*http.Request]

WithBodyString applies a string to the *http.Request body.

Example
package main

import (
	"fmt"
	"io/ioutil"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewPost("https://breakfast.com/api/cereals",
		qst.WithBodyString("Part of a complete breakfast."),
	)

	body, _ := ioutil.ReadAll(request.Body)
	fmt.Println(string(body))
}
Output:

Part of a complete breakfast.

func WithBodyXML added in v0.1.2

func WithBodyXML(v interface{}) option.Option[*http.Request]

WithBodyXML encodes an object as XML and applies it to the *http.Request body.

Example
package main

import (
	"fmt"
	"io/ioutil"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewPost("https://breakfast.com/api/cereals",
		qst.WithBodyXML("Part of a complete breakfast."),
	)
	body, _ := ioutil.ReadAll(request.Body)
	fmt.Println(string(body))
}
Output:

<string>Part of a complete breakfast.</string>

func WithContentTypeHeader added in v0.1.2

func WithContentTypeHeader(contentType string) option.Option[*http.Request]

WithContentTypeHeader applies a "Content-Type" to the *http.Request.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithContentTypeHeader("application/json"),
	)

	fmt.Println(request.Header.Get("Content-Type"))
}
Output:

application/json

func WithContext added in v0.1.2

func WithContext(ctx context.Context) option.Option[*http.Request]

WithContext applies a context.Context to the *http.Request.

func WithContextValue added in v0.1.2

func WithContextValue(key, value interface{}) option.Option[*http.Request]

WithContextValue applies a context key/value pair to the *http.Request.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithContextValue("frosted", true),
	)

	fmt.Println(request.Context().Value("frosted"))
}
Output:

true

func WithCookie added in v0.1.2

func WithCookie(cookie *http.Cookie) option.Option[*http.Request]

WithCookie applies a cookie to the *http.Request.

Example
package main

import (
	"fmt"
	"net/http"
	"time"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithCookie(&http.Cookie{
			Name:    "cookie-crisp",
			Value:   "COOOOKIE CRISP!",
			Path:    "/",
			Expires: time.Now().Add(time.Hour),
		}),
	)

	fmt.Println(request.Cookie("cookie-crisp"))
}
Output:

cookie-crisp="COOOOKIE CRISP!" <nil>

func WithDump added in v0.1.2

func WithDump(w io.Writer) option.Option[*http.Request]

WithDump writes the request to w.

func WithHeader added in v0.1.2

func WithHeader(key, value string) option.Option[*http.Request]

WithHeader applies a key/value pair to the headers of the *http.Request, retaining the existing headers for the key.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithHeader("grain", "oats"),
	)

	fmt.Println(request.Header.Get("grain"))
}
Output:

oats

func WithHost added in v0.1.2

func WithHost(host string) option.Option[*http.Request]

WithHost applies the host to the *http.Request and *http.Request URL.

func WithPath added in v0.1.2

func WithPath(segments ...string) option.Option[*http.Request]

WithPath joins the segments with path.Join, and appends the result to the *http.Request URL.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/",
		qst.WithPath("/cereals", "1234/variants", "frosted"),
	)

	fmt.Println(request.URL.Path)
}
Output:

/api/cereals/1234/variants/frosted

func WithQuery added in v0.1.2

func WithQuery(key, value string) option.Option[*http.Request]

WithQuery applies a key/value pair to the query parameters of the *http.Request.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithQuery("page", "10"),
	)

	fmt.Println(request.URL.Query().Encode())
}
Output:

page=10

func WithRawURL added in v0.1.2

func WithRawURL(url *pkgurl.URL) option.Option[*http.Request]

WithRawURL applies the URL to the *http.Request.

func WithRefererHeader added in v0.1.2

func WithRefererHeader(referer string) option.Option[*http.Request]

WithRefererHeader applies a "Referer" header to the *http.Request.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithRefererHeader("https://breakfast.com"),
	)

	fmt.Println(request.Header.Get("Referer"))
}
Output:

https://breakfast.com

func WithScheme added in v0.1.2

func WithScheme(scheme string) option.Option[*http.Request]

WithScheme applies the scheme to the *http.Request URL.

func WithTokenAuth added in v0.1.2

func WithTokenAuth(token string) option.Option[*http.Request]

WithTokenAuth applies an "Authorization: Token <token>" header to the *http.Request.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithTokenAuth("c0rnfl@k3s"),
	)

	fmt.Println(request.Header.Get("Authorization"))
}
Output:

Token c0rnfl@k3s

func WithURL added in v0.1.2

func WithURL(url string) option.Option[*http.Request]

WithURL applies a url string to the *http.Request.

func WithUser added in v0.1.2

func WithUser(user *pkgurl.Userinfo) option.Option[*http.Request]

WithUser applies the Userinfo to the *http.Request URL User.

func WithUserAgentHeader added in v0.1.2

func WithUserAgentHeader(userAgent string) option.Option[*http.Request]

WithUserAgentHeader applies a "User-Agent" header to the *http.Request.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithUserAgentHeader("qst"),
	)

	fmt.Println(request.Header.Get("User-Agent"))
}
Output:

qst

func WithUserPassword added in v0.1.2

func WithUserPassword(username, password string) option.Option[*http.Request]

WithUserPassword applies the username and password to *http.Request URL User.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithUserPassword("TonyTheTiger", "grrreat"),
	)

	fmt.Println(request.URL)
}
Output:

https://TonyTheTiger:[email protected]/api/cereals

func WithUsername added in v0.1.2

func WithUsername(username string) option.Option[*http.Request]

WithUsername applies the username to *http.Request URL User.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithUsername("TonyTheTiger"),
	)

	fmt.Println(request.URL)
}
Output:

https://[email protected]/api/cereals

Types

type WithBodyForm added in v0.1.2

type WithBodyForm pkgurl.Values

WithBodyForm URL-encodes multiple key/value pairs and applies the result to the *http.Request body.

Example
package main

import (
	"fmt"
	"io/ioutil"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewPost("https://breakfast.com/api/cereals",
		qst.WithBodyForm{"name": {"Grape Nuts"}},
	)

	body, _ := ioutil.ReadAll(request.Body)
	fmt.Println(string(body))
}
Output:

name=Grape+Nuts

func (WithBodyForm) Apply added in v0.1.2

func (f WithBodyForm) Apply(request *http.Request) (*http.Request, error)

Apply URL-encodes the WithBodyForm and applies the result to the *http.Request body.

type WithHeaders added in v0.1.2

type WithHeaders http.Header

WithHeaders applies multiple key/value pairs to the headers of the *http.Request. It wraps http.Header.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithHeaders{
			"grain": {"oats"},
			"style": {"toasted"},
		},
	)

	fmt.Println(request.Header)
}
Output:

map[Grain:[oats] Style:[toasted]]

func (WithHeaders) Apply added in v0.1.2

func (h WithHeaders) Apply(request *http.Request) (*http.Request, error)

Apply applies the WithHeaders to the *http.Request.

type WithQueries added in v0.1.2

type WithQueries pkgurl.Values

WithQueries applies multiple key/value pairs to the query parameters of the *http.Request. It wraps url.Values.

Example
package main

import (
	"fmt"

	"github.com/broothie/qst"
)

func main() {
	request, _ := qst.NewGet("https://breakfast.com/api/cereals",
		qst.WithQueries{
			"page":  {"10"},
			"limit": {"50"},
		},
	)

	fmt.Println(request.URL.Query().Encode())
}
Output:

limit=50&page=10

func (WithQueries) Apply added in v0.1.2

func (q WithQueries) Apply(request *http.Request) (*http.Request, error)

Apply applies the WithQueries to the *http.Request.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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