client

package module
v0.0.0-...-26bf477 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2022 License: MIT Imports: 14 Imported by: 0

README

Go Client

This library is a go client library and underneath it uses go's net/http library. When we send HTTP requests via using the net/http library. We usually have duplications. We need to create our own retry logics and rate limiting mechanisms. This library is a lightweight helper library to help you use client functionality very clean and good.

Advantages

  • It allows you to write very clean client codes.
  • You don't need to worry about retrying mechanisms, retrying intervals...
  • Highly consistent when you have a failure and if your retry count is finally reached the end library provides you a dead-letter mechanism. So whenever you reached retry limit it will use the interface to send this letter to some database, message queue, file etc.
  • Provides hands-on rate limiting for you. You only need to worry about the configurations

Getting Started

Directly use the client struct that library provides you.

package main

import (
	"context"

	"github.com/bilginyuksel/client"
	"github.com/yudai/pp"
)

func main() {
    ctx := context.Background()
    c := client.New(client.WithHost("https://api.sampleapis.com"))
    req := c.NewRequest(ctx).Path("/coffee/hot")

    var hotCoffees []Coffee
    if err := c.GetJSON(ctx, req, &hotCoffees); err != nil {
        panic(err)
    }
    pp.Println(hotCoffees)

    var icedCoffees []Coffee
    if err := c.GetJSON(ctx, req, &icedCoffees); err != nil {
        panic(err)
    }
    pp.Println(icedCoffees)
}

type Coffee struct {
	ID          int64    `json:"id"`
	Title       string   `json:"title"`
	Description string   `json:"description"`
	Ingredients []string `json:"ingredients"`
}

Create a new client struct and embed the library client. Use your new struct with meaningful methods.

package main

import (
	"context"

	"github.com/bilginyuksel/client"
	"github.com/yudai/pp"
)

func main() {
    coffeeClient := NewCoffeeClient(client.WithHost("https://api.sampelapis.com"))
    hotCoffees, err := coffeeClient.GetHotCoffees(context.Background())
    if err != nil {
        panic(err)
    }
    pp.Println(hotCoffees)

    icedCoffees, err := coffeeClient.GetIcedCoffees(context.Background())
    if err != nil {
        panic(err)
    }
    pp.Println(icedCoffees)
}

type Coffee struct {
	ID          int64    `json:"id"`
	Title       string   `json:"title"`
	Description string   `json:"description"`
	Ingredients []string `json:"ingredients"`
}

// Embed the client that library provides you into the CoffeeClient
type CoffeeClient struct {
	*client.Client
}

func NewCoffeeClient(options client.Option) *MockClient {
	return &CoffeeClient{
		Client: client.New(options),
	}
}

func (c *CoffeeClient) GetHotCoffees(ctx context.Context) ([]Coffee, error) {
    var coffees []Coffee
    req := c.NewRequest(ctx).Path("/coffee/hot")
    return coffees, c.GetJSON(ctx, req, &coffees)
}

func (c *CoffeeClient) GetIcedCoffees(ctx context.Context) ([]Coffee, error) {
    var coffees []Coffee
    req := c.NewRequest(ctx).Path("/coffee/iced")
    return coffees, c.GetJSON(ctx, req, &coffees)
}

Documentation

Overview

Package client is a generated GoMock package.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

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

Client is a wrapper for http.Client Has easy to use methods to send http requests Provides a deadletter to save requests that could not be sent and a rate limiter to limit the number of requests per second

func New

func New(opts ...Option) *Client

New create a client with multiple options or get the default client without providing any options

func (*Client) Do

func (c *Client) Do(ctx context.Context, request *Request) (res *http.Response, err error)

Do Execute an http request with the given request

func (*Client) GetJSON

func (c *Client) GetJSON(ctx context.Context, request *Request, response interface{}) error

GetJSON execute a get method with the given request and then unmarshal the json response body

func (*Client) GetXML

func (c *Client) GetXML(ctx context.Context, request *Request, response interface{}) error

GetXML execute a get method with the given request and then unmarshal the xml response body

func (*Client) NewRequest

func (c *Client) NewRequest() *Request

NewRequest creates a new request with the given context

func (*Client) Parse

