httpmock: with-body-closure
Exhibit path: docs/examples/codegen/httpmock/with-body-closure/
A handler that uses a body closure to generate response bodies per call. Shows how to return different payloads on repeated requests to the same route without registering multiple handlers.
Input (in.go)
go
//go:build glacier_codegen_fixture
// Package apiclient defines the HTTP transport for the dynamic API client.
package apiclient
import "net/http"
// DynamicTransport is an HTTP transport that generates response bodies per call.
//
// +glacier:mock
// +glacier:httpmock body=closure
type DynamicTransport interface {
// RoundTrip executes an HTTP request.
RoundTrip(req *http.Request) (*http.Response, error)
}Output (out.go)
go
//go:build glacier_codegen_fixture
// Code generated by glaciergen. DO NOT EDIT.
// Source: in.go
package apiclient
import (
"io"
"net/http"
"github.com/nathanbrophy/glacier/httpmock"
)
// MockDynamicTransport is a generated httpmock-backed transport for DynamicTransport.
// Routes support a BodyFunc closure for per-request response body generation.
type MockDynamicTransport struct {
router *httpmock.Router
}
// NewMockDynamicTransport returns a MockDynamicTransport with an empty route table.
func NewMockDynamicTransport() *MockDynamicTransport {
return &MockDynamicTransport{router: httpmock.NewRouter()}
}
// Route registers a handler for the given method and path pattern.
func (m *MockDynamicTransport) Route(method, path string, handler httpmock.Handler) {
m.router.Route(method, path, handler)
}
// RouteFunc registers a handler whose body is produced by a closure on each call.
// The closure receives the matched *http.Request and returns an io.Reader.
func (m *MockDynamicTransport) RouteFunc(method, path string, status int, bodyFn func(*http.Request) io.Reader) {
m.router.RouteFunc(method, path, status, bodyFn)
}
// RoundTrip implements DynamicTransport (and http.RoundTripper).
func (m *MockDynamicTransport) RoundTrip(req *http.Request) (*http.Response, error) {
return m.router.RoundTrip(req)
}What the generator did
- Generated the
MockTransportscaffold with aBodyFunchandler field alongside the standardBodyfield. - When
BodyFuncis non-nil, the mock calls it on each request to produce the response body. The closure receives the*http.Requestso it can vary the response based on query parameters or headers. httpcbody closures are called once per attempt; retries are correct by construction because the closure produces a freshio.Readeron each call.