Categorygithub.com/phuc1998/http-builder
modulepackage
0.0.0-20221103110002-ce170081b599
Repository: https://github.com/phuc1998/http-builder.git
Documentation: pkg.go.dev

# README

http-builder

Introduction:

http-builder is an enhanced http client which provides you a http client package to help your create requests easier and reusable.

Features:

  • You can customize requests with http client build in Go.

  • It supports for adding a base path for many requests in a group.

  • You also add default headers into your requests.

  • It supports tags for building request struct into request parameter types: query param, path param, form data, body and hybrid parameters.

  • Unmarshalling responses have declared struct in json or your response custom parser.

Installation

go get -u github.com/phuc1998/http-builder

Usage:

Create a simple request

All configuration is default.

func main() {
  var response interface{}

  cfg := NewConfiguration()
  apiClient := NewAPIClient(cfg)
  _, err := apiClient.Builder("/booking/detail").
    Get().                               //support Get, Post, Put, Delete (Default: Get)
    Call(context.Background(), response) //request url: http://localhost/booking/detail

  if err != nil {
    log.Fatal(err)
  }
  log.Println("Response", response)
}

Create a request with customize client config

func main() {
  var (
    response interface{}
    basePath = "http://localhost/cars/v1"
  )

  proxyURL, err := url.Parse("http://proxy.bigphuc.com")
  if err != nil {
    panic(err)
  }

  // Customize http client for a proxy transport and max connection client.
  httpClient := &http.Client{
    Transport: &http.Transport{
      Proxy:           http.ProxyURL(proxyURL),
      MaxConnsPerHost: 10,
    },
    Timeout: 60,
  }

  cfg := NewConfiguration().
    // Now you call many request start with base path: http://localhost/cars/v1
    AddBasePath(basePath).
    // APIClient now can send request through a proxy with 10 max connections per host
    AddHTTPClient(httpClient).
    // This header will be added to every requests.
    AddDefaultHeader("Age", "23")

  apiClient := NewAPIClient(cfg)
  _, err = apiClient.Builder("/booking/detail").
    Get().
    Call(context.Background(), response) //request url: http://localhost/cars/v1/booking/detail
                                          //             --header 'age="23"'

  if err != nil {
    log.Fatal(err)
  }
  log.Println("Response", response)
}

Custom response parser:

You can use create your own response struct and use the default parser or customize your own one.

type Response struct {
	StatusCode int32  `json:"statusCode"`
	Message    string `json:"message"`
}

func main() {
  var response = Response{}

  // With request response header text/plain this parser add body into Response.Message field
  customParser := func(resp interface{}, body []byte) error {
    result := resp.(*Response)
    r := string(body)
    result.Message = r
    return nil
  }

  cfg := NewConfiguration()
  apiClient := NewAPIClient(cfg)
  _, err := apiClient.Builder("/booking/detail").
    Get().
    Call(context.Background(), &response, customParser) // You can add customParser or not

  log.Println("Response", response)
  if err != nil {
    log.Fatal(err)
  }
}

Create complex request

The Content-Type header default is application/json.

Create request with header

Use SetHeader(key, value).

func() {
  var (
    response interface{}
    basePath = "http://localhost/cars/v1"
  )

  cfg := NewConfiguration().AddBasePath(basePath)
  apiClient := NewAPIClient(cfg)
  _, err := apiClient.Builder("/booking/detail").
    Get().
    SetHeader("Content-Type", "text/plaint").
    Call(context.Background(), response) //request url: http://localhost/cars/v1/booking/detail
                                          //             --header 'content-type="text/plaint"'

  log.Println("Response", response)
  if err != nil {
    log.Fatal(err)
  }
}

Use BuildHeader(object interface{}) to build header from struct.

type Request struct {
  // tag is one of followings:
  // ""
  // "name"
  // "name,opt"
  // "name,opt,opt2"
  // ",opt"
  ID string `http:"id,header"`
}

func () {
  var (
    response interface{}
    basePath = "http://localhost/cars/v1"
    req = &Request{
      ID: "123456",
    }
  )

  cfg := NewConfiguration().AddBasePath(basePath)
  apiClient := NewAPIClient(cfg)
  _, err := apiClient.Builder("/booking/detail").
    Get().
    BuildHeader(req).
    Call(context.Background(), response) //request url: http://localhost/cars/v1/booking/detail

  log.Println("Response", response)
  if err != nil {
    log.Fatal(err)
  }
}

Create request with query param

Use SetQuery(key, value).

func() {
  var (
    response interface{}
    basePath = "http://localhost/cars/v1"
  )

  cfg := NewConfiguration().AddBasePath(basePath)
  apiClient := NewAPIClient(cfg)
  _, err := apiClient.Builder("/booking/detail").
    Get().
    SetQuery("id", "123456").
    Call(context.Background(), response) //request url: http://localhost/cars/v1/booking/detail?id=123456

  log.Println("Response", response)
  if err != nil {
    log.Fatal(err)
  }
}

Use BuildQuery(object) to build query param from struct.

type Request struct {
  // tag is one of followings:
  // ""
  // "name"
  // "name,opt"
  // "name,opt,opt2"
  // ",opt"
  ID string `http:"id,query"`
}

func () {
  var (
    response interface{}
    basePath = "http://localhost/cars/v1"
    req = &Request{
      ID: "123456",
    }
  )

  cfg := NewConfiguration().AddBasePath(basePath)
  apiClient := NewAPIClient(cfg)
  _, err := apiClient.Builder("/booking/detail").
    Get().
    BuildQuery(req).
    Call(context.Background(), response) //request url: http://localhost/cars/v1/booking/detail?id=123456

  log.Println("Response", response)
  if err != nil {
    log.Fatal(err)
  }
}

