http

package
v0.0.41 Latest Latest
Warning

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

Go to latest
Published: Nov 16, 2025 License: MIT Imports: 17 Imported by: 0

Documentation

Index

Examples

Constants

View Source
const (
	ErrNilResponse         = httpError("nil response provided")
	ErrEmptyResponseBody   = httpError("empty response body")
	ErrNilTarget           = httpError("nil value passed for decoding target")
	ErrRequestFailure      = httpError("request failed")
	ErrDecodeResponseBody  = httpError("failed to decode response body")
	ErrDecodeErrorResponse = httpError("failed to decode error response")
)

Variables

This section is empty.

Functions

func DecodeRequestJSON

func DecodeRequestJSON[T any](request *http.Request, v *T, opts DecodeOptions) error

func DecodeResponseJSON

func DecodeResponseJSON[T any](response *http.Response, v *T, opts DecodeOptions) error

func InjectMessageMetadata

func InjectMessageMetadata(ctx context.Context, metadata types.Metadata) context.Context

func NewRequestWithContext

func NewRequestWithContext[T any](ctx context.Context, method, baseURL string,
	options ...RequestOption[T],
) (*http.Request, error)

NewRequestWithContext ...

func RequestWithContext

func RequestWithContext[T any](ctx context.Context, req *Request[T]) (*http.Request, error)

func RetrieveMessageMetadata

func RetrieveMessageMetadata(ctx context.Context) types.Metadata

Types

type AnySender

type AnySender Sender[any]

type AnySenderFunc

type AnySenderFunc SenderFunc[any]

func (AnySenderFunc) Send

func (fn AnySenderFunc) Send(ctx context.Context, request *Request[any], decoder ResponseDecoder) error

type CoreClient

type CoreClient[T any] struct {
	// contains filtered or unexported fields
}

func NewAnySender

func NewAnySender(options ...CoreClientOption[any]) *CoreClient[any]

func NewSender

func NewSender[T any](options ...CoreClientOption[T]) *CoreClient[T]
Example
package main

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"time"

	whttp "github.com/piusalfred/whatsapp/pkg/http"
)

type TestMessage struct {
	Name  string `json:"name"`
	Value int    `json:"value"`
}

