mrapids 0.1.7

Your OpenAPI, but executable
Documentation
// 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}}