qst

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Apr 16, 2023 License: MIT Imports: 11 Imported by: 3

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.BearerAuth("c0rNfl@k3s"),                         // Authorization header
    qst.Path("/cereals", cerealID),                       // Query param
    qst.BodyJSON(map[string]string{"name": "Life"}),      // JSON body
)

It can also be used to fire requests:

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

The options pattern makes it easy to define custom options:

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

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

This package also includes a Client, which can be outfitted with a set of default options:

client := qst.NewClient(http.DefaultClient,
    qst.URL("https://breakfast.com/api"),
    qst.BearerAuth("c0rNfl@k3s"), 
)

response, err := client.Patch(
    // qst.URL("https://breakfast.com/api"), // Not necessary, included via client
    // qst.BearerAuth("c0rNfl@k3s"),         // Not necessary, included via client
    qst.Path("/cereals", cerealID),
    qst.BodyJSON(map[string]interface{}{
        "name": "Golden Grahams",
    }),
)
qst.OptionFunc

OptionFunc can be used to add a custom function which is run during request creation:

client := qst.NewClient(http.DefaultClient,
    qst.OptionFunc(func(request *http.Request) (*http.Request, error) {
      token := dynamicallyGetBearerTokenSomehow()
      return qst.BearerAuth(token).Apply(request)
    }),
)

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultClient = NewClient(http.DefaultClient)

DefaultClient captures the current Doer.

Functions

func Apply added in v0.1.0

func Apply(request *http.Request, options ...Option) (*http.Request, error)

Apply applies the Options to the *http.Request.

func Connect

func Connect(url string, options ...Option) (*http.Response, error)

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

func Delete

func Delete(url string, options ...Option) (*http.Response, error)

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

func Do

func Do(method, url string, options ...Option) (*http.Response, error)

Do makes an *http.Request using the current DefaultClient 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.Path("api", "/cereals", "1234"),
		qst.BearerAuth("c0rnfl@k3s"),
		qst.BodyJSON(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) (*http.Response, error)

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

func Head(url string, options ...Option) (*http.Response, error)

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

func New

func New(method, url string, options ...Option) (*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.Scheme("https"),
		qst.Host("breakfast.com"),
		qst.Path("/cereals", "1234"),
		qst.BearerAuth("c0rnfl@k3s"),
		qst.BodyJSON(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) (*http.Request, error)

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

func NewDelete

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

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

func NewGet

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

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

func NewHead

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

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

func NewOptions

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

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

func NewPatch

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

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

func NewPost

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

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

func NewPut

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

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

func NewTrace

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

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

func Options

func Options(url string, options ...Option) (*http.Response, error)

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

func Patch

func Patch(url string, options ...Option) (*http.Response, error)

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

func Post

func Post(url string, options ...Option) (*http.Response, error)

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

func Put

func Put(url string, options ...Option) (*http.Response, error)

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

func Trace

func Trace(url string, options ...Option) (*http.Response, error)

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

Types

type BodyForm

type BodyForm pkgurl.Values

BodyForm 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.BodyForm{"name": {"Grape Nuts"}},
	)

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

name=Grape+Nuts

func (BodyForm) Apply

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

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

type Client

type Client struct {
	Pipeline
	// contains filtered or unexported fields
}

Client captures a Doer and Options to apply to every request.

func NewClient added in v0.1.0

func NewClient(doer Doer, options ...Option) *Client

NewClient creates a new Client.

Example
package main

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

	"github.com/broothie/qst"
)

func main() {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Println(r.Header.Get("Authorization"))
		fmt.Println(r.URL.RawQuery)
	}))
	defer server.Close()

	client := qst.NewClient(http.DefaultClient,
		qst.URL(server.URL),
		qst.BearerAuth("c0rnfl@k3s"),
	)

	client.Get(qst.Query("page", "10"))
}
Output:

Bearer c0rnfl@k3s
page=10

func (*Client) Connect

func (c *Client) Connect(options ...Option) (*http.Response, error)

Connect makes a CONNECT request and returns the *http.Response using the Doer assigned to c.

func (*Client) Delete

func (c *Client) Delete(options ...Option) (*http.Response, error)

Delete makes a DELETE request and returns the *http.Response using the Doer assigned to c.

func (*Client) Do

func (c *Client) Do(method string, options ...Option) (*http.Response, error)

Do makes an *http.Request and returns the *http.Response using the Doer assigned to c.

func (*Client) Get

func (c *Client) Get(options ...Option) (*http.Response, error)

Get makes a GET request and returns the *http.Response using the Doer assigned to c.

func (*Client) Head

func (c *Client) Head(options ...Option) (*http.Response, error)

Head makes a HEAD request and returns the *http.Response using the Doer assigned to c.

func (*Client) Options

func (c *Client) Options(options ...Option) (*http.Response, error)

Options makes a OPTIONS request and returns the *http.Response using the Doer assigned to c.

func (*Client) Patch

func (c *Client) Patch(options ...Option) (*http.Response, error)

Patch makes a PATCH request and returns the *http.Response using the Doer assigned to c.

func (*Client) Post

func (c *Client) Post(options ...Option) (*http.Response, error)

Post makes a POST request and returns the *http.Response using the Doer assigned to c.

func (*Client) Put

func (c *Client) Put(options ...Option) (*http.Response, error)

Put makes a PUT request and returns the *http.Response using the Doer assigned to c.

func (*Client) Trace

func (c *Client) Trace(options ...Option) (*http.Response, error)

Trace makes a TRACE request and returns the *http.Response using the Doer assigned to c.

type Doer

type Doer interface {
	Do(*http.Request) (*http.Response, error)
}

Doer is typically an *http.Client.

type Headers

type Headers http.Header

Headers 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.Headers{
			"grain": {"oats"},
			"style": {"toasted"},
		},
	)

	fmt.Println(request.Header)
}
Output:

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

func (Headers) Apply

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

Apply applies the Headers to the *http.Request.

type Option

type Option interface {
	Apply(request *http.Request) (*http.Request, error)
}

Option is an option for building an *http.Request.

func Accept added in v0.1.1

func Accept(accept string) Option

Accept 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.Accept("application/json"),
	)

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

application/json

func Authorization

func Authorization(authorization string) Option

Authorization 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.Authorization("c0rnfl@k3s"),
	)

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

c0rnfl@k3s

func BasicAuth

func BasicAuth(username, password string) Option

BasicAuth 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.BasicAuth("TonyTheTiger", "grrreat"),
	)

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

Basic VG9ueVRoZVRpZ2VyOmdycnJlYXQ=

func BearerAuth

func BearerAuth(token string) Option

BearerAuth 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.BearerAuth("c0rnfl@k3s"),
	)

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

Bearer c0rnfl@k3s

func Body

func Body(body io.ReadCloser) Option

Body 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.Body(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 BodyBytes

func BodyBytes(body []byte) Option

BodyBytes 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.BodyBytes([]byte("Part of a complete breakfast.")),
	)

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

Part of a complete breakfast.

func BodyJSON

func BodyJSON(v interface{}) Option

BodyJSON 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.BodyJSON(map[string]string{"name": "Rice Krispies"}),
	)

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

{"name":"Rice Krispies"}

func BodyReader added in v0.0.7

func BodyReader(body io.Reader) Option

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

func BodyString

func BodyString(body string) Option

BodyString 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.BodyString("Part of a complete breakfast."),
	)

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

Part of a complete breakfast.

func BodyXML

func BodyXML(v interface{}) Option

BodyXML 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.BodyXML("Part of a complete breakfast."),
	)
	body, _ := ioutil.ReadAll(request.Body)
	fmt.Println(string(body))
}
Output:

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

func ContentType added in v0.1.1

func ContentType(contentType string) Option

ContentType 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.ContentType("application/json"),
	)

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

application/json

func Context

func Context(ctx context.Context) Option

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

func ContextValue added in v0.0.6

func ContextValue(key, value interface{}) Option

ContextValue 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.ContextValue("frosted", true),
	)

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

true
func Cookie(cookie *http.Cookie) Option

Cookie applies a cookie to the *http.Request.

func Dump added in v0.1.0

func Dump(w io.Writer) Option

Dump writes the request to w.

func Header(key, value string) Option

Header 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.Header("grain", "oats"),
	)

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

oats

func Host added in v0.1.0

func Host(host string) Option

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

func Path added in v0.1.0

func Path(segments ...string) Option

Path 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.Path("/cereals", "1234/variants", "frosted"),
	)

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

/api/cereals/1234/variants/frosted

func Query

func Query(key, value string) Option

Query 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.Query("page", "10"),
	)

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

page=10

func RawURL added in v0.1.0

func RawURL(url *pkgurl.URL) Option

RawURL applies the URL to the *http.Request.

func Referer added in v0.1.1

func Referer(referer string) Option

Referer 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.Referer("https://breakfast.com"),
	)

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

https://breakfast.com

func Scheme added in v0.1.0

func Scheme(scheme string) Option

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

func TokenAuth added in v0.1.1

func TokenAuth(token string) Option

TokenAuth 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.TokenAuth("c0rnfl@k3s"),
	)

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

Token c0rnfl@k3s

func URL added in v0.1.0

func URL(url string) Option

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

func User added in v0.1.0

func User(user *pkgurl.Userinfo) Option

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

func UserAgent added in v0.1.1

func UserAgent(userAgent string) Option

UserAgent 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.UserAgent("qst"),
	)

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

qst

func UserPassword added in v0.1.0

func UserPassword(username, password string) Option

UserPassword 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.UserPassword("TonyTheTiger", "grrreat"),
	)

	fmt.Println(request.URL)
}
Output:

https://TonyTheTiger:grrreat@breakfast.com/api/cereals

func Username added in v0.1.0

func Username(username string) Option

Username 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.Username("TonyTheTiger"),
	)

	fmt.Println(request.URL)
}
Output:

https://TonyTheTiger@breakfast.com/api/cereals

type OptionFunc

type OptionFunc func(request *http.Request) (*http.Request, error)

OptionFunc is a function form of Option.

Example
package main

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

	"github.com/broothie/qst"
)

func main() {
	token := "c0rnfl@k3s"

	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Println(r.Header.Get("Authorization"))
	}))
	defer server.Close()

	client := qst.NewClient(server.Client(),
		qst.URL(server.URL),
		qst.OptionFunc(func(request *http.Request) (*http.Request, error) {
			return qst.BearerAuth(token).Apply(request)
		}),
	)

	client.Get()
	token = "c00ki3cr!5p"
	client.Get()

}
Output:

Bearer c0rnfl@k3s
Bearer c00ki3cr!5p

func (OptionFunc) Apply

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

Apply applies the OptionFunc to the *http.Request.

type Pipeline

type Pipeline []Option

Pipeline is a collection of options, which can be applied as a whole.

func (Pipeline) Apply

func (p Pipeline) Apply(request *http.Request) (*http.Request, error)

Apply applies the Pipeline to the *http.Request.

func (Pipeline) With added in v0.1.0

func (p Pipeline) With(options ...Option) Pipeline

type Queries added in v0.1.0

type Queries pkgurl.Values

Queries 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.Queries{
			"page":  {"10"},
			"limit": {"50"},
		},
	)

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

limit=50&page=10

func (Queries) Apply added in v0.1.0

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

Apply applies the Queries to the *http.Request.

Jump to

Keyboard shortcuts

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