mirror of
https://github.com/IBM/fp-go.git
synced 2025-06-23 00:27:49 +02:00
79 lines
1.9 KiB
Go
79 lines
1.9 KiB
Go
![]() |
package http
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"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"
|
||
|
IOE "github.com/ibm/fp-go/ioeither"
|
||
|
IOEF "github.com/ibm/fp-go/ioeither/file"
|
||
|
J "github.com/ibm/fp-go/json"
|
||
|
)
|
||
|
|
||
|
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)}
|
||
|
}
|
||
|
|
||
|
// ReadAll sends a request and reads the response as a byte array
|
||
|
func ReadAll(client Client) func(Requester) RIOE.ReaderIOEither[[]byte] {
|
||
|
return func(req Requester) RIOE.ReaderIOEither[[]byte] {
|
||
|
doReq := client.Do(req)
|
||
|
return func(ctx context.Context) IOE.IOEither[error, []byte] {
|
||
|
return IOEF.ReadAll(F.Pipe2(
|
||
|
ctx,
|
||
|
doReq,
|
||
|
IOE.Map[error](func(resp *http.Response) io.ReadCloser {
|
||
|
return resp.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.Flow2(
|
||
|
ReadAll(client),
|
||
|
RIOE.ChainEitherK(J.Unmarshal[A]),
|
||
|
)
|
||
|
}
|