1
0
mirror of https://github.com/IBM/fp-go.git synced 2025-06-23 00:27:49 +02:00
Files
fp-go/context/readerioeither/http/request.go

99 lines
2.5 KiB
Go
Raw Normal View History

package http
import (
"io"
"net/http"
B "github.com/ibm/fp-go/bytes"
RIOE "github.com/ibm/fp-go/context/readerioeither"
F "github.com/ibm/fp-go/function"
H "github.com/ibm/fp-go/http"
IOE "github.com/ibm/fp-go/ioeither"
IOEF "github.com/ibm/fp-go/ioeither/file"
J "github.com/ibm/fp-go/json"
T "github.com/ibm/fp-go/tuple"
)
type (
// Requester is a reader that constructs a request
Requester = RIOE.ReaderIOEither[*http.Request]
Client interface {
// Do can send an HTTP request considering a context
Do(Requester) RIOE.ReaderIOEither[*http.Response]
}
client struct {
delegate *http.Client
doIOE func(*http.Request) IOE.IOEither[error, *http.Response]
}
)
var (
NewRequest = RIOE.Eitherize3(http.NewRequestWithContext)
)
func (client client) Do(req Requester) RIOE.ReaderIOEither[*http.Response] {
return F.Pipe1(
req,
RIOE.ChainIOEitherK(client.doIOE),
)
}
// MakeClient creates an HTTP client proxy
func MakeClient(httpClient *http.Client) Client {
return client{delegate: httpClient, doIOE: IOE.Eitherize1(httpClient.Do)}
}
// ReadFullResponse sends a request, reads the response as a byte array and represents the result as a tuple
func ReadFullResponse(client Client) func(Requester) RIOE.ReaderIOEither[H.FullResponse] {
return func(req Requester) RIOE.ReaderIOEither[H.FullResponse] {
return F.Flow3(
client.Do(req),
IOE.ChainEitherK(H.ValidateResponse),
IOE.Chain(func(resp *http.Response) IOE.IOEither[error, H.FullResponse] {
return F.Pipe1(
F.Pipe3(
resp,
H.GetBody,
IOE.Of[error, io.ReadCloser],
IOEF.ReadAll[io.ReadCloser],
),
IOE.Map[error](F.Bind1st(T.MakeTuple2[*http.Response, []byte], resp)),
)
}),
)
}
}
// ReadAll sends a request and reads the response as bytes
func ReadAll(client Client) func(Requester) RIOE.ReaderIOEither[[]byte] {
return F.Flow2(
ReadFullResponse(client),
RIOE.Map(H.Body),
)
}
// ReadText sends a request, reads the response and represents the response as a text string
func ReadText(client Client) func(Requester) RIOE.ReaderIOEither[string] {
return F.Flow2(
ReadAll(client),
RIOE.Map(B.ToString),
)
}
// ReadJson sends a request, reads the response and parses the response as JSON
func ReadJson[A any](client Client) func(Requester) RIOE.ReaderIOEither[A] {
return F.Flow3(
ReadFullResponse(client),
RIOE.ChainFirstEitherK(F.Flow2(
H.Response,
H.ValidateJsonResponse,
)),
RIOE.ChainEitherK(F.Flow2(
H.Body,
J.Unmarshal[A],
)),
)
}