The Roku REST client provides a straightforward and simple interface for interacting with REST APIs. With Roku you can:
- Easily marshal and unmarshal requests and responses without the need for boilerplate or repetitive code.
- Utilize the built-in exponential backoff algorithm.
- Enhance your request functions by wrapping them with RxGo 2 Observable streams, enabling the creation of custom pipelines, including parallel requests.
-
Before starting to make requests, we need to create a *http.Client in Golang. For this, we can use Roku's constructor method:
import ( ... "github.com/v8tix/roku" "net/http" ... ) func NewHTTPClient( timeout time.Duration, redirectPolicy func(req *http.Request, via []*http.Request) error, transport http.RoundTripper, ) *http.Client { ... }
-
Where:
timeout: Its purpose is to control how long the client waits to receive a response from the server before considering the request as failed due to a timeout.
redirectPolicy: Its purpose is to allow you to control how the HTTP client handles 3xx redirection responses.
transport: Its purpose is to allow you to have more granular control over how HTTP requests are made and how network connections are managed. -
Example:
httpClient := roku.NewHTTPClient( 5*time.Second, policy.OneRedirect, transport.IdleConnectionTimeout(15*time.Second), )
The OneRedirect and IdleConnectionTimeout functions are examples of how the Golang REST client can be configured and are part of Roku. -
*Once our client is configured, we can start configuring the functions provided by Roku: Fetch and FetchRx. The difference between them is that Fetch does not provide a backoff mechanism and does not return the response as an observable. For production environments, we recommend using Rx.
- FetchRx signature:
func FetchRx[T ReqI, U ResI](
ctx context.Context,
client *http.Client,
method HTTPMethod,
endpoint string,
request *T,
headers map[string]string,
deadline time.Duration,
backoffInterval time.Duration,
backoffRetries uint64,
statusCodeValidator ...func(res *http.Response) bool,
) rxgo.Observable {
...
}
- FetchRx example:
ch := roku.FetchRx[CreateUserV1Req, GetUserEnvV1Res](
context.Background(),
httpClient,
roku.Put,
url,
createUserV1Req,
nil,
time.Second,
150 * time.Millisecond,
3,
).Observe()
res, err := roku.To[roku.Envelope[GetUserEnvV1Res]](<-ch)
switch err {
case nil:
if res.Body != nil {
...
return res.Body.User
}
default:
var errHTTP roku.ErrInvalidHTTPStatus
if errors.As(err, &errHTTP) {
errDesc := roku.GetErrorDesc(errHTTP)
return fmt.Errorf("http error: %v", errDesc)
}
}
- Notes about the example:
- Due to generics in Golang, CreateUserV1Req and GetUserEnvV1Res must implement the roku.ReqI and roku.ResI interfaces, respectively.
type CreateUserV1Req struct {
Name string `json:"name,omitempty"`
Email string `json:"email,omitempty"`
}
func (CreateUserV1Req) Req() {}
type GetUserEnvV1Res struct {
User GetUserV1Res `json:"user,omitempty"`
}
func (GetUserEnvV1Res) Res() {}
- In cases where the request does not have a request body, you should use the type roku.NoReq and pass nil as a parameter to FetchRx.
- In cases where the request does not return a response, you should use the type roku.NoRes for FetchRx.
ch:= roku.FetchRx[roku.NoReq, roku.NoRes](
ctx,
httpClient,
roku.Delete,
url,
nil,
nil,
roku.DeadLine,
roku.RetryInterval,
3,
).Observe()
_, err := roku.To[roku.Envelope[roku.NoRes]](<-ch)
switch err {
case nil:
return nil
default:
var errHTTP roku.ErrInvalidHTTPStatus
if errors.As(err, &errHTTP) {
errDesc := roku.GetErrorDesc(errHTTP)
return fmt.Errorf("http error: %v", errDesc)
}
}
- deadline: It enables FetchRx to block requests to the service, preventing both overloading and cascading failures.
- backoffInterval: It represents a waiting period in which FetchRx delays before attempting to retry a failed request.
- backoffRetries: It represents the maximum number of retry attempts that FetchRx will make for a request.
- Fork the repository
- Clone the forked repository
- Create a new branch for your feature or fix
- Make your changes
- Submit a pull request
This project is licensed under the MIT License. You can refer to the LICENSE file for more information.