rest

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2024 License: MIT Imports: 12 Imported by: 1

README

go-kit/rest - Rest Module

Go Reference Last Commit Open Issues Open Pull Requests

The rest module provides an easy-to-use client to make HTTP requests to a RESTful API.

About this module

The rest module provides a generic REST client to make HTTP requests towards a (RESTful) API. It is built on top of the standard http package and provides a simple interface to make requests and handle responses. It also provides a mock client to use in tests.

Installation

To install, run:

go get github.com/lvlcn-t/go-kit/rest

And import the package in your code:

import "github.com/lvlcn-t/go-kit/rest"

Usage

The documentation for this module can be found on pkg.go.dev.

To see how to use this module, you can check the examples directory of the repository.

Code of Conduct

This project has adopted the Contributor Covenant in version 2.1 as our code of conduct. Please see the details in our CODE_OF_CONDUCT.md. All contributors must abide by the code of conduct.

Working Language

We decided to apply English as the primary project language.

Consequently, all content will be made available primarily in English. We also ask all interested people to use English as the preferred language to create issues, in their code (comments, documentation, etc.) and when you send requests to us. The application itself and all end-user facing content will be made available in other languages as needed.

Support and Feedback

The following channels are available for discussions, feedback, and support requests:

Type Channel
Issues General Discussion

How to Contribute

Contribution and feedback is encouraged and always welcome. For more information about how to contribute, the project structure, as well as additional contribution information, see our Contribution Guidelines. By participating in this project, you agree to abide by its Code of Conduct at all times.

Licensing

Copyright (c) 2024 lvlcn-t.

Licensed under the MIT (the "License"); you may not use this file except in compliance with the License.

You may obtain a copy of the License at https://www.mit.edu/~amini/LICENSE.md.

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an " AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the LICENSE for the specific language governing permissions and limitations under the License.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrRateLimitExceeded = errors.New("rate limit exceeded")

ErrRateLimitExceeded is the error returned when the rate limit is exceeded.

Functions

func Close

func Close(ctx context.Context)

Close closes the default rest client and gracefully awaits all pending requests to finish. If the context is canceled, it will close the idle connections immediately.

func Do

func Do[T any](ctx context.Context, endpoint *Endpoint, payload any, opts ...RequestOption) (resp T, code int, err error)

Do makes a request to the given endpoint with the given payload and response type. It applies the given options and returns an error if the request fails.

Example:

// Define the request endpoint
ctx := context.Background()
endpoint := rest.Get("https://api.example.com/resource")

// Define the response type
type response struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

// Make the request
resp, status, err := rest.Do[response](ctx, endpoint, nil)
if err != nil {
	// Handle error
}

The request will be made to "https://api.example.com/resource" with the payload marshaled to JSON and the response unmarshaled into a response object with the given type.

Types

type Client

type Client interface {
	// Do makes a request to the given [Endpoint], with the given payload and response objects. It applies the given options.
	// Returns the status code of the response and an error if the request fails.
	//
	// Example:
	//	ctx := context.Background()
	// 	client := rest.NewClient("https://api.example.com", 5*time.Second)
	// 	defer client.Close(ctx)
	//
	// 	endpoint := rest.Post("/resource")
	// 	payload := map[string]string{"key": "value"}
	// 	var response map[string]any
	// 	status, err := client.Do(ctx, endpoint, payload, &response)
	//	if err != nil {
	// 		// Handle error
	// 	}
	//
	// The request will be made to "https://api.example.com/resource" with the payload marshaled to JSON
	// and the response unmarshaled into the response object.
	Do(ctx context.Context, endpoint *Endpoint, payload, response any, opts ...RequestOption) (int, error)
	// Close closes the rest client and gracefully awaits all pending requests to finish.
	// If the context is canceled, it will close the idle connections immediately.
	Close(ctx context.Context)
	// Client returns the [http.Client] the rest client uses.
	Client() *http.Client
	// RateLimiter returns the [rate.Limiter] the rest client uses.
	RateLimiter() *rate.Limiter
}

Client allows doing requests to different endpoints. It provides a simple way to make requests with rate limiting and request options. The client is safe for concurrent use.

var (

	// DefaultClient is the default rest client used for making requests.
	DefaultClient Client = newDefaultClient()
)

func NewClient

func NewClient(baseURL string, timeout ...time.Duration) (Client, error)

NewClient creates a new rest client with the given base URL. You can optionally provide a timeout for requests. If no timeout is provided, the default timeout is used.

type ClientMock

type ClientMock struct {
	// ClientFunc mocks the Client method.
	ClientFunc func() *http.Client

	// CloseFunc mocks the Close method.
	CloseFunc func(ctx context.Context)

	// DoFunc mocks the Do method.
	DoFunc func(ctx context.Context, endpoint *Endpoint, payload any, response any, opts ...RequestOption) (int, error)

	// RateLimiterFunc mocks the RateLimiter method.
	RateLimiterFunc func() *rate.Limiter
	// contains filtered or unexported fields
}

ClientMock is a mock implementation of Client.

