fork of indigo with slightly nicer lexgen

api client: do JSON unmarshaling in Get and Post

Changed files
+23 -17
atproto
client
+23 -17
atproto/client/api_client.go
··· 20 20 // High-level helper for simple JSON "Query" API calls. 21 21 // 22 22 // Does not work with all API endpoints. For more control, use the Do() method with APIRequest. 23 - func (c *APIClient) Get(ctx context.Context, endpoint syntax.NSID, params map[string]string) (*json.RawMessage, error) { 23 + func (c *APIClient) Get(ctx context.Context, endpoint syntax.NSID, params map[string]string, out any) error { 24 24 hdr := map[string]string{ 25 25 "Accept": "application/json", 26 26 } ··· 33 33 } 34 34 resp, err := c.Do(ctx, req) 35 35 if err != nil { 36 - return nil, err 36 + return err 37 37 } 38 38 39 39 defer resp.Body.Close() ··· 41 41 if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { 42 42 var eb ErrorBody 43 43 if err := json.NewDecoder(resp.Body).Decode(&eb); err != nil { 44 - return nil, &APIError{StatusCode: resp.StatusCode} 44 + return &APIError{StatusCode: resp.StatusCode} 45 45 } 46 - return nil, eb.APIError(resp.StatusCode) 46 + return eb.APIError(resp.StatusCode) 47 47 } 48 48 49 - var ret json.RawMessage 50 - if err := json.NewDecoder(resp.Body).Decode(&ret); err != nil { 51 - return nil, fmt.Errorf("expected JSON response body: %w", err) 49 + if out == nil { 50 + return nil 52 51 } 53 - return &ret, nil 52 + 53 + if err := json.NewDecoder(resp.Body).Decode(out); err != nil { 54 + return fmt.Errorf("failed decoding JSON response body: %w", err) 55 + } 56 + return nil 54 57 } 55 58 56 59 // High-level helper for simple JSON-to-JSON "Procedure" API calls. 57 60 // 58 61 // Does not work with all API endpoints. For more control, use the Do() method with APIRequest. 59 - func (c *APIClient) Post(ctx context.Context, endpoint syntax.NSID, body any) (*json.RawMessage, error) { 62 + func (c *APIClient) Post(ctx context.Context, endpoint syntax.NSID, body any, out any) error { 60 63 bodyJSON, err := json.Marshal(body) 61 64 if err != nil { 62 - return nil, err 65 + return err 63 66 } 64 67 hdr := map[string]string{ 65 68 "Accept": "application/json", ··· 74 77 } 75 78 resp, err := c.Do(ctx, req) 76 79 if err != nil { 77 - return nil, err 80 + return err 78 81 } 79 82 80 83 defer resp.Body.Close() ··· 82 85 if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { 83 86 var eb ErrorBody 84 87 if err := json.NewDecoder(resp.Body).Decode(&eb); err != nil { 85 - return nil, &APIError{StatusCode: resp.StatusCode} 88 + return &APIError{StatusCode: resp.StatusCode} 86 89 } 87 - return nil, eb.APIError(resp.StatusCode) 90 + return eb.APIError(resp.StatusCode) 88 91 } 89 92 90 - var ret json.RawMessage 91 - if err := json.NewDecoder(resp.Body).Decode(&ret); err != nil { 92 - return nil, fmt.Errorf("expected JSON response body: %w", err) 93 + if out == nil { 94 + return nil 93 95 } 94 - return &ret, nil 96 + 97 + if err := json.NewDecoder(resp.Body).Decode(out); err != nil { 98 + return fmt.Errorf("failed decoding JSON response body: %w", err) 99 + } 100 + return nil 95 101 } 96 102 97 103 // Full-power method for atproto API requests.