requests

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Feb 8, 2023 License: MIT Imports: 19 Imported by: 0

README

requests

http method

  • GET
  • POST
  • PUT
  • PATCH
  • DELETE
  • HEAD
  • CONNECT
  • OPTIONS
  • TRACE

Feature

  • Middleware
  • Retry

Example

package main

import (
	"bytes"
	"context"
	"fmt"
	"net/http"

	"github.com/lujin123/requests"
)

type User struct {
	Id   int    `form:"id" xml:"id"`
	Name string `form:"name" xml:"name"`
}

func main() {
	endpoint := "https://www.baidu.com/"
	//直接请求
	_, _ = requests.Get(context.Background(), endpoint)
	//使用字符串map作为请求参数
	_, _ = requests.Get(context.Background(), endpoint, requests.WithParam(map[string]string{
		"id":  "1",
		"key": "abc",
	}))
	//使用结构体作为请求参数
	//参数key使用form的tag,如果不指定form直接使用field name
	query := User{
		Id:   1,
		Name: "hello",
	}
	_, _ = requests.Get(context.Background(), endpoint, requests.WithQuery(&query))
	//空body的POST请求
	_, _ = requests.Post(context.Background(), endpoint)

	//使用json格式数据作为请求body
	jsonData := User{
		Id:   2,
		Name: "json",
	}
	_, _ = requests.Post(context.Background(), endpoint, requests.WithJSON(&jsonData))

	//使用xml格式数据作为请求body
	xmlData := User{
		Id:   3,
		Name: "xml",
	}
	_, _ = requests.Post(context.Background(), endpoint, requests.WithXML(&xmlData))

	//设置请求头
	headers := map[string]string{
		"Content-Type":  "application/xml",
		"custom-header": "custom",
	}
	_, _ = requests.Post(context.Background(), endpoint, requests.WithXML(xmlData), requests.WithHeaders(headers))

	//自定义本地请求的client
	client := http.Client{
		Transport:     nil,
		CheckRedirect: nil,
		Jar:           nil,
		Timeout:       0,
	}
	_, _ = requests.Post(context.Background(), endpoint, requests.WithClient(&client))

	//自定义一个请求client
	newRequests := requests.New(requests.WithClient(&client))
	_, _ = newRequests.Post(context.Background(), endpoint)

	//处理请求结果
	resp, err := requests.Get(context.Background(), endpoint)
	if err != nil {
		return
	}
	//返回值只能读取一次
	//返回内容字符串
	fmt.Println(resp.Text())
	//json
	var jsonResp interface{}
	_ = resp.JSON(&jsonResp)
	fmt.Println(jsonResp)
	//xml
	var xmlResp interface{}
	_ = resp.XML(&xmlResp)
	fmt.Println(xmlResp)
	//读取字节流,resp.Raw()返回的是一个channel
	var buffs bytes.Buffer
	for buf := range resp.Raw() {
		buffs.Write(buf)
	}
	fmt.Println(buffs.Bytes())
}

middleware

package main

import (
	"bytes"
	"context"
	"fmt"
	"net/http"

	"github.com/lujin123/requests"
)

func main() {
	endpoint := "https://www.baidu.com/"
	var m1 = func() requests.Middleware {
		return func(next requests.Handler) requests.Handler {
			return func(client *http.Client, request *http.Request) (response *http.Response, err error) {
				ctx := context.WithValue(request.Context(), "token", "1234")
				request = request.Clone(ctx)
				fmt.Printf("method=%s, url=%s, body=%s\n", request.Method, request.URL, request.Body)
				resp, err := next(client, request)
				if err != nil {
					return resp, err
				}
				ctx = resp.Request.Context()
				fmt.Printf("token=%s\n", ctx.Value("token"))
				return resp, err
			}
		}
	}
	var m2 = func() requests.Middleware {
		return func(next requests.Handler) requests.Handler {
			return func(client *http.Client, request *http.Request) (response *http.Response, err error) {
				fmt.Println("m2 before...")
				resp, err := next(client, request)
				fmt.Println("m2 after")
				return resp, err
			}
		}
	}
	resp, err := requests.Get(context.Background(), endpoint,
		requests.WithParam(map[string]string{"id": "1"}),
		requests.WithDebug(true),
		requests.WithRetry(),
		requests.WithMiddleware(m1(), m2()))
	if err != nil {
		return
	}
	fmt.Println(resp.Text())
}

retry

package main

import (
	"bytes"
	"context"
	"fmt"
	"net/http"

	"github.com/lujin123/requests"
)

func main() {
	endpoint := "https://www.baidu.com/"
	resp, err := requests.Get(context.Background(), endpoint, requests.WithRetry())
	if err != nil {
		return
	}
	fmt.Println(resp.Text())
}

debug

开启debug的时候会自动加入请求日志

package main

import (
	"bytes"
	"context"
	"fmt"
	"log"
	"net/http"

	"github.com/lujin123/requests"
)

func main() {
	endpoint := "http://localhost:8080/v1/task/status"
	r, err := requests.Get(context.Background(),
		endpoint,
		requests.WithDebug(true),
		requests.WithParam(map[string]string{
			"event": "event",
		}),
		requests.WithHeaders(map[string]string{
			"Authorization": "Bearer abc",
		}),
	)
	if err != nil {
		log.Fatal(err)
	}
	var result interface{}
	if err := r.JSON(&result); err != nil {
		log.Fatal(err)
	}
}

File upload

package main

import (
	"bytes"
	"context"
	"fmt"
	"log"
	"net/http"

	"github.com/lujin123/requests"
)