func (c *Client) Parse(ctx context.Context, request *Request, response interface{}, parser func(bodyBytes []byte, response interface{}) error) error

Parse send a request with the given request properties Read the body with the given parser function

func (*Client) ParseJSON

func (c *Client) ParseJSON(ctx context.Context, request *Request, response interface{}) error

ParseJSON send a request with given request properties Read the body and run json unmarshaler to fill the given response

func (*Client) ParseXML

func (c *Client) ParseXML(ctx context.Context, request *Request, response interface{}) error

ParseXML send a request with the given request properties Read the body and run xml unmarshaler to fill the given response

func (*Client) PostJSON

func (c *Client) PostJSON(ctx context.Context, request *Request, response interface{}) error

PostJSON execute a post method with the given request and then unmarshal the json response body

func (*Client) PutJSON

func (c *Client) PutJSON(ctx context.Context, request *Request, response interface{}) error

PutJSON execute a put method with the given request and then unmarshal the json response body

type DeadLetter

type DeadLetter interface {
	Save(letter *Letter) error
}

DeadLetter save request to somewhere to ensure consistency

type Letter

type Letter struct {
	Method  string              `json:"method"`
	URL     string              `json:"url"`
	Body    []byte              `json:"body"`
	Headers map[string][]string `json:"headers"`
}

Letter is a letter that is sent to deadletter

type MockDeadLetter

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

MockDeadLetter is a mock of DeadLetter interface.

func NewMockDeadLetter

func NewMockDeadLetter(ctrl *gomock.Controller) *MockDeadLetter

NewMockDeadLetter creates a new mock instance.

func (*MockDeadLetter) EXPECT

EXPECT returns an object that allows the caller to indicate expected use.

func (*MockDeadLetter) Save

func (m *MockDeadLetter) Save(letter *Letter) error

Save mocks base method.

type MockDeadLetterMockRecorder

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

MockDeadLetterMockRecorder is the mock recorder for MockDeadLetter.

func (*MockDeadLetterMockRecorder) Save

func (mr *MockDeadLetterMockRecorder) Save(letter interface{}) *gomock.Call

Save indicates an expected call of Save.

type Option

type Option func(c *Client)

Option is a function that configures a client

func WithDeadLetter

func WithDeadLetter(deadLetter DeadLetter) Option

WithDeadLetter create client option function with deadletter properties

func WithHTTPClient

func WithHTTPClient(httpClient *http.Client) Option

WithHTTPClient create client option function with http client

func WithHost

func WithHost(host string) Option

WithHost create client option function with host

func WithRateLimit

func WithRateLimit(interval time.Duration, requests int) Option

WithRateLimit create client option function with http client

func WithRetry

func WithRetry(maxRetry int, retryInterval time.Duration) Option

WithRetry create client option function with retrying properties

type Request

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

Request use this request struct to send http requests

func (*Request) AddHeader

func (r *Request) AddHeader(key string, value ...string) *Request

AddHeader if given header key currently has a value it will add another one if the key does not exists it will add a new key value

func (*Request) AddQuery

func (r *Request) AddQuery(key string, value ...string) *Request

AddQuery if given query key currently has a value it will add another one if the key does not exists it will add a new key value

func (*Request) Body

func (r *Request) Body(body []byte) *Request

Body set the body of the request

func (*Request) Host

func (r *Request) Host(host string) *Request

Host set the host

func (*Request) Method

func (r *Request) Method(method string) *Request

Method set a method to given request

func (*Request) Path

func (r *Request) Path(path string, opts ...interface{}) *Request

Path sets the given request path to request. To avoid fmt.Sprintf call while calling the function you can directly give the formatted string as path variable and options after that function will automatically insert the paremeters

func (*Request) SetBasicAuth

func (r *Request) SetBasicAuth(username, password string) *Request

SetBasicAuth sets the basic auth header

func (*Request) SetHeader

func (r *Request) SetHeader(key string, value ...string) *Request

SetHeader if given header key currently has a value it will replace it with the given value if the key does not exists it will add a new key value

func (*Request) SetQuery

func (r *Request) SetQuery(key string, value ...string) *Request

SetQuery if given query key currently has a value it will replace it with the given value if the key does not exists it will add a new key value

func (*Request) URL

func (r *Request) URL() (string, error)

URL returns the url of the request

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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