fetch is a focused helper package for downloading data from URL endpoints.
It wraps common net/http idioms so callers can handle download flows with less boilerplate and safer defaults.
- Keep application code simple for one-shot data fetching.
- Hide repetitive
net/httphandling patterns. - Keep API surface small and composable.
- Use
context.Contextbased operations as the default style.
- Go 1.25 or later
- Task command (local tool for this repository)
task test
task govulncheck
Run all maintenance tasks:
task
ci: lint (golangci-lintwithgosec), tests, andgovulncheckCodeQL: scheduled and push/PR static analysis
go get github.com/goark/fetch@latestimport "github.com/goark/fetch"All sample files under sample/ use the run build tag.
go run -tags run ./sample/sample.go
- Basic GET download: sample/sample.go
package main
import (
"context"
"fmt"
"io"
"os"
"github.com/goark/fetch"
)
func main() {
u, err := fetch.URL("https://github.com/spiegel-im-spiegel.gpg")
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
resp, err := fetch.New().GetWithContext(context.Background(), u)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
defer resp.Close()
if _, err := io.Copy(os.Stdout, resp.Body()); err != nil {
fmt.Fprintln(os.Stderr, err)
}
}payload := strings.NewReader("name=alice")
resp, err := fetch.New().PostWithContext(ctx, u, payload,
fetch.WithRequestHeaderSet("Content-Type", "application/x-www-form-urlencoded"),
)
if err != nil {
return err
}
defer resp.Close()fetch.URL(raw string)parses and validates URL input.fetch.New(opts ...fetch.ClientOpts)creates a fetch client.Client.GetWithContext(ctx, u, opts...)performs GET request.Client.PostWithContext(ctx, u, payload, opts...)performs POST request.fetch.WithHTTPClient(cli)injects custom*http.Client.fetch.WithRequestHeaderAdd(name, value)andfetch.WithRequestHeaderSet(name, value)apply request headers.
The package wraps errors, so use errors.Is for checks against:
fetch.ErrInvalidURLfetch.ErrInvalidRequestfetch.ErrHTTPStatus
if err != nil {
switch {
case errors.Is(err, fetch.ErrInvalidURL):
// invalid URL input
case errors.Is(err, fetch.ErrHTTPStatus):
// non-success HTTP status (>= 400)
}
}Always close the response:
defer resp.Close()for streaming use.- Use
resp.DumpBodyAndClose()when you need body bytes at once.
