Documentation ¶
Overview ¶
Package rest is an extremely simple to use, lightweight, yet powerful REST Client.
Motivation ¶
The Go http standard library is a great library, but it might sometimes be a bit too low level to use, and it doesn't offer features like fork-join requests for better performance, response caching based on headers, and the possibility to mockup responses.
Features and Roadmap ¶
v0.1
- GET, POST, PUT, PATCH, DELETE, HEAD & OPTIONS HTTP verbs
- Dead simple, synchronous requests
- Automatic caching of transport object and hosts connections
- Response Caching, based on response headers (cache-control, last-modified, etag, expires)
- Local caching strategies: TTL, LRU & Max Byte Size.
- Mockups!
- Fork-Join request pattern, for sending many requests concurrently, getting better client perfomance.
- Async request pattern.
- Request Body can be `string`, `[]byte`, `struct` & `map`
- Automatic marshal and unmarshal for `JSON` and `XML` Content-Type. Default JSON.
- Full access to http.Response object.
v0.2
- Retries
- BasicAuth
- UserAgent
v0.3
- Connection usage metrics
- Response Time metrics
- Brotli Content-Encoding Responses support - http://google-opensource.blogspot.com.ar/2015/09/introducing-brotli-new-compression.html
v0.4
- Custom Root Certificates and Client Certificates
- Testing +95%
v0.5
- Plugable external caches like Memcached
Caching ¶
Caching is done by two strategies working together: Time To Live (TTL) and Least Recently Used (LRU). Objects are inserted in the cache based on Response Headers. You can establish a maximum Memory Size for the cache and objects are flushed based on time expiration (TTL) or by hitting the maximum memory limit. In the last case, least accessed objects will be removed first.
Examples ¶
Installation
go get github.com/go-loco/restful/rest
Importing
import "github.com/go-loco/restful/rest"
Simple GET
resp := rest.Get("https://api.restfulsite.com/resource")
Simple POST
// Using a `string` as body resp := rest.Post("https://api.restfulsite.com/resource", "Body")
Simple POST, with Struct Body
type User struct { Id int `json:"id"` Name string `json:"name"` } body := new(User) body.Id = 1 body.Name = "Hernan" // body will be marshall as JSON resp := rest.Post("https://api.restfulsite.com/resource/1", body) fmt.Println(resp)
Fork Join ¶
ForkJoin let you **fork** requests, and **wait** until all of them have return.
Concurrent has methods for Get, Post, Put, Patch, Delete, Head & Options, with the almost the same API as the synchronous methods. The difference is that these methods return a FutureResponse, which holds a pointer to Response. Response inside FutureResponse is nil until request has finished.
var f [3]*rest.FutureResponse // ForkJoin will send all requests concurrently // and will wait until all requests have their correspondent responses rest.ForkJoin(func(c *rest.Concurrent) { f[0] = c.Get("https://api.restfulsite.com/resource/1") f[1] = c.Get("https://api.restfulsite.com/resource/2") f[2] = c.Get("https://api.restfulsite.com/resource/3") }) for i := range f { if f[i].Response().StatusCode == http.StatusOK { fmt.Println(f[i].Response()) } }
Async ¶
Async let you make Restful requests in an **asynchronous** way, without blocking the go routine calling the Async function.
Whenever the Response is ready, the **f** function will be called back.
// This won't be blocked. rest.AsyncGet("https://api.restfulsite.com/user", func(r *rest.Response) { if r.StatusCode == http.StatusOK { fmt.Println(r) } }) // This will be printed first. fmt.Println("print first")
Defaults * Headers: keep-alive, Cache-Control: no-cache * Timeout: 2 seconds * ContentType: JSON (for body requests in POST, PUT and PATCH) * Cache: enable * Cache Size: 1GB * Idle Connections Per Host: 2 (the default of http.net package) * HTTP/2: automatic with Go 1.6 * Gzip: automatic support for gzip responses
RequestBuilder ¶
RequestBuilder gives you the power to go beyond defaults. It is possible to set up headers, timeout, baseURL, proxy, contentType, not to use cache, directly disabling timeout (in an explicit way), and setting max idle connections.
headers := make(http.Header) headers.Add("myHeader", "myValue") var rb = rest.RequestBuilder{ Headers: headers, Timeout: 200 * time.Millisecond, BaseURL: "https://baseURL", Proxy: "http://myproxy", ContentType: rest.JSON, DisableCache: false, DisableTimeout: false, MaxIdleConnsPerHost: 10, } resp := rb.Get("/mypath")
Mockups ¶
When using mockups, all requests will be sent to the mockup server. To activate the mockup *environment* you have two ways: using the flag -mock
go test -mock
Or by programmatically starting the mockup server
StartMockupServer()
An example
myURL := "http://mytest.com/foo" myHeaders := make(http.Header) myHeaders.Add("Hello", "world") mock := rest.Mock{ URL: myURL, HTTPMethod: http.MethodGet, ReqHeaders: myHeaders, RespHTTPCode: http.StatusOK, RespBody: "foo", } rest.AddMockups(&mock) v := rest.Get(myURL)
Index ¶
- Constants
- Variables
- func AddMockups(mocks ...*Mock) error
- func AsyncDelete(url string, f func(*Response))
- func AsyncGet(url string, f func(*Response))
- func AsyncHead(url string, f func(*Response))
- func AsyncOptions(url string, f func(*Response))
- func AsyncPatch(url string, body interface{}, f func(*Response))
- func AsyncPost(url string, body interface{}, f func(*Response))
- func AsyncPut(url string, body interface{}, f func(*Response))
- func FlushMockups()
- func ForkJoin(f func(*Concurrent))
- func StartMockupServer()
- func StopMockupServer()
- type BasicAuth
- type ByteSize
- type Concurrent
- func (c *Concurrent) Delete(url string) *FutureResponse
- func (c *Concurrent) Get(url string) *FutureResponse
- func (c *Concurrent) Head(url string) *FutureResponse
- func (c *Concurrent) Options(url string) *FutureResponse
- func (c *Concurrent) Patch(url string, body interface{}) *FutureResponse
- func (c *Concurrent) Post(url string, body interface{}) *FutureResponse
- func (c *Concurrent) Put(url string, body interface{}) *FutureResponse
- type ContentType
- type CustomPool
- type FutureResponse
- type Mock
- type RequestBuilder
- func (rb *RequestBuilder) AsyncDelete(url string, f func(*Response))
- func (rb *RequestBuilder) AsyncGet(url string, f func(*Response))
- func (rb *RequestBuilder) AsyncHead(url string, f func(*Response))
- func (rb *RequestBuilder) AsyncOptions(url string, f func(*Response))
- func (rb *RequestBuilder) AsyncPatch(url string, body interface{}, f func(*Response))
- func (rb *RequestBuilder) AsyncPost(url string, body interface{}, f func(*Response))
- func (rb *RequestBuilder) AsyncPut(url string, body interface{}, f func(*Response))
- func (rb *RequestBuilder) Delete(url string) *Response
- func (rb *RequestBuilder) ForkJoin(f func(*Concurrent))
- func (rb *RequestBuilder) Get(url string) *Response
- func (rb *RequestBuilder) Head(url string) *Response
- func (rb *RequestBuilder) Options(url string) *Response
- func (rb *RequestBuilder) Patch(url string, body interface{}) *Response
- func (rb *RequestBuilder) Post(url string, body interface{}) *Response
- func (rb *RequestBuilder) Put(url string, body interface{}) *Response
- type Response
Constants ¶
const MOCK_NOT_FOUND_ERROR string = "MockUp nil!"
Variables ¶
var DefaultConnectTimeout = 1500 * time.Millisecond
var DefaultMaxIdleConnsPerHost = 2
DefaultMaxIdleConnsPerHost is the default maxium idle connections to have per Host for all clients, that use *any* RequestBuilder that don't set a CustomPool
var DefaultTimeout = 500 * time.Millisecond
DefaultTimeout is the default timeout for all clients. DefaultConnectTimeout is the time it takes to make a connection Type: time.Duration
var MaxCacheSize = 1 * GB
MaxCacheSize is the Maxium Byte Size to be hold by the ResourceCache Default is 1 GigaByte Type: rest.ByteSize
Functions ¶
func AsyncDelete ¶
AsyncDelete is the *asynchronous* option for DELETE. The go routine calling AsyncDelete(), will not be blocked.
Whenever the Response is ready, the *f* function will be called back.
AsyncDelete uses the DefaultBuilder
func AsyncGet ¶
AsyncGet is the *asynchronous* option for GET. The go routine calling AsyncGet(), will not be blocked.
Whenever the Response is ready, the *f* function will be called back.
AsyncGet uses the DefaultBuilder
func AsyncHead ¶
AsyncHead is the *asynchronous* option for HEAD. The go routine calling AsyncHead(), will not be blocked.
Whenever the Response is ready, the *f* function will be called back.
AsyncHead uses the DefaultBuilder
func AsyncOptions ¶
AsyncOptions is the *asynchronous* option for OPTIONS. The go routine calling AsyncOptions(), will not be blocked.
Whenever the Response is ready, the *f* function will be called back.
AsyncOptions uses the DefaultBuilder
func AsyncPatch ¶
AsyncPatch is the *asynchronous* option for PATCH. The go routine calling AsyncPatch(), will not be blocked.
Whenever the Response is ready, the *f* function will be called back.
AsyncPatch uses the DefaultBuilder
func AsyncPost ¶
AsyncPost is the *asynchronous* option for POST. The go routine calling AsyncPost(), will not be blocked.
Whenever the Response is ready, the *f* function will be called back.
AsyncPost uses the DefaultBuilder
func AsyncPut ¶
AsyncPut is the *asynchronous* option for PUT. The go routine calling AsyncPut(), will not be blocked.
Whenever the Response is ready, the *f* function will be called back.
AsyncPut uses the DefaultBuilder
func ForkJoin ¶
func ForkJoin(f func(*Concurrent))
ForkJoin let you *fork* requests, and *wait* until all of them have return.
Concurrent has methods for Get, Post, Put, Patch, Delete, Head & Options, with the almost the same API as the synchronous methods. The difference is that these methods return a FutureResponse, which holds a pointer to Response. Response inside FutureResponse is nil until request has finished.
var futureA, futureB *rest.FutureResponse rest.ForkJoin(func(c *rest.Concurrent){ futureA = c.Get("/url/1") futureB = c.Get("/url/2") }) fmt.Println(futureA.Response()) fmt.Println(futureB.Response())
AsyncOptions uses the DefaultBuilder
func StartMockupServer ¶
func StartMockupServer()
StartMockupServer sets the enviroment to send all client requests to the mockup server.
func StopMockupServer ¶
func StopMockupServer()
StopMockupServer stop sending requests to the mockup server
Types ¶
type BasicAuth ¶
BasicAuth gives the possibility to set UserName and Password for a given RequestBuilder. Basic Auth is used by some APIs
type Concurrent ¶
type Concurrent struct {
// contains filtered or unexported fields
}
Concurrent has methods for Get, Post, Put, Patch, Delete, Head & Options, with the almost the same API as the synchronous methods. The difference is that these methods return a FutureResponse, which holds a pointer to Response. Response inside FutureResponse is nil until the request has finished.
rest.ForkJoin(func(c *rest.Concurrent){ futureA = c.Get("/url/1") futureB = c.Get("/url/2") })
The difference is that Concurrent methods returns a FutureResponse, instead of a Resonse
func (*Concurrent) Delete ¶
func (c *Concurrent) Delete(url string) *FutureResponse
Delete issues a DELETE HTTP verb to the specified URL, concurrently with any other concurrent requests that may be called.
In Restful, DELETE is used to "delete" a resource. Client should expect a response status code of of 200(OK), 404(Not Found), or 400(Bad Request).
func (*Concurrent) Get ¶
func (c *Concurrent) Get(url string) *FutureResponse
Get issues a GET HTTP verb to the specified URL, concurrently with any other concurrent requests that may be called.
In Restful, GET is used for "reading" or retrieving a resource. Client should expect a response status code of 200(OK) if resource exists, 404(Not Found) if it doesn't, or 400(Bad Request).
func (*Concurrent) Head ¶
func (c *Concurrent) Head(url string) *FutureResponse
Head issues a HEAD HTTP verb to the specified URL, concurrently with any other concurrent requests that may be called.
In Restful, HEAD is used to "read" a resource headers only. Client should expect a response status code of 200(OK) if resource exists, 404(Not Found) if it doesn't, or 400(Bad Request).
func (*Concurrent) Options ¶
func (c *Concurrent) Options(url string) *FutureResponse
Options issues a OPTIONS HTTP verb to the specified URL, concurrently with any other concurrent requests that may be called.
In Restful, OPTIONS is used to get information about the resource and supported HTTP verbs. Client should expect a response status code of 200(OK) if resource exists, 404(Not Found) if it doesn't, or 400(Bad Request).
func (*Concurrent) Patch ¶
func (c *Concurrent) Patch(url string, body interface{}) *FutureResponse
Patch issues a PATCH HTTP verb to the specified URL, concurrently with any other concurrent requests that may be called.
In Restful, PATCH is used for "partially updating" a resource. Client should expect a response status code of of 200(OK), 404(Not Found), or 400(Bad Request). 200(OK) could be also 204(No Content)
Body could be any of the form: string, []byte, struct & map.
func (*Concurrent) Post ¶
func (c *Concurrent) Post(url string, body interface{}) *FutureResponse
Post issues a POST HTTP verb to the specified URL, concurrently with any other concurrent requests that may be called.
In Restful, POST is used for "creating" a resource. Client should expect a response status code of 201(Created), 400(Bad Request), 404(Not Found), or 409(Conflict) if resource already exist.
Body could be any of the form: string, []byte, struct & map.
func (*Concurrent) Put ¶
func (c *Concurrent) Put(url string, body interface{}) *FutureResponse
Put issues a PUT HTTP verb to the specified URL, concurrently with any other concurrent requests that may be called.
In Restful, PUT is used for "updating" a resource. Client should expect a response status code of of 200(OK), 404(Not Found), or 400(Bad Request). 200(OK) could be also 204(No Content)
Body could be any of the form: string, []byte, struct & map.
type ContentType ¶
type ContentType int
ContentType represents the Content Type for the Body of HTTP Verbs like POST, PUT, and PATCH
const ( // JSON represents a JSON Content Type JSON ContentType = iota // XML represents an XML Content Type XML // BYTES represents a plain Content Type BYTES )
type CustomPool ¶
type CustomPool struct { MaxIdleConnsPerHost int Proxy string // Public for custom fine tuning Transport http.RoundTripper }
CustomPool defines a separate internal *transport* and connection pooling.
type FutureResponse ¶
type FutureResponse struct {
// contains filtered or unexported fields
}
FutureResponse represents a response to be completed after a ForkJoin operation is done.
FutureResponse will never be nil, and has a Response function for getting the Response, that will be nil after the ForkJoin operation is completed
func (*FutureResponse) Response ¶
func (fr *FutureResponse) Response() *Response
Response gives you the Response of a Request,after the ForkJoin operation is completed.
Response will be nil if the ForkJoin operation is not completed.
type Mock ¶
type Mock struct { // Request URL URL string // Request HTTP Method (GET, POST, PUT, PATCH, HEAD, DELETE, OPTIONS) // As a good practice use the constants in http package (http.MethodGet, etc.) HTTPMethod string // Request array Headers ReqHeaders http.Header // Request Body, used with POST, PUT & PATCH ReqBody string // Response HTTP Code RespHTTPCode int // Response Array Headers RespHeaders http.Header // Response Body RespBody string }
Mock serves the purpose of creating Mockups. All requests will be sent to the mockup server if mockup is activated. To activate the mockup *environment* you have two ways: using the flag -mock
go test -mock
Or by programmatically starting the mockup server
StartMockupServer()
type RequestBuilder ¶
type RequestBuilder struct { // Headers to be send in the request Headers http.Header // Complete request time out. Timeout time.Duration //Connection timeout, it bounds the time spent obtaining a successful connection ConnectTimeout time.Duration // Base URL to be used for each Request. The final URL will be BaseURL + URL. BaseURL string // ContentType ContentType ContentType // Disable internal caching of Responses DisableCache bool // Disable timeout and default timeout = no timeout DisableTimeout bool // Set the http client to follow a redirect if we get a 3xx response FollowRedirect bool // Create a CustomPool if you don't want to share the *transport*, with others // RequestBuilder CustomPool *CustomPool // Set Basic Auth for this RequestBuilder BasicAuth *BasicAuth // Set an specific User Agent for this RequestBuilder UserAgent string // Public for custom fine tuning Client *http.Client // contains filtered or unexported fields }
RequestBuilder is the baseline for creating requests There's a Default Builder that you may use for simple requests RequestBuilder si thread-safe, and you should store it for later re-used.
func (*RequestBuilder) AsyncDelete ¶
func (rb *RequestBuilder) AsyncDelete(url string, f func(*Response))
AsyncDelete is the *asynchronous* option for DELETE. The go routine calling AsyncDelete(), will not be blocked.
Whenever the Response is ready, the *f* function will be called back.
func (*RequestBuilder) AsyncGet ¶
func (rb *RequestBuilder) AsyncGet(url string, f func(*Response))
AsyncGet is the *asynchronous* option for GET. The go routine calling AsyncGet(), will not be blocked.
Whenever the Response is ready, the *f* function will be called back.
func (*RequestBuilder) AsyncHead ¶
func (rb *RequestBuilder) AsyncHead(url string, f func(*Response))
AsyncHead is the *asynchronous* option for HEAD. The go routine calling AsyncHead(), will not be blocked.
Whenever the Response is ready, the *f* function will be called back.
func (*RequestBuilder) AsyncOptions ¶
func (rb *RequestBuilder) AsyncOptions(url string, f func(*Response))
AsyncOptions is the *asynchronous* option for OPTIONS. The go routine calling AsyncOptions(), will not be blocked.
Whenever the Response is ready, the *f* function will be called back.
func (*RequestBuilder) AsyncPatch ¶
func (rb *RequestBuilder) AsyncPatch(url string, body interface{}, f func(*Response))
AsyncPatch is the *asynchronous* option for PATCH. The go routine calling AsyncPatch(), will not be blocked.
Whenever the Response is ready, the *f* function will be called back.
func (*RequestBuilder) AsyncPost ¶
func (rb *RequestBuilder) AsyncPost(url string, body interface{}, f func(*Response))
AsyncPost is the *asynchronous* option for POST. The go routine calling AsyncPost(), will not be blocked.
Whenever the Response is ready, the *f* function will be called back.
func (*RequestBuilder) AsyncPut ¶
func (rb *RequestBuilder) AsyncPut(url string, body interface{}, f func(*Response))
AsyncPut is the *asynchronous* option for PUT. The go routine calling AsyncPut(), will not be blocked.
Whenever the Response is ready, the *f* function will be called back.
func (*RequestBuilder) Delete ¶
func (rb *RequestBuilder) Delete(url string) *Response
Delete issues a DELETE HTTP verb to the specified URL
In Restful, DELETE is used to "delete" a resource. Client should expect a response status code of of 200(OK), 404(Not Found), or 400(Bad Request).
func (*RequestBuilder) ForkJoin ¶
func (rb *RequestBuilder) ForkJoin(f func(*Concurrent))
ForkJoin let you *fork* requests, and *wait* until all of them have return.
Concurrent has methods for Get, Post, Put, Patch, Delete, Head & Options, with the almost the same API as the synchronous methods. The difference is that these methods return a FutureResponse, which holds a pointer to Response. Response inside FutureResponse is nil until the request has finished.
var futureA, futureB *rest.FutureResponse rest.ForkJoin(func(c *rest.Concurrent){ futureA = c.Get("/url/1") futureB = c.Get("/url/2") }) fmt.Println(futureA.Response()) fmt.Println(futureB.Response())
func (*RequestBuilder) Get ¶
func (rb *RequestBuilder) Get(url string) *Response
Get issues a GET HTTP verb to the specified URL.
In Restful, GET is used for "reading" or retrieving a resource. Client should expect a response status code of 200(OK) if resource exists, 404(Not Found) if it doesn't, or 400(Bad Request).
func (*RequestBuilder) Head ¶
func (rb *RequestBuilder) Head(url string) *Response
Head issues a HEAD HTTP verb to the specified URL
In Restful, HEAD is used to "read" a resource headers only. Client should expect a response status code of 200(OK) if resource exists, 404(Not Found) if it doesn't, or 400(Bad Request).
func (*RequestBuilder) Options ¶
func (rb *RequestBuilder) Options(url string) *Response
Options issues a OPTIONS HTTP verb to the specified URL
In Restful, OPTIONS is used to get information about the resource and supported HTTP verbs. Client should expect a response status code of 200(OK) if resource exists, 404(Not Found) if it doesn't, or 400(Bad Request).
func (*RequestBuilder) Patch ¶
func (rb *RequestBuilder) Patch(url string, body interface{}) *Response
Patch issues a PATCH HTTP verb to the specified URL.
In Restful, PATCH is used for "partially updating" a resource. Client should expect a response status code of of 200(OK), 404(Not Found), or 400(Bad Request). 200(OK) could be also 204(No Content)
Body could be any of the form: string, []byte, struct & map.
func (*RequestBuilder) Post ¶
func (rb *RequestBuilder) Post(url string, body interface{}) *Response
Post issues a POST HTTP verb to the specified URL.
In Restful, POST is used for "creating" a resource. Client should expect a response status code of 201(Created), 400(Bad Request), 404(Not Found), or 409(Conflict) if resource already exist.
Body could be any of the form: string, []byte, struct & map.
func (*RequestBuilder) Put ¶
func (rb *RequestBuilder) Put(url string, body interface{}) *Response
Put issues a PUT HTTP verb to the specified URL.
In Restful, PUT is used for "updating" a resource. Client should expect a response status code of of 200(OK), 404(Not Found), or 400(Bad Request). 200(OK) could be also 204(No Content)
Body could be any of the form: string, []byte, struct & map.
type Response ¶
Response ...
func Delete ¶
Delete issues a DELETE HTTP verb to the specified URL
In Restful, DELETE is used to "delete" a resource. Client should expect a response status code of of 200(OK), 404(Not Found), or 400(Bad Request).
Delete uses the DefaultBuilder.
func Get ¶
Get issues a GET HTTP verb to the specified URL.
In Restful, GET is used for "reading" or retrieving a resource. Client should expect a response status code of 200(OK) if resource exists, 404(Not Found) if it doesn't, or 400(Bad Request).
Get uses the DefaultBuilder.
func Head ¶
Head issues a HEAD HTTP verb to the specified URL
In Restful, HEAD is used to "read" a resource headers only. Client should expect a response status code of 200(OK) if resource exists, 404(Not Found) if it doesn't, or 400(Bad Request).
Head uses the DefaultBuilder.
func Options ¶
Options issues a OPTIONS HTTP verb to the specified URL
In Restful, OPTIONS is used to get information about the resource and supported HTTP verbs. Client should expect a response status code of 200(OK) if resource exists, 404(Not Found) if it doesn't, or 400(Bad Request).
Options uses the DefaultBuilder.
func Patch ¶
Patch issues a PATCH HTTP verb to the specified URL
In Restful, PATCH is used for "partially updating" a resource. Client should expect a response status code of of 200(OK), 404(Not Found), or 400(Bad Request). 200(OK) could be also 204(No Content)
Body could be any of the form: string, []byte, struct & map.
Patch uses the DefaultBuilder.
func Post ¶
Post issues a POST HTTP verb to the specified URL.
In Restful, POST is used for "creating" a resource. Client should expect a response status code of 201(Created), 400(Bad Request), 404(Not Found), or 409(Conflict) if resource already exist.
Body could be any of the form: string, []byte, struct & map.
Post uses the DefaultBuilder.
func Put ¶
Put issues a PUT HTTP verb to the specified URL.
In Restful, PUT is used for "updating" a resource. Client should expect a response status code of of 200(OK), 404(Not Found), or 400(Bad Request). 200(OK) could be also 204(No Content)
Body could be any of the form: string, []byte, struct & map.
Put uses the DefaultBuilder.
func (*Response) Debug ¶
Debug let any request/response to be dumped, showing how the request/response went through the wire, only if debug mode is *on* on RequestBuilder.