Skip to content

Fix JSON body conversion for array types in HTTP requests#159

Merged
linyows merged 2 commits intomainfrom
fix-json-body-array-conversion
Jan 27, 2026
Merged

Fix JSON body conversion for array types in HTTP requests#159
linyows merged 2 commits intomainfrom
fix-json-body-array-conversion

Conversation

@linyows
Copy link
Owner

@linyows linyows commented Jan 27, 2026

Summary

  • Support []any body type for JSON conversion (previously only map[string]any was supported)
  • Handle all header map types: map[string]any, map[string]string, map[string]interface{}
  • Use case-insensitive Content-Type header matching (content-type and Content-Type both work)

Test plan

  • Add comprehensive tests for JSON body conversion (TestRequestBodyJSONConversion)
  • Verify array body is correctly serialized to JSON
  • Verify different header map types are handled
  • Verify case-insensitive Content-Type matching
  • Verify string body is not double-converted
  • Verify non-JSON content-type does not trigger conversion

🤖 Generated with Claude Code

Previously, only map[string]any body was converted to JSON string when
Content-Type was application/json. This caused 400 errors when sending
array bodies (e.g., Mackerel API metrics).

Changes:
- Support []any body type for JSON conversion
- Handle all header map types: map[string]any, map[string]string, map[string]interface{}
- Use case-insensitive Content-Type header matching
- Add comprehensive tests for JSON body conversion

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Extract hasJSONContentType() and MarshalBodyIfJSON() from Request()
to improve code readability and maintainability.

Add unit tests for hasJSONContentType() and MarshalBodyIfJSON().

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions
Copy link

Code Metrics Report

main (3b12b21) #159 (e94546d) +/-
Coverage 55.3% 56.0% +0.6%
Code to Test Ratio 1:1.0 1:1.0 +0.0
Test Execution Time 1m22s 22s -1m0s
Details
  |                     | main (3b12b21) | #159 (e94546d) |  +/-  |
  |---------------------|----------------|----------------|-------|
+ | Coverage            |          55.3% |          56.0% | +0.6% |
  |   Files             |             65 |             65 |     0 |
  |   Lines             |           6563 |           6578 |   +15 |
+ |   Covered           |           3633 |           3684 |   +51 |
+ | Code to Test Ratio  |          1:1.0 |          1:1.0 |  +0.0 |
  |   Code              |          12892 |          12892 |     0 |
+ |   Test              |          13267 |          13269 |    +2 |
+ | Test Execution Time |          1m22s |            22s | -1m0s |

Code coverage of files in pull request scope (53.3% → 82.0%)

Files Coverage +/- Status
http/client.go 82.0% +28.6% modified

Reported by octocov

@github-actions
Copy link

Code Metrics Report

main (3b12b21) #159 (e94546d) +/-
Coverage 55.3% 56.0% +0.6%
Code to Test Ratio 1:1.0 1:1.0 +0.0
Test Execution Time 1m22s 22s -1m0s
Details
  |                     | main (3b12b21) | #159 (e94546d) |  +/-  |
  |---------------------|----------------|----------------|-------|
+ | Coverage            |          55.3% |          56.0% | +0.6% |
  |   Files             |             65 |             65 |     0 |
  |   Lines             |           6563 |           6578 |   +15 |
+ |   Covered           |           3633 |           3685 |   +52 |
+ | Code to Test Ratio  |          1:1.0 |          1:1.0 |  +0.0 |
  |   Code              |          12892 |          12892 |     0 |
+ |   Test              |          13267 |          13269 |    +2 |
+ | Test Execution Time |          1m22s |            22s | -1m0s |

Code coverage of files in pull request scope (60.9% → 78.6%)

Files Coverage +/- Status
http/client.go 82.0% +28.6% modified
mail/mock_server.go 73.1% +1.0% affected

Reported by octocov

@linyows linyows requested a review from Copilot January 27, 2026 08:32
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances JSON body handling in HTTP requests by supporting array types and improving header type flexibility. Previously, only map[string]any bodies could be converted to JSON; now []any is also supported. The implementation adds case-insensitive Content-Type header matching and handles multiple header map types.

Changes:

  • Added support for []any body type in JSON conversion (previously only map[string]any)
  • Implemented case-insensitive Content-Type header matching
  • Added handling for multiple header map types: map[string]any, map[string]string, map[string]interface{}

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
http/client.go Refactored JSON body conversion into separate functions (hasJSONContentType, MarshalBodyIfJSON) and added support for array bodies and multiple header map types
http/client_test.go Added comprehensive test coverage for JSON body conversion including array bodies, various header map types, and case-insensitive Content-Type matching

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}

switch h := headers.(type) {
case map[string]any: // also matches map[string]interface{}
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is misleading. In Go, map[string]any and map[string]interface{} are identical at compile time (since any is an alias for interface{}), but the type switch will only match the exact type used in the code. If a caller passes a variable explicitly typed as map[string]interface{}, this case won't match it. The separate handling in the Request function (lines with headersInterfaceMap) confirms they need to be handled as distinct types in practice.

Suggested change
case map[string]any: // also matches map[string]interface{}
case map[string]any: // headers map with arbitrary value types ('any' is alias of interface{})

Copilot uses AI. Check for mistakes.
"headers": map[string]any{"content-type": "application/json"},
"body": `{"already":"json"}`,
},
expectedBody: nil, // not modified
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment 'not modified' is ambiguous. It would be clearer to state 'body should not be set in output map' to match the actual test expectation being verified.

Copilot uses AI. Check for mistakes.
@linyows linyows merged commit 81a3499 into main Jan 27, 2026
7 of 9 checks passed
@linyows linyows deleted the fix-json-body-array-conversion branch January 27, 2026 14:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants