// Package {{packageName}} provides a client for the {{info.title}} API
// Generated by MicroRapid
package {{packageName}}
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strings"
"time"
)
// Client is the main API client for {{info.title}}
type Client struct {
baseURL string
httpClient *http.Client
{{#if includeAuth}}
config *Config
{{/if}}
}
// NewClient creates a new API client
func NewClient(config *Config) *Client {
if config == nil {
config = &Config{}
}
baseURL := config.BaseURL
if baseURL == "" {
baseURL = "{{baseUrl}}"
}
httpClient := &http.Client{
Timeout: config.Timeout,
}
{{#if includeResilience}}
if config.MaxRetries > 0 {
httpClient.Transport = &retryTransport{
underlying: http.DefaultTransport,
maxRetries: config.MaxRetries,
retryDelay: config.RetryDelay,
}
}
{{/if}}
return &Client{
baseURL: baseURL,
httpClient: httpClient,
{{#if includeAuth}}
config: config,
{{/if}}
}
}
// request makes an HTTP request
func (c *Client) request(ctx context.Context, method, path string, query url.Values, body interface{}) ([]byte, error) {
u, err := url.Parse(c.baseURL + path)
if err != nil {
return nil, err
}
if query != nil {
u.RawQuery = query.Encode()
}
var bodyReader io.Reader
if body != nil {
jsonBody, err := json.Marshal(body)
if err != nil {
return nil, err
}
bodyReader = bytes.NewReader(jsonBody)
}
req, err := http.NewRequestWithContext(ctx, method, u.String(), bodyReader)
if err != nil {
return nil, err
}
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
req.Header.Set("Accept", "application/json")
{{#if includeAuth}}
// Add authentication headers
if c.config.BearerToken != "" {
req.Header.Set("Authorization", "Bearer " + c.config.BearerToken)
} else if c.config.APIKey != "" {
req.Header.Set("X-API-Key", c.config.APIKey)
}
{{/if}}
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode >= 400 {
var apiErr APIError
apiErr.StatusCode = resp.StatusCode
apiErr.Message = string(respBody)
return nil, &apiErr
}
return respBody, nil
}
{{#each operations}}
// {{operation_id}} {{#if summary}}{{summary}}{{/if}}
func (c *Client) {{operation_id}}(ctx context.Context{{#each parameters}}, {{name}} string{{/each}}{{#if requestBody}}, body interface{}{{/if}}) (interface{}, error) {
{{#if parameters}}
query := url.Values{}
{{#each parameters}}
// Add query parameters
if {{name}} != "" {
query.Set("{{name}}", {{name}})
}
{{/each}}
{{/if}}
path := "{{path}}"
{{#each parameters}}
// Replace path parameters
path = strings.ReplaceAll(path, "{{{name}}}", {{name}})
{{/each}}
respBody, err := c.request(ctx, "{{method}}", path, {{#if parameters}}query{{else}}nil{{/if}}, {{#if requestBody}}body{{else}}nil{{/if}})
if err != nil {
return nil, err
}
var result interface{}
if err := json.Unmarshal(respBody, &result); err != nil {
return nil, err
}
return result, nil
}
{{/each}}
{{#if includeResilience}}
// retryTransport implements automatic retry logic
type retryTransport struct {
underlying http.RoundTripper
maxRetries int
retryDelay time.Duration
}
func (t *retryTransport) RoundTrip(req *http.Request) (*http.Response, error) {
var resp *http.Response
var err error
for i := 0; i <= t.maxRetries; i++ {
resp, err = t.underlying.RoundTrip(req)
if err == nil && resp.StatusCode < 500 {
return resp, nil
}
if i < t.maxRetries {
time.Sleep(t.retryDelay * time.Duration(i+1))
}
}
return resp, err
}
{{/if}}