# 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)
}
}