xhttpclient

package module
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Dec 19, 2023 License: MIT Imports: 23 Imported by: 2

README

X-HTTP-Client

Install

go get github.com/electricbubble/xhttpclient

Usage

func ExampleXClient_Do() {
	type Response struct {
		Args struct {
			Hello string `json:"hello"`
		} `json:"args"`
	}

	cli := NewClient()

	var respHello Response
	_, respBody, err := cli.Do(&respHello, nil,
		NewGet().
			Path("https://httpbin.org/get").
			SetQuery("hello", "world"),
	)
	if err != nil {
		log.Fatalf("%s\n%s", err, respBody)
	}

	fmt.Println(respHello.Args.Hello)
	// Output:
	// world
}

func ExampleXClient_Do_unexpected_error() {
	cli := NewClient()

	var respEmpty any
	_, _, err := cli.Do(&respEmpty, nil,
		NewGet().
			Path("https://httpbin.org/status/", "404"),
	)
	fmt.Println(err)
	// Output:
	// unexpected error: URL: https://httpbin.org/status/404 (404 Not Found)
}

func ExampleXClient_Do_wrong_resp() {
	type GitHubError struct {
		Message          string `json:"message"`
		DocumentationUrl string `json:"documentation_url"`
	}

	cli := NewClient().BaseURL("https://api.github.com")

	var (
		respEmpty any
		respWrong GitHubError
	)
	_, respBody, err := cli.Do(&respEmpty, &respWrong,
		NewGet().
			Path("/markdown"),
	)
	if err != nil {
		log.Fatalf("%s\n%s", err, respBody)
	}
	fmt.Println(respWrong.Message)
	fmt.Println(respWrong.DocumentationUrl)
	fmt.Println(string(respBody))
	// Output:
	// Not Found
	// https://docs.github.com/rest
	// {"message":"Not Found","documentation_url":"https://docs.github.com/rest"}
}

func ExampleXClient_Do_upload() {
	tmpTestdata := filepath.Join(os.TempDir(), "testdata.json")
	if err := os.WriteFile(tmpTestdata, []byte(`{"x","go"}`), 0644); err != nil {
		log.Fatalln(err)
	}
	defer os.Remove(tmpTestdata)

	type Response struct {
		Files struct {
			Testfile string `json:"testfile"`
		} `json:"files"`
		Form struct {
			Hello string `json:"hello"`
		} `json:"form"`
	}

	cli := NewClient().BaseURL("https://httpbin.org")

	var resp Response
	_, respBody, err := cli.DoOnceWithBodyCodec(BodyCodecMultipart, &resp, nil,
		NewPost().
			Path("/post").
			Body(
				NewMultipartWriter().
					WriteWithFieldValue("hello", "world").
					WriteWithFile("testfile", tmpTestdata),
			),
	)
	if err != nil {
		log.Fatalf("%s\n%s", err, respBody)
	}

	fmt.Println(resp.Form.Hello)
	fmt.Println(resp.Files.Testfile)
	// Output:
	// world
	// {"x","go"}
}