func main() {
	customHTTPClient := &http.Client{
		Timeout: 2 * time.Second,
	}

	// Define middleware that logs request information
	loggingMiddleware := func(next whttp.SenderFunc[TestMessage]) whttp.SenderFunc[TestMessage] {
		return func(ctx context.Context, req *whttp.Request[TestMessage], decoder whttp.ResponseDecoder) error {
			fmt.Println("request logger init called before core middlewares")

			return next(ctx, req, decoder)
		}
	}

	methodPrinter := func(next whttp.SenderFunc[TestMessage]) whttp.SenderFunc[TestMessage] {
		return func(ctx context.Context, req *whttp.Request[TestMessage], decoder whttp.ResponseDecoder) error {
			fmt.Printf("from core middleware request method is: %s\n", req.Method)

			return next(ctx, req, decoder)
		}
	}

	loggingMiddleware2 := func(next whttp.SenderFunc[TestMessage]) whttp.SenderFunc[TestMessage] {
		return func(ctx context.Context, req *whttp.Request[TestMessage], decoder whttp.ResponseDecoder) error {
			fmt.Println("called after core middleware request logger final")

			return next(ctx, req, decoder)
		}
	}

	loggingMiddleware3 := func(next whttp.SenderFunc[TestMessage]) whttp.SenderFunc[TestMessage] {
		return func(ctx context.Context, req *whttp.Request[TestMessage], decoder whttp.ResponseDecoder) error {
			err := next(ctx, req, decoder)
			fmt.Println("called after request send execution and the err is:", err)

			return err
		}
	}

	reqInterceptor := func(_ context.Context, req *http.Request) error {
		fmt.Println("Just intercepted the request and the method is:", req.Method)

		return nil
	}

	resInterceptor := func(_ context.Context, res *http.Response) error {
		fmt.Println("Just intercepted the response and status code:", res.StatusCode)

		return nil
	}

	resBodyInterceptor := func(_ context.Context, res *http.Response) error {
		body, _ := io.ReadAll(res.Body)
		defer func() {
			res.Body = io.NopCloser(bytes.NewReader(body))
		}()
		fmt.Println("from response body interceptor:", string(body))

		return nil
	}

	options := []whttp.CoreClientOption[TestMessage]{
		whttp.WithCoreClientHTTPClient[TestMessage](customHTTPClient),
		whttp.WithCoreClientMiddlewares[TestMessage](methodPrinter),
		whttp.WithCoreClientRequestInterceptor[TestMessage](nil),
		whttp.WithCoreClientResponseInterceptor[TestMessage](resBodyInterceptor),
	}

	sender := whttp.NewSender(
		options...,
	)

	longLiveClient := &http.Client{Timeout: time.Hour}

	sender.PrependMiddlewares(loggingMiddleware) // they will be executed first before previous set middlewares if any
	sender.AppendMiddlewares(loggingMiddleware2, loggingMiddleware3)
	sender.SetHTTPClient(longLiveClient)
	sender.SetRequestInterceptor(reqInterceptor)  // overrides the default interceptors
	sender.SetResponseInterceptor(resInterceptor) // overrides the default interceptors

	echoHandler := func(w http.ResponseWriter, r *http.Request) {
		bodyBytes, err := io.ReadAll(r.Body)
		if err != nil {
			http.Error(w, "could not read body", http.StatusInternalServerError)

			return
		}
		defer r.Body.Close()

		w.WriteHeader(http.StatusOK)
		w.Write(bodyBytes)
	}

	server := httptest.NewServer(http.HandlerFunc(echoHandler))
	defer server.Close()

	req := &whttp.Request[TestMessage]{
		Method:    http.MethodPost,
		BaseURL:   server.URL,
		Endpoints: []string{"send"},
		Message:   &TestMessage{Name: "Hello", Value: 123},
		Bearer:    "example-token",
	}

	// Response decoder to handle the response
	decoder := whttp.ResponseDecoderJSON(&TestMessage{}, whttp.DecodeOptions{})

	// Send the request using the sender
	err := sender.Send(context.Background(), req, decoder)
	if err != nil {
		fmt.Println("Error sending request:", err)
	}

}
Output:
request logger init called before core middlewares
from core middleware request method is: POST
called after core middleware request logger final
Just intercepted the request and the method is: POST
Just intercepted the response and status code: 200
called after request send execution and the err is: <nil>

func (*CoreClient[T]) AppendMiddlewares

func (core *CoreClient[T]) AppendMiddlewares(mws ...Middleware[T])

func (*CoreClient[T]) PrependMiddlewares

func (core *CoreClient[T]) PrependMiddlewares(mws ...Middleware[T])

func (*CoreClient[T]) Send

func (core *CoreClient[T]) Send(ctx context.Context, request *Request[T], decoder ResponseDecoder) error

func (*CoreClient[T]) SetBaseSender

func (core *CoreClient[T]) SetBaseSender(sender Sender[T])

func (*CoreClient[T]) SetHTTPClient

func (core *CoreClient[T]) SetHTTPClient(httpClient *http.Client)

func (*CoreClient[T]) SetRequestInterceptor

func (core *CoreClient[T]) SetRequestInterceptor(hook RequestInterceptorFunc)

func (*CoreClient[T]) SetResponseInterceptor

func (core *CoreClient[T]) SetResponseInterceptor(hook ResponseInterceptorFunc)

type CoreClientOption

type CoreClientOption[T any] func(client *CoreClient[T])

func WithCoreClientHTTPClient

func WithCoreClientHTTPClient[T any](httpClient *http.Client) CoreClientOption[T]

func WithCoreClientMiddlewares

func WithCoreClientMiddlewares[T any](mws ...Middleware[T]) CoreClientOption[T]

func WithCoreClientRequestInterceptor

func WithCoreClientRequestInterceptor[T any](hook RequestInterceptorFunc) CoreClientOption[T]

func WithCoreClientResponseInterceptor

func WithCoreClientResponseInterceptor[T any](hook ResponseInterceptorFunc) CoreClientOption[T]

type Cursors

type Cursors struct {
	After  string `json:"after,omitempty"`
	Before string `json:"before,omitempty"`
}

type DecodeOptions

type DecodeOptions struct {
	DisallowUnknownFields bool
	DisallowEmptyResponse bool
	InspectResponseError  bool
}

