gofast

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Apr 18, 2021 License: MIT Imports: 5 Imported by: 0

README

Gofast

Test Lint codecov Go Report Card

⚡️ Gofast is a HTTP client based on fasthttp with zero memory allocation.

Automatic struct binding let you focus on entity writing.

JSON-to-Go is very useful to generate struct.

Install

go get -u github.com/cloudingcity/gofast

Quick Start

package main

import (
	"fmt"
	"log"

	"github.com/cloudingcity/gofast"
)

type Out struct {
	Hello string `json:"hello"`
}

func main() {
	fast := gofast.New()

	var out Out
	uri := "http://echo.jsontest.com/hello/world"
	if err := fast.Get(uri, &out, nil); err != nil {
		log.Fatalln(err)
	}
	fmt.Printf("hello %v", out.Hello)
	// hello world
}

Examples

Send request with body

The default encoding is JSON with application/json header.

You can also use map to bind value, but the worse performance you will get.

type CreateToken struct {
    ID     string `json:"id"`
    Secret string `json:"secret"`
}

type Token struct {
    Token     string `json:"token"`
    ExpiredAt string `json:"expired_at"`
}

fast := gofast.New()

uri := "https://example.com/api/v1/token"
body := CreateToken{
    ID:     "my-id",
    Secret: "my-secret",
}
var token Token
if err := fast.Post(uri, &body, &token, nil); err != nil {
    log.Fatalln(err)
}
fmt.Printf("token: %v, expired_at: %v", token.Token, token.ExpiredAt)
Get with header
type User struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

fast := gofast.New()

var user User
uri := "https://example.com/api/v1/users/100"
h := gofast.Header{fasthttp.HeaderAuthorization: "Bearer My-JWT"}
if err := fast.Get(uri, &user, h); err != nil {
    log.Fatalln(err)
}
fmt.Printf("id: %v, name: %v", user.ID, user.Name)
URL encode

Post body with application/x-www-form-urlencoded header and get text.

fast := gofast.New(gofast.Config{
    RequestEncoder:  gofast.URLEncoder,
    ResponseDecoder: gofast.TextDecoder,
})

uri := "https://example.com/api/v1/token"
body := gofast.Body{
    "id":     "my-id",
    "secret": "my-secret",
}
var token string
if err := fast.Post(uri, body, &token, nil); err != nil {
    log.Fatalln(err)
}
Customize error handler

Error handler will handle non 2xx HTTP status code.

cfg := gofast.Config{
    ErrorHandler: func(resp *fasthttp.Response) error {
        return fmt.Errorf("http code = %d", resp.StatusCode())
    },
}

fast := gofast.New(cfg)
err := fast.Get(uri, nil, nil)
// http code = 400

Benchmarks

$ go test -bench=. -benchmem -benchtime=3s -run=none -cpu 4
BenchmarkPostJSON-4               1263522              2891 ns/op               0 B/op          0 allocs/op
BenchmarkPostURLEncode-4          1219441              2777 ns/op               0 B/op          0 allocs/op

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ConfigDefault = Config{
	Name:                     "gofast",
	NoDefaultUserAgentHeader: false,
	ReadTimeout:              6 * time.Second,
	WriteTimeout:             6 * time.Second,
	RequestEncoder:           JSONEncoder,
	ResponseDecoder:          JSONDecoder,
	ErrorHandler:             defaultErrorHandler,
}

ConfigDefault is the default config

View Source
var JSONDecoder = func(resp *fasthttp.Response, out interface{}) error {
	if err := json.Unmarshal(resp.Body(), out); err != nil {
		log.Printf("[gofast] response decode failed - code: %v, body: %v", resp.StatusCode(), string(resp.Body()))
		return err
	}
	return nil
}
View Source
var JSONEncoder = func(req *fasthttp.Request, in interface{}) error {
	req.Header.SetContentType("application/json")
	return json.NewEncoder(req.BodyWriter()).Encode(in)
}
View Source
var TextDecoder = func(resp *fasthttp.Response, out interface{}) error {
	s := out.(*string)
	*s = string(resp.Body())
	return nil
}
View Source
var URLEncoder = func(req *fasthttp.Request, in interface{}) error {
	args := fasthttp.AcquireArgs()
	defer fasthttp.ReleaseArgs(args)

	for k, v := range in.(Body) {
		args.Set(k, v)
	}
	if _, err := args.WriteTo(req.BodyWriter()); err != nil {
		return err
	}
	req.Header.SetContentType("application/x-www-form-urlencoded")
	return nil
}

Functions

This section is empty.

Types

type Body added in v0.3.0

type Body map[string]string

type Client

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

func New

func New(config ...Config) *Client

func (*Client) Delete

func (c *Client) Delete(uri string, in, out interface{}, header Header) error

func (*Client) Get

func (c *Client) Get(uri string, out interface{}, header Header) error

func (*Client) Patch

func (c *Client) Patch(uri string, in, out interface{}, header Header) error

func (*Client) Post

func (c *Client) Post(uri string, in, out interface{}, header Header) error

func (*Client) Put

func (c *Client) Put(uri string, in, out interface{}, header Header) error

type Config

type Config struct {
	// fasthttp client configurations
	Name                     string
	NoDefaultUserAgentHeader bool
	ReadTimeout              time.Duration
	WriteTimeout             time.Duration

	// RequestEncoder encode request before send
	RequestEncoder RequestEncoder

	// ResponseDecoder decode response after send
	ResponseDecoder ResponseDecoder

	// ErrorHandler handle the status code without 2xx
	ErrorHandler ErrorHandler
}

type ErrorHandler

type ErrorHandler func(resp *fasthttp.Response) error
type Header map[string]string

type RequestEncoder

type RequestEncoder func(req *fasthttp.Request, in interface{}) error

type ResponseDecoder

type ResponseDecoder func(resp *fasthttp.Response, out interface{}) error

Jump to

Keyboard shortcuts

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