func main() {
	endpoint := "http://localhost:8080/v1/task/status"
	_, err := requests.Post(context.Background(),
		endpoint,
		requests.WithDebug(true),
		requests.WithFile(&requests.File{
			Path: "path to file",
			Name: "field name",
			Extras: map[string]string{
				"author":      "test",
				"title":       "My Document",
				"description": "A document with all the Go programming language secrets",
			},
		}),
	)
	if err != nil {
		log.Fatal(err)
	}
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	Request *http.Request
	// contains filtered or unexported fields
}

func New

func New(opts ...DialOption) *Client

init request client eg: New(WithClient(http.DefaultClient))

func Session

func Session(opts ...DialOption) *Client

session

func (*Client) Connect

func (req *Client) Connect(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func (*Client) Delete

func (req *Client) Delete(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func (*Client) Do

func (req *Client) Do(ctx context.Context, method, url string, opts ...DialOption) (*Response, error)

func (*Client) Get

func (req *Client) Get(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func (*Client) Head

func (req *Client) Head(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func (*Client) Options

func (req *Client) Options(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func (*Client) Patch

func (req *Client) Patch(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func (*Client) Post

func (req *Client) Post(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func (*Client) Put

func (req *Client) Put(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func (*Client) Trace

func (req *Client) Trace(ctx context.Context, url string, opts ...DialOption) (*Response, error)

type DialOption

type DialOption func(opts *dialOptions)

func WithBody

func WithBody(body io.Reader) DialOption

直接设置一个请求body

func WithClient

func WithClient(clients ...*http.Client) DialOption

设置请求client 一般在创建一个requests的时候才使用 中间件中也可以直接替换一个client

func WithCookies

func WithCookies(cookies ...*http.Cookie) DialOption

设置cookie

func WithDebug

func WithDebug(debug bool) DialOption

是否开启debug模式 可以在初始化的时候统一设置,也可以给每个请求单独设置

func WithFile

func WithFile(file *File) DialOption

上传文件

func WithForm

func WithForm(form Value) DialOption

func WithHeaders

func WithHeaders(headers Value) DialOption

添加请求头 这里设置的headers会

func WithJSON

func WithJSON(data interface{}) DialOption

func WithMiddleware

func WithMiddleware(middles ...Middleware) DialOption

添加中间件 中间件中可以获取到client,Request, Response对象,所以可以对请求做很多的操作

func WithParam

func WithParam(query Value) DialOption

func WithQuery

func WithQuery(i interface{}) DialOption

直接传递一个结构体指针作为query参数 注意: 1. 支持map、struct,其他的类型会直接panic,struct使用`form`指定字段名称,未指定的使用默认值 2. 支持匿名嵌套,但不支持命名嵌套,内容不会解析,直接变成一个字符串

func WithRetry

func WithRetry(retries ...Retry) DialOption

设置请求重试 自带一个默认的重试实现,可以自定义实现

func WithSession

func WithSession(session bool) DialOption

是否清空cookies 如果设置成true,后续的请求都会带上前面请求返回的cookie,所以不要随便设置,只有在确实需要的时候再设置

func WithTrace

func WithTrace(trace *httptrace.ClientTrace) DialOption

添加请求追踪 trace需要自定义

func WithXML

func WithXML(data interface{}) DialOption

type File

type File struct {
	Path   string
	Name   string
	Extras Value
}

type Handler

type Handler func(client *http.Client, request *http.Request) (response *http.Response, err error)

type Http

type Http interface {
	Get(ctx context.Context, url string, opts ...DialOption) (*Response, error)
	Post(ctx context.Context, url string, opts ...DialOption) (*Response, error)
	Put(ctx context.Context, url string, opts ...DialOption) (*Response, error)
	Patch(ctx context.Context, url string, opts ...DialOption) (*Response, error)
	Delete(ctx context.Context, url string, opts ...DialOption) (*Response, error)
	Head(ctx context.Context, url string, opts ...DialOption) (*Response, error)
	Connect(ctx context.Context, url string, opts ...DialOption) (*Response, error)
	Options(ctx context.Context, url string, opts ...DialOption) (*Response, error)
	Trace(ctx context.Context, url string, opts ...DialOption) (*Response, error)
	Do(ctx context.Context, method, url string, opts ...DialOption) (*Response, error)
}

type Middleware

type Middleware func(next Handler) Handler

func Chain

func Chain(middles ...Middleware) Middleware

compress middleware

type Response

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

func Connect

func Connect(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func Delete

func Delete(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func Do

func Do(ctx context.Context, method, url string, opts ...DialOption) (*Response, error)

func Get

func Get(ctx context.Context, url string, opts ...DialOption) (*Response, error)
func Head(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func Options

func Options(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func Patch

func Patch(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func Post

func Post(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func Put

func Put(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func Trace

func Trace(ctx context.Context, url string, opts ...DialOption) (*Response, error)

func (*Response) Close

func (r *Response) Close() error

func (*Response) Content

func (r *Response) Content() ([]byte, error)

二进制内容

func (*Response) JSON

func (r *Response) JSON(i interface{}) error

json内容

func (*Response) Raw

func (r *Response) Raw() chan []byte

读取字节流 读取完或者遇到错误,会关闭channel

func (*Response) Response

func (r *Response) Response() *http.Response

原始的Response对象

func (*Response) Text

func (r *Response) Text() (string, error)

字符串内容

func (*Response) XML

func (r *Response) XML(i interface{}) error

XML格式内容

type Retry

type Retry interface {
	MaxEntries() int
	WaitTime() time.Duration
	MaxWaitTime() time.Duration
	RetryConditions() []RetryCondition
	RetryPolicy() RetryPolicy
}

type RetryCondition

type RetryCondition func(resp *http.Response, err error) bool

type RetryPolicy

type RetryPolicy func(resp *http.Response, min, max time.Duration, attempt int) (time.Duration, error)

type Value

type Value map[string]string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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