func ExampleXClient_Do_download() {
	cli := NewClient()

	_, resp, cancel, err := cli.DoWithRaw(
		NewGet().
			Path("https://raw.githubusercontent.com/electricbubble/xhttpclient/main/LICENSE"),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer cancel()

	var buf bytes.Buffer
	if _, err = io.Copy(&buf, resp.Body); err != nil {
		log.Fatal(err)
	}

	license, _, _ := strings.Cut(buf.String(), "\n")
	fmt.Println(license)
	// Output:
	// MIT License
}

Documentation

Index

Examples

Constants

View Source
const (
	ContentTypeValueJSON           = "application/json; charset=utf-8"
	ContentTypeValueFormUrlencoded = "application/x-www-form-urlencoded"
)

Variables

This section is empty.

Functions

func BodyCodecResponseIsWrongGTE400

func BodyCodecResponseIsWrongGTE400(resp *http.Response) bool

func DefaultClient

func DefaultClient() *http.Client

func DefaultTransport

func DefaultTransport() *http.Transport

func ResponseIsSuccessfulGTE200LTE299

func ResponseIsSuccessfulGTE200LTE299(resp *http.Response) bool

Types

type BodyCodec

type BodyCodec interface {
	Get() BodyCodec
	Put(bc BodyCodec)

	Encode(body any) (io.Reader, error)
	Decode(r io.Reader, v any) error
}
var (
	BodyCodecFormUrlencodedAndJSON BodyCodec = &bodyCodecFormUrlencodedAndJSON{}
)
var (
	BodyCodecJSON BodyCodec = &bodyCodecJSON{}
)
var (
	BodyCodecMultipart BodyCodec = &bodyCodecMultipart{}
)

type BodyCodecDecodeWrong

type BodyCodecDecodeWrong interface {
	DecodeWrong(r io.Reader, v any) error
}

type BodyCodecOnReceive

type BodyCodecOnReceive interface {
	OnReceive(req *http.Request, resp *http.Response)
}

type BodyCodecOnSend

type BodyCodecOnSend interface {
	OnSend(req *http.Request)
}

type BodyCodecResponseIsSuccessful

type BodyCodecResponseIsSuccessful interface {
	IsSuccessful(resp *http.Response) bool
}

type BodyCodecResponseIsWrong

type BodyCodecResponseIsWrong interface {
	IsWrong(resp *http.Response) bool
}

type BodyHeaderAccept

type BodyHeaderAccept interface {
	Accept() string
}

type BodyHeaderAcceptEncoding

type BodyHeaderAcceptEncoding interface {
	AcceptEncoding() string
}

type BodyHeaderContentEncoding

type BodyHeaderContentEncoding interface {
	ContentEncoding() string
}

type BodyHeaderContentLength

type BodyHeaderContentLength interface {
	ContentLength() int
}

type BodyHeaderContentType

type BodyHeaderContentType interface {
	ContentType() string
}

type XClient

type XClient struct {
	// contains filtered or unexported fields
}

func NewClient

func NewClient() *XClient

func (*XClient) AddHeader

func (xc *XClient) AddHeader(key, value string) *XClient

func (*XClient) BaseURL

func (xc *XClient) BaseURL(baseURL string) *XClient

func (*XClient) Clone

func (xc *XClient) Clone() *XClient

func (*XClient) Do

func (xc *XClient) Do(successV, wrongV any, xReq *XRequestBuilder) (resp *http.Response, respBody []byte, err error)
Example
type Response struct {
	Args struct {
		Hello string `json:"hello"`
	} `json:"args"`
}

cli := NewClient()

var respHello Response
_, respBody, err := cli.Do(&respHello, nil,
	NewGet().
		Path("https://httpbin.org/get").
		SetQuery("hello", "world"),
)
if err != nil {
	log.Fatalf("%s\n%s", err, respBody)
}

fmt.Println(respHello.Args.Hello)
Output:

world
Example (Download)
cli := NewClient()

_, resp, cancel, err := cli.DoWithRaw(
	NewGet().
		Path("https://raw.githubusercontent.com/electricbubble/xhttpclient/main/LICENSE"),
)
if err != nil {
	log.Fatal(err)
}
defer cancel()

var buf bytes.Buffer
if _, err = io.Copy(&buf, resp.Body); err != nil {
	log.Fatal(err)
}

license, _, _ := strings.Cut(buf.String(), "\n")
fmt.Println(license)
Output:

MIT License
Example (Unexpected_error)
cli := NewClient()

var respEmpty any
_, _, err := cli.Do(&respEmpty, nil,
	NewGet().
		Path("https://httpbin.org/status/", "404"),
)
fmt.Println(err)
Output:

unexpected error: URL: https://httpbin.org/status/404 (404 Not Found)
Example (Upload)
tmpTestdata := filepath.Join(os.TempDir(), "testdata.json")
if err := os.WriteFile(tmpTestdata, []byte(`{"x","go"}`), 0644); err != nil {
	log.Fatalln(err)
}
defer os.Remove(tmpTestdata)

type Response struct {
	Files struct {
		Testfile string `json:"testfile"`
	} `json:"files"`
	Form struct {
		Hello string `json:"hello"`
	} `json:"form"`
}

cli := NewClient().BaseURL("https://httpbin.org")

var resp Response
_, respBody, err := cli.DoOnceWithBodyCodec(BodyCodecMultipart, &resp, nil,
	NewPost().
		Path("/post").
		Body(
			NewMultipartWriter().
				WriteWithFieldValue("hello", "world").
				WriteWithFile("testfile", tmpTestdata),
		),
)
if err != nil {
	log.Fatalf("%s\n%s", err, respBody)
}

fmt.Println(resp.Form.Hello)
fmt.Println(resp.Files.Testfile)
Output:

world
{"x","go"}
Example (Wrong_resp)
type GitHubError struct {
	Message          string `json:"message"`
	DocumentationUrl string `json:"documentation_url"`
}

cli := NewClient().BaseURL("https://api.github.com")

var (
	respEmpty any
	respWrong GitHubError
)
_, respBody, err := cli.Do(&respEmpty, &respWrong,
	NewGet().
		Path("/markdown"),
)
if err != nil {
	log.Fatalf("%s\n%s", err, respBody)
}
fmt.Println(respWrong.Message)
fmt.Println(respWrong.DocumentationUrl)
fmt.Println(string(respBody))
Output:

Not Found
https://docs.github.com/rest
{"message":"Not Found","documentation_url":"https://docs.github.com/rest"}

func (*XClient) DoOnceWithBodyCodec

func (xc *XClient) DoOnceWithBodyCodec(bodyCodec BodyCodec, successV, wrongV any, xReq *XRequestBuilder) (resp *http.Response, respBody []byte, err error)

func (*XClient) DoWithRaw

func (xc *XClient) DoWithRaw(xReq *XRequestBuilder) (req *http.Request, resp *http.Response, cancel context.CancelFunc, err error)

func (*XClient) Header

func (xc *XClient) Header(header http.Header) *XClient

func (*XClient) SetBasicAuth

func (xc *XClient) SetBasicAuth(username, password string) *XClient

func (*XClient) SetHeader

func (xc *XClient) SetHeader(key, value string) *XClient

func (*XClient) WithBodyCodec

func (xc *XClient) WithBodyCodec(bodyCodec BodyCodec) *XClient

func (*XClient) WithBodyCodecJSON

func (xc *XClient) WithBodyCodecJSON() *XClient

func (*XClient) WithClient

func (xc *XClient) WithClient(c *http.Client) *XClient

func (*XClient) WithRequestTimeout added in v0.3.0

func (xc *XClient) WithRequestTimeout(d time.Duration) *XClient

type XMultipartWriter

type XMultipartWriter struct {
	// contains filtered or unexported fields
}

func NewMultipartWriter

func NewMultipartWriter() *XMultipartWriter

func (*XMultipartWriter) Boundary

func (xmw *XMultipartWriter) Boundary() string

func (*XMultipartWriter) FormDataContentType

func (xmw *XMultipartWriter) FormDataContentType() string

FormDataContentType returns the Content-Type for an HTTP multipart/form-data with this Writer's Boundary.

Copied from mime/multipart/writer.go

func (*XMultipartWriter) SetBoundary

func (xmw *XMultipartWriter) SetBoundary(boundary string) *XMultipartWriter

func (*XMultipartWriter) WriteWithField

func (xmw *XMultipartWriter) WriteWithField(fieldname string, r io.Reader) *XMultipartWriter

func (*XMultipartWriter) WriteWithFieldValue

func (xmw *XMultipartWriter) WriteWithFieldValue(fieldname, value string) *XMultipartWriter

func (*XMultipartWriter) WriteWithFile

func (xmw *XMultipartWriter) WriteWithFile(fieldname, filename string) *XMultipartWriter

func (*XMultipartWriter) WriteWithHeader

func (xmw *XMultipartWriter) WriteWithHeader(header textproto.MIMEHeader, r io.Reader) *XMultipartWriter

type XRequestBuilder

type XRequestBuilder struct {
	// contains filtered or unexported fields
}

func NewConnect

func NewConnect() *XRequestBuilder

func NewDelete

func NewDelete() *XRequestBuilder

func NewGet

func NewGet() *XRequestBuilder

func NewHead

func NewHead() *XRequestBuilder

func NewOptions

func NewOptions() *XRequestBuilder

func NewPatch

func NewPatch() *XRequestBuilder

func NewPost

func NewPost() *XRequestBuilder

func NewPut

func NewPut() *XRequestBuilder

func NewTrace

func NewTrace() *XRequestBuilder

func (*XRequestBuilder) AddHeader

func (xr *XRequestBuilder) AddHeader(key, value string) *XRequestBuilder

func (*XRequestBuilder) AddQuery

func (xr *XRequestBuilder) AddQuery(key, value string) *XRequestBuilder

func (*XRequestBuilder) Body

func (xr *XRequestBuilder) Body(body any) *XRequestBuilder

func (*XRequestBuilder) Header

func (xr *XRequestBuilder) Header(header http.Header) *XRequestBuilder

func (*XRequestBuilder) Path

func (xr *XRequestBuilder) Path(elements ...string) *XRequestBuilder

func (*XRequestBuilder) Query

func (xr *XRequestBuilder) Query(query urlpkg.Values) *XRequestBuilder

func (*XRequestBuilder) SetBasicAuth

func (xr *XRequestBuilder) SetBasicAuth(username, password string) *XRequestBuilder

func (*XRequestBuilder) SetHeader

func (xr *XRequestBuilder) SetHeader(key, value string) *XRequestBuilder

func (*XRequestBuilder) SetQuery

func (xr *XRequestBuilder) SetQuery(key, value string) *XRequestBuilder

func (*XRequestBuilder) WithContext

func (xr *XRequestBuilder) WithContext(ctx context.Context) *XRequestBuilder

func (*XRequestBuilder) WithTimeout added in v0.3.0

func (xr *XRequestBuilder) WithTimeout(d time.Duration) *XRequestBuilder

Jump to

Keyboard shortcuts

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