updated slapapi
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
package slapshotapi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -14,31 +16,101 @@ type endpoint interface {
|
||||
method() string
|
||||
}
|
||||
|
||||
// bodyEndpoint is an optional interface for endpoints that send a JSON body
|
||||
type bodyEndpoint interface {
|
||||
endpoint
|
||||
body() ([]byte, error)
|
||||
}
|
||||
|
||||
func (c *SlapAPI) request(
|
||||
ctx context.Context,
|
||||
ep endpoint,
|
||||
) ([]byte, error) {
|
||||
baseurl := fmt.Sprintf("https://%s.slapshot.gg%s", c.env, ep.path())
|
||||
req, err := http.NewRequest(ep.method(), baseurl, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "http.NewRequest")
|
||||
|
||||
var bodyReader io.Reader
|
||||
if bep, ok := ep.(bodyEndpoint); ok {
|
||||
data, err := bep.body()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "endpoint.body")
|
||||
}
|
||||
bodyReader = bytes.NewReader(data)
|
||||
}
|
||||
req.Header.Add("accept", "application/json")
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, ep.method(), baseurl, bodyReader)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "http.NewRequestWithContext")
|
||||
}
|
||||
req.Header.Add("Accept", "application/json")
|
||||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", c.key))
|
||||
if bodyReader != nil {
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
res, err := c.do(ctx, req)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "http.DefaultClient.Do")
|
||||
return nil, errors.Wrap(err, "c.do")
|
||||
}
|
||||
if res.StatusCode != 200 {
|
||||
return nil, errors.New(fmt.Sprintf("Error making request: %v", res.StatusCode))
|
||||
defer func() { _ = res.Body.Close() }()
|
||||
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil, errors.New(fmt.Sprintf("API request failed with status %d", res.StatusCode))
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "io.ReadAll")
|
||||
}
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "resp.Body.Close")
|
||||
}
|
||||
return body, nil
|
||||
}
|
||||
|
||||
// requestRaw performs an API request and returns the raw status code and body.
|
||||
// This is used for endpoints where non-200 status codes carry meaningful data
|
||||
// (e.g. DELETE returning a plain text response).
|
||||
func (c *SlapAPI) requestRaw(
|
||||
ctx context.Context,
|
||||
ep endpoint,
|
||||
) (int, []byte, error) {
|
||||
baseurl := fmt.Sprintf("https://%s.slapshot.gg%s", c.env, ep.path())
|
||||
|
||||
var bodyReader io.Reader
|
||||
if bep, ok := ep.(bodyEndpoint); ok {
|
||||
data, err := bep.body()
|
||||
if err != nil {
|
||||
return 0, nil, errors.Wrap(err, "endpoint.body")
|
||||
}
|
||||
bodyReader = bytes.NewReader(data)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, ep.method(), baseurl, bodyReader)
|
||||
if err != nil {
|
||||
return 0, nil, errors.Wrap(err, "http.NewRequestWithContext")
|
||||
}
|
||||
req.Header.Add("Accept", "application/json")
|
||||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", c.key))
|
||||
if bodyReader != nil {
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
res, err := c.do(ctx, req)
|
||||
if err != nil {
|
||||
return 0, nil, errors.Wrap(err, "c.do")
|
||||
}
|
||||
defer func() { _ = res.Body.Close() }()
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return 0, nil, errors.Wrap(err, "io.ReadAll")
|
||||
}
|
||||
return res.StatusCode, body, nil
|
||||
}
|
||||
|
||||
// unmarshal is a helper that unmarshals JSON response data into a target struct
|
||||
func unmarshal[T any](data []byte) (*T, error) {
|
||||
var result T
|
||||
err := json.Unmarshal(data, &result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "json.Unmarshal")
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user