Skip to content
Carl Johnson edited this page Jun 3, 2022 · 14 revisions

Cookbook

How to do some common and uncommon tasks with requests!

Basics

GET response body as a string

var s string
err := requests.
	URL("http://example.com").
	ToString(&s).
	Fetch(context.Background())

POST raw bytes

err := requests.
	URL("https://postman-echo.com/post").
	BodyBytes([]byte(`hello, world`)).
	ContentType("text/plain").
	Fetch(context.Background())

GET JSON object

var data SomeDataType
err := requests.
	URL("https://example.com/my-json").
	ToJSON(&data).
	Fetch(context.Background())

POST JSON and parse JSON response

body := MyRequestType{}
var resp MyResponseType
err := requests.
	URL("https://example.com/my-json").
	BodyJSON(&body).
	ToJSON(&resp).
	Fetch(context.Background())

Custom headers

// Set headers
var headers postman
err := requests.
	URL("https://postman-echo.com/get").
	UserAgent("bond/james-bond").
	ContentType("secret").
	Header("martini", "shaken").
	Fetch(context.Background())

Query parameters

var params postman
err := requests.
	URL("https://example.com/get?a=1&b=2").
	Param("b", "3").
	Param("c", "4").
	Fetch(context.Background())
	// URL is https://example.com/get?a=1&b=3&c=4

Send or save a file

// Save a file
err := requests.
	URL("http://example.com").
	ToFile("myfile.txt").
	Fetch(context.Background())

// Send a file
err := requests.
	URL("http://example.com").
	BodyFile("myfile.txt").
	ContentType("text/plain").
	Fetch(context.Background())

Advanced techniques

Write your own BodyGetter or Config

Write your own validators/handlers as a ResponseHandler

Create and use custom transports

You can do almost anything by writing a requests.RoundTripFunc. Remember that the http.RoundTripper interface requires that you copy requests before modifying them. Other than that, the sky is the limit.

  • Validate certificates

Always set Content-Length

Ensure that a request has a fixed Content-Length for the server by writing body to buffer before sending.

func BufferedBodyTransport(rt http.RoundTripper) http.RoundTripper {
	if rt == nil {
		rt = http.DefaultTransport
	}
	return requests.RoundTripFunc(func(req *http.Request) (res *http.Response, err error) {
		var buf bytes.Buffer
		if _, err = io.Copy(&buf, req.Body); err != nil {
			return
		}
		// shallow copy req before modifying
		req2 := *req
		data := buf.Bytes()
		req2.Body = io.NopCloser(bytes.NewReader(data))
		req2.ContentLength = int64(len(data))
		req2.GetBody = func() (io.ReadCloser, error) {
			return io.NopCloser(bytes.NewReader(data)), nil
		}

		return rt.RoundTrip(&req2)
	})
}

var s string
err := requests.
	URL("http://example.com").
	BodyReader(MyXMLReader()).
	Transport(BufferedBodyTransport).
	ToString(&s).
	Fetch(ctx)

Basic rate limiting

ctx := context.Background()
cancelled := errors.New("context was cancelled")
l := rate.NewLimiter(15.0/60, 15)
func RateLimitTransport(rt http.RoundTripper) http.RoundTripper {
	if rt == nil {
		rt = http.DefaultTransport
	}
	return requests.RoundTripFunc(func(req *http.Request) (res *http.Response, err error) {
		if err := l.Wait(ctx); err != nil {
			return nil, cancelled
		}

		return rt.RoundTrip(req)
	})
}

var s string
err := requests.
	URL("http://example.com").
	Transport(RateLimitTransport(nil)).
	ToString(&s).
	Fetch(ctx)
Clone this wiki locally