Create request with path param

Use SetPath(key, value).

func() {
  var (
    response interface{}
    basePath = "http://localhost/cars/v1"
  )

  cfg := NewConfiguration().AddBasePath(basePath)
  apiClient := NewAPIClient(cfg)
  _, err := apiClient.Builder("/booking/detail/:id").
    Get().
    SetPath("id", "123456").
    Call(context.Background(), response) //request url: http://localhost/cars/v1/booking/detail/123456

  log.Println("Response", response)
  if err != nil {
    log.Fatal(err)
  }
}

Use BuildPath(object) to build path param from struct.

type Request struct {
  // tag is one of followings:
  // ""
  // "name"
  // "name,opt"
  // "name,opt,opt2"
  // ",opt"
  ID string `http:"id,path"`
}

func () {
  var (
    response interface{}
    basePath = "http://localhost/cars/v1"
    req = &Request{
      ID: "123456",
    }
  )

  cfg := NewConfiguration().AddBasePath(basePath)
  apiClient := NewAPIClient(cfg)
  _, err := apiClient.Builder("/booking/detail/:id").
    Get().
    BuildPath(req).
    Call(context.Background(), response) //request url: http://localhost/cars/v1/booking/detail/123456

  log.Println("Response", response)
  if err != nil {
    log.Fatal(err)
  }
}

Create request with form data

Use SetFormParam(key, value).

If you want ContentType: "multipart/form-data" use UseMultipartFormData(). Moreover, if you want "application/x-www-form-urlencoded" use UseXFormURLEncoded() or SetContentType(contentType) before Call function.

func() {
  var (
    response interface{}
    basePath = "http://localhost/cars/v1"
  )

  cfg := NewConfiguration().AddBasePath(basePath)
  apiClient := NewAPIClient(cfg)
  _, err := apiClient.Builder("/booking/detail").
    Post().
    SetFormParam("id", "123456").
    UseMultipartFormData().
    Call(context.Background(), response) //request url: http://localhost/cars/v1/booking/detail
                                          //             --form 'id="123456"'
  log.Println("Response", response)
  if err != nil {
    log.Fatal(err)
  }
}

Use BuildForm(object) to build form param from struct.

type Request struct {
  // tag is one of followings:
  // ""
  // "name"
  // "name,opt"
  // "name,opt,opt2"
  // ",opt"
  ID string `http:"id,form"`
}

func () {
  var (
    response interface{}
    basePath = "http://localhost/cars/v1"
    req = &Request{
      ID: "123456",
    }
  )

  cfg := NewConfiguration().AddBasePath(basePath)
  apiClient := NewAPIClient(cfg)
  _, err := apiClient.Builder("/booking/detail").
    Post().
    BuildForm(req).
    UseMultipartFormData().
    Call(context.Background(), response) //request url: http://localhost/cars/v1/booking/detail
                                          //             --form 'id="123456"'
  log.Println("Response", response)
  if err != nil {
    log.Fatal(err)
  }
}

Create request with body data

Use SetBody(body). It does not have BuildBody function.

type RequestBody struct {
  ID string `json:"id"`
}

func () {
  var (
    response interface{}
    basePath = "http://localhost/cars/v1"
    req := &RequestBody{
      ID: "123456",
    }
  )

  cfg := NewConfiguration().AddBasePath(basePath)
  apiClient := NewAPIClient(cfg)
  _, err := apiClient.Builder("/booking/detail").
    Post().
    Setbody(body).
    Call(context.Background(), response) //request url: http://localhost/cars/v1/booking/detail

  log.Println("Response", response)
  if err != nil {
    log.Fatal(err)
  }
}

Create hybrid request

Use BuildRequest(object) to build hybrid param from struct, but it not support for build body. You can use SetBody instead.

type Request struct {
  Muid string    `http:"muid,header"`
  KeyWord string `http:"keyword,query"`
}

func () {
  var (
    response interface{}
    basePath = "http://localhost/cars/v1"
    req = &Request{
      Muid: "abc",
      Keyword: "cba",
    }
  )

  cfg := NewConfiguration().AddBasePath(basePath)
  apiClient := NewAPIClient(cfg)
  _, err := apiClient.Builder("/booking/detail").
    Post().
    BuildRequest(req).
    Call(context.Background(), response) //request url: http://localhost/cars/v1/booking/detail?keyword=cba

  log.Println("Response", response)
  if err != nil {
    log.Fatal(err)
  }
}

# Packages

Package structs contains various utilities functions to work with structs.

# Functions

CacheExpires helper function to determine remaining time before repeating a request.
NewAPIClient creates a new API client.
NewConfiguration returns a new Configuration object.

# Variables

APIKeyHeader takes an APIKey as authentication for the request.
No description provided by the author
BasicAuthHeader takes BasicAuth as authentication for the request.
BearerHeader takes a string Bearer á authentication for the request.
ContextAccessToken takes a string oauth2 access token as authentication for the request.
ContextAPIKey takes an APIKey as authentication for the request.
ContextBasicAuth takes BasicAuth as authentication for the request.
ContextOAuth2 takes an oauth2.TokenSource as authentication for the request.

# Structs

APIClient manages communication with the ANVUI API API v1.0.0 In most cases there should be only one, shared, APIClient.
APIKey provides API key based authentication to a request passed via context using ContextAPIKey.
BasicAuth provides basic http authentication to a request passed via context using ContextBasicAuth.
Configuration stores the configuration of the API client.
GenericOpenAPIError Provides access to the body, error and model on returned errors.
ServerConfiguration stores the information about a server.
ServerVariable stores the information about a server variable.

# Type aliases

ParserCustomHandle custom parser.