package api_gen import ( "bytes" "go/format" "os" "path/filepath" "text/template" ) func generateClient(outputDir string, pkg *APIPackage) error { tmpl := `// Code generated by api_gen. DO NOT EDIT. package client import ( "bytes" "context" "encoding/json" "fmt" "io" "net/http" "time" "{{ .PkgPath }}" ) type Client struct { BaseURL string Client *http.Client } func NewClient(baseURL string) *Client { return &Client{ BaseURL: baseURL, Client: &http.Client{Timeout: 30 * time.Second}, } } {{ $ := . }} {{ range .Endpoints }} func (c *Client) {{.Name}}(ctx context.Context, req *{{ $.PkgName }}.{{.ReqType}}) (*{{ $.PkgName }}.{{.ResType}}, error) { reqBody, err := json.Marshal(req) if err != nil { return nil, fmt.Errorf("failed to marshal request: %w", err) } httpReq, err := http.NewRequestWithContext(ctx, "{{.Method}}", c.BaseURL+"{{.Path}}", bytes.NewBuffer(reqBody)) if err != nil { return nil, fmt.Errorf("failed to create request: %w", err) } httpReq.Header.Set("Content-Type", "application/json") resp, err := c.Client.Do(httpReq) if err != nil { return nil, fmt.Errorf("failed to execute request: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) return nil, fmt.Errorf("request failed with status %d: %s", resp.StatusCode, string(body)) } var res {{ $.PkgName }}.{{.ResType}} if err := json.NewDecoder(resp.Body).Decode(&res); err != nil { return nil, fmt.Errorf("failed to decode response: %w", err) } return &res, nil } {{ end }} ` tmplObj := template.Must(template.New("client").Parse(tmpl)) var buf bytes.Buffer if err := tmplObj.Execute(&buf, pkg); err != nil { return err } unformatted := buf.Bytes() formatted, err := format.Source(unformatted) if err != nil { return err } return os.WriteFile(filepath.Join(outputDir, "client.go"), formatted, 0644) }