type EncodeResponse

type EncodeResponse struct {
	Body        io.Reader
	ContentType string
}

func EncodePayload

func EncodePayload(payload any) (*EncodeResponse, error)

EncodePayload takes different types of payloads (form data, readers, JSON) and returns an EncodeResponse.

type FormFile

type FormFile struct {
	Name string
	Path string
	Type string
}

type Middleware

type Middleware[T any] func(next SenderFunc[T]) SenderFunc[T]

type Paging

type Paging struct {
	Cursors  *Cursors `json:"cursors,omitempty"`
	Previous string   `json:"previous,omitempty"`
	Next     string   `json:"next,omitempty"`
}

type Request

type Request[T any] struct {
	Type           RequestType
	Method         string
	Bearer         string
	Headers        map[string]string
	QueryParams    map[string]string
	BaseURL        string
	Endpoints      []string
	Metadata       types.Metadata
	Message        *T
	Form           *RequestForm
	AppSecret      string
	SecureRequests bool
	DownloadURL    string // this is used for downloading media (it is taken as is)
	BodyReader     io.Reader
}

func MakeDownloadRequest

func MakeDownloadRequest[T any](downloadURL string, options ...RequestOption[T]) *Request[T]

MakeDownloadRequest creates a new request for downloading media.

func MakeRequest

func MakeRequest[T any](method, baseURL string, options ...RequestOption[T]) *Request[T]

MakeRequest creates a new request with the provided options.

func (*Request[T]) SetEndpoints

func (request *Request[T]) SetEndpoints(endpoints ...string)

func (*Request[T]) SetRequestMessage

func (request *Request[T]) SetRequestMessage(message *T)

SetRequestMessage sets the body of the request.

func (*Request[T]) URL

func (request *Request[T]) URL() (string, error)

URL returns the formatted URL for the request.

type RequestForm

type RequestForm struct {
	Fields   map[string]string
	FormFile *FormFile
}

type RequestInterceptor

type RequestInterceptor interface {
	InterceptRequest(ctx context.Context, request *http.Request) error
}

type RequestInterceptorFunc

type RequestInterceptorFunc func(ctx context.Context, request *http.Request) error

func (RequestInterceptorFunc) InterceptRequest

func (fn RequestInterceptorFunc) InterceptRequest(ctx context.Context, request *http.Request) error

type RequestOption

type RequestOption[T any] func(request *Request[T])

func WithRequestAppSecret

func WithRequestAppSecret[T any](appSecret string) RequestOption[T]

WithRequestAppSecret sets the app secret for the request and turns on secure requests.

func WithRequestBearer

func WithRequestBearer[T any](bearer string) RequestOption[T]

WithRequestBearer sets the bearer token for the request.

func WithRequestBodyReader

func WithRequestBodyReader[T any](bodyReader io.Reader) RequestOption[T]

func WithRequestEndpoints

func WithRequestEndpoints[T any](endpoints ...string) RequestOption[T]

WithRequestEndpoints sets the endpoints for the request.

func WithRequestForm

func WithRequestForm[T any](form *RequestForm) RequestOption[T]

func WithRequestHeaders

func WithRequestHeaders[T any](headers map[string]string) RequestOption[T]

WithRequestHeaders sets the headers for the request.

func WithRequestMessage

func WithRequestMessage[T any](message *T) RequestOption[T]

WithRequestMessage sets the message for the request.

func WithRequestMetadata

func WithRequestMetadata[T any](metadata types.Metadata) RequestOption[T]

WithRequestMetadata sets the metadata for the request.

func WithRequestQueryParams

func WithRequestQueryParams[T any](queryParams map[string]string) RequestOption[T]

WithRequestQueryParams sets the query parameters for the request.

func WithRequestSecured

func WithRequestSecured[T any](secured bool) RequestOption[T]

WithRequestSecured sets the request to be secure.

func WithRequestType

func WithRequestType[T any](requestType RequestType) RequestOption[T]

WithRequestType sets the request type for the request.

type RequestType