func TestSomethingThatUsesClient(t *testing.T) {

	// make and configure a mocked Client
	mockedClient := &ClientMock{
		ClientFunc: func() *http.Client {
			panic("mock out the Client method")
		},
		CloseFunc: func(ctx context.Context)  {
			panic("mock out the Close method")
		},
		DoFunc: func(ctx context.Context, endpoint *Endpoint, payload any, response any, opts ...RequestOption) (int, error) {
			panic("mock out the Do method")
		},
		RateLimiterFunc: func() *rate.Limiter {
			panic("mock out the RateLimiter method")
		},
	}

	// use mockedClient in code that requires Client
	// and then make assertions.

}

func (*ClientMock) Client

func (mock *ClientMock) Client() *http.Client

Client calls ClientFunc.

func (*ClientMock) ClientCalls

func (mock *ClientMock) ClientCalls() []struct {
}

ClientCalls gets all the calls that were made to Client. Check the length with:

len(mockedClient.ClientCalls())

func (*ClientMock) Close

func (mock *ClientMock) Close(ctx context.Context)

Close calls CloseFunc.

func (*ClientMock) CloseCalls

func (mock *ClientMock) CloseCalls() []struct {
	Ctx context.Context
}

CloseCalls gets all the calls that were made to Close. Check the length with:

len(mockedClient.CloseCalls())

func (*ClientMock) Do

func (mock *ClientMock) Do(ctx context.Context, endpoint *Endpoint, payload any, response any, opts ...RequestOption) (int, error)

Do calls DoFunc.

func (*ClientMock) DoCalls

func (mock *ClientMock) DoCalls() []struct {
	Ctx      context.Context
	Endpoint *Endpoint
	Payload  any
	Response any
	Opts     []RequestOption
}

DoCalls gets all the calls that were made to Do. Check the length with:

len(mockedClient.DoCalls())

func (*ClientMock) RateLimiter

func (mock *ClientMock) RateLimiter() *rate.Limiter

RateLimiter calls RateLimiterFunc.

func (*ClientMock) RateLimiterCalls

func (mock *ClientMock) RateLimiterCalls() []struct {
}

RateLimiterCalls gets all the calls that were made to RateLimiter. Check the length with:

len(mockedClient.RateLimiterCalls())

type Endpoint

type Endpoint struct {
	// Method is the HTTP method to use for the request.
	Method string
	// Path is the URL path to the endpoint.
	Path string
	// Query is the URL query parameters to use for the request.
	Query url.Values
}

Endpoint represents a REST endpoint.

func Delete

func Delete(path string, queries ...url.Values) *Endpoint

Delete creates a new Endpoint with the http.MethodDelete method and the given path and queries.

func Get

func Get(path string, queries ...url.Values) *Endpoint

Get creates a new Endpoint with the http.MethodGet method and the given path and queries.

func Patch

func Patch(path string, queries ...url.Values) *Endpoint

Patch creates a new Endpoint with the http.MethodPatch method and the given path and queries.

func Post

func Post(path string, queries ...url.Values) *Endpoint

Post creates a new Endpoint with the http.MethodPost method and the given path and queries.

func Put

func Put(path string, queries ...url.Values) *Endpoint

Put creates a new Endpoint with the http.MethodPut method and the given path and queries.

func (*Endpoint) AddQuery

func (e *Endpoint) AddQuery(query url.Values) *Endpoint

Query adds the given query parameters to the endpoint.

func (*Endpoint) Compile

func (e *Endpoint) Compile(baseURL string) (string, error)

Compile compiles the endpoint into a full URL.

type ErrDecodingResponse

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

ErrDecodingResponse is the error returned when the response cannot be unmarshalled into the response object.

func (*ErrDecodingResponse) Error

func (e *ErrDecodingResponse) Error() string

Error returns the error message.

func (*ErrDecodingResponse) Is

func (e *ErrDecodingResponse) Is(target error) bool

Is checks if the target error is an ErrDecodingResponse.

func (*ErrDecodingResponse) Unwrap

func (e *ErrDecodingResponse) Unwrap() error

Unwrap returns the wrapped error.

type Request

type Request struct {
	// Request is the HTTP request to be made.
	Request *http.Request
	// Delay is the amount of time to wait before executing the request.
	Delay time.Duration
}

Request represents a request to be made by the rest client.

type RequestOption

type RequestOption func(*Request)

RequestOption is a function that modifies a request.

func WithBasicAuth

func WithBasicAuth(username, password string) RequestOption

WithBasicAuth is a request option that sets basic auth for the request

func WithBearer

func WithBearer(token string) RequestOption

WithBearer is a request option that sets a bearer token for the request

func WithDelay

func WithDelay(d time.Duration) RequestOption

WithDelay is a request option that adds a delay before executing the request

func WithHeader

func WithHeader(key, value string) RequestOption

WithHeader is a request option that sets custom headers for the request

func WithTracer

func WithTracer(c *httptrace.ClientTrace) RequestOption

WithTracer is a request option that sets a httptrace.ClientTrace for the request.

Jump to

Keyboard shortcuts

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