|
- package helpers
-
- import (
- "bytes"
- "encoding/json"
- "fmt"
- "io"
- "net/http"
- "net/http/cookiejar"
- "strings"
- "time"
-
- "github.com/QuantumNous/new-api/common"
- )
-
- type APIClient struct {
- BaseURL string
- UserID int
- client *http.Client
- }
-
- func NewAPIClient(baseURL string) (*APIClient, error) {
- jar, err := cookiejar.New(nil)
- if err != nil {
- return nil, fmt.Errorf("create cookie jar: %w", err)
- }
- return &APIClient{
- BaseURL: strings.TrimRight(baseURL, "/"),
- client: &http.Client{
- Jar: jar,
- Timeout: 15 * time.Second,
- },
- }, nil
- }
-
- func (c *APIClient) DoJSON(method, path string, requestBody any, expectedStatus int, responseBody any) error {
- return c.DoJSONWithHeaders(method, path, requestBody, expectedStatus, nil, responseBody)
- }
-
- func (c *APIClient) DoJSONWithHeaders(method, path string, requestBody any, expectedStatus int, headers map[string]string, responseBody any) error {
- var bodyReader io.Reader
- var requestDump string
- if requestBody != nil {
- data, err := common.Marshal(requestBody)
- if err != nil {
- return fmt.Errorf("marshal request body for %s %s: %w", method, path, err)
- }
- bodyReader = bytes.NewReader(data)
- requestDump = string(data)
- }
-
- req, err := http.NewRequest(method, c.BaseURL+path, bodyReader)
- if err != nil {
- return fmt.Errorf("create request %s %s: %w", method, path, err)
- }
- req.Header.Set("Accept", "application/json")
- if requestBody != nil {
- req.Header.Set("Content-Type", "application/json")
- }
- if c.UserID != 0 {
- req.Header.Set("New-Api-User", fmt.Sprintf("%d", c.UserID))
- }
- for key, value := range headers {
- req.Header.Set(key, value)
- }
-
- resp, err := c.client.Do(req)
- if err != nil {
- return fmt.Errorf("do request %s %s: %w", method, path, err)
- }
- defer resp.Body.Close()
-
- respData, err := io.ReadAll(resp.Body)
- if err != nil {
- return fmt.Errorf("read response %s %s: %w", method, path, err)
- }
-
- if resp.StatusCode != expectedStatus {
- return fmt.Errorf(
- "%s %s: expected status %d, got %d, request=%s, response=%s",
- method, path, expectedStatus, resp.StatusCode, requestDump, string(respData),
- )
- }
-
- if responseBody == nil || len(respData) == 0 {
- return nil
- }
-
- if err := common.Unmarshal(respData, responseBody); err != nil {
- return fmt.Errorf(
- "unmarshal response for %s %s: %w, raw=%s",
- method, path, err, string(respData),
- )
- }
- return nil
- }
-
- func (c *APIClient) GetJSON(path string, expectedStatus int, responseBody any) error {
- return c.DoJSON(http.MethodGet, path, nil, expectedStatus, responseBody)
- }
-
- func (c *APIClient) PostJSON(path string, requestBody any, expectedStatus int, responseBody any) error {
- return c.DoJSON(http.MethodPost, path, requestBody, expectedStatus, responseBody)
- }
-
- func (c *APIClient) PutJSON(path string, requestBody any, expectedStatus int, responseBody any) error {
- return c.DoJSON(http.MethodPut, path, requestBody, expectedStatus, responseBody)
- }
-
- func (c *APIClient) DeleteJSON(path string, expectedStatus int, responseBody any) error {
- return c.DoJSON(http.MethodDelete, path, nil, expectedStatus, responseBody)
- }
-
- type Envelope struct {
- Success bool `json:"success"`
- Message string `json:"message,omitempty"`
- Error string `json:"error,omitempty"`
- Data json.RawMessage `json:"data,omitempty"`
- }
|