type RequestType uint8
const (
	RequestTypeSendMessage RequestType = iota
	RequestTypeUpdateStatus
	RequestTypeCreateQR
	RequestTypeListQR
	RequestTypeGetQR
	RequestTypeUpdateQR
	RequestTypeDeleteQR
	RequestTypeListPhoneNumbers
	RequestTypeGetPhoneNumber
	RequestTypeDownloadMedia
	RequestTypeUploadMedia
	RequestTypeDeleteMedia
	RequestTypeGetMedia
	RequestTypeUpdateBusinessProfile
	RequestTypeGetBusinessProfile
	RequestTypeRetrieveFlows
	RequestTypeRetrieveFlowDetails
	RequestTypeRetrieveAssets
	RequestTypePublishFlow
	RequestTypeDeprecateFlow
	RequestTypeDeleteFlow
	RequestTypeUpdateFlow
	RequestTypeCreateFlow
	RequestTypeRetrieveFlowPreview
	RequestTypeGetFlowMetrics
	RequestTypeInstallApp
	RequestTypeRefreshToken
	RequestTypeGenerateToken
	RequestTypeRevokeToken
	RequestTypeTwoStepVerification
	RequestTypeFetchMessagingAnalytics
	RequestTypeFetchTemplateAnalytics
	RequestTypeFetchPricingAnalytics
	RequestTypeFetchConversationAnalytics
	RequestTypeEnableTemplatesAnalytics
	RequestTypeDisableButtonClickTracking
	RequestTypeBlockUsers
	RequestTypeUnblockUsers
	RequestTypeListBlockedUsers
	RequestTypeDisableWelcomeMessage
	RequestTypeEnableWelcomeMessage
	RequestTypeGetConversationAutomationComponents
	RequestTypeUpdateConversationAutomationComponents
	RequestTypeInitResumableUploadSession
	RequestTypeGetResumableUploadSessionStatus
	RequestTypePerformResumableUpload
	RequestTypeSetWABAAlternateCallbackURI
	RequestTypeGetWABAAlternateCallbackURI
	RequestTypeDeleteWABAAlternateCallbackURI
	RequestTypeSetPhoneNumberAlternateCallbackURI
	RequestTypeGetPhoneNumberAlternateCallbackURI
	RequestTypeDeletePhoneNumberAlternateCallbackURI
	RequestTypeGetSettings
	RequestTypeUpdateSettings
)

func (RequestType) Name

func (r RequestType) Name() string

func (RequestType) String

func (r RequestType) String() string

String returns the string representation of the request type.

type ResponseBodyReaderFunc

type ResponseBodyReaderFunc func(ctx context.Context, reader io.Reader) error

type ResponseDecoder

type ResponseDecoder interface {
	Decode(ctx context.Context, response *http.Response) error
}

type ResponseDecoderFunc

type ResponseDecoderFunc func(ctx context.Context, response *http.Response) error

func ResponseDecoderJSON

func ResponseDecoderJSON[T any](v *T, options DecodeOptions) ResponseDecoderFunc

func (ResponseDecoderFunc) Decode

func (decoder ResponseDecoderFunc) Decode(ctx context.Context, response *http.Response) error

type ResponseError

type ResponseError struct {
	Code int            `json:"code,omitempty"`
	Err  *werrors.Error `json:"error,omitempty"`
}

func (*ResponseError) Error

func (e *ResponseError) Error() string

func (*ResponseError) Unwrap

func (e *ResponseError) Unwrap() error

type ResponseInterceptor

type ResponseInterceptor interface {
	InterceptResponse(ctx context.Context, response *http.Response) error
}

type ResponseInterceptorFunc

type ResponseInterceptorFunc func(ctx context.Context, response *http.Response) error

func (ResponseInterceptorFunc) InterceptResponse

func (fn ResponseInterceptorFunc) InterceptResponse(ctx context.Context, response *http.Response) error

type Sender

type Sender[T any] interface {
	Send(ctx context.Context, request *Request[T], decoder ResponseDecoder) error
}

type SenderFunc

type SenderFunc[T any] func(ctx context.Context, request *Request[T], decoder ResponseDecoder) error

func SendFuncWithInterceptors

func SendFuncWithInterceptors[T any](client *http.Client, reqHook RequestInterceptorFunc,
	resHook ResponseInterceptorFunc,
) SenderFunc[T]

func (SenderFunc[T]) Send

func (fn SenderFunc[T]) Send(ctx context.Context, request *Request[T], decoder ResponseDecoder) error

Jump to

Keyboard shortcuts

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