Skip to content

CAMEL-25745: camel-http - make it stand out that a message with a body is sent as a POST unless httpMethod is set - #28041

Merged
davsclaus merged 2 commits into
mainfrom
fix/CAMEL-25745
Oct 18, 2026
Merged

davsclaus merged 2 commits into
mainfrom
fix/CAMEL-25745

Conversation

@davsclaus

@davsclaus davsclaus commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

CAMEL-25745: without the httpMethod option or the CamelHttpMethod header, the http producer picks the method from the message body: a message with a body is sent as a POST, a message without one as a GET. After unmarshal, split or setBody the message has a body, so a call meant as a GET is sent as a POST. This trips many users, and AI models too: in the overnight benchmark of Oct 17-18, a step that calls a stock service for each line of a split order failed 6 of 10 times on it. The behaviour cannot change without breaking existing applications, so this PR makes the rule stand out.

What

  • The http page opens its Usage section with "Which HTTP method will be used" (moved up from the middle of the page, with the same heading, so links to it keep working):
    • The rule as an IMPORTANT note, plus getWithBody.
    • The order in which the method is chosen.
    • Two examples in Java, XML and YAML: a GET for each line of a split order with httpMethod=GET, and a POST of JSON with httpMethod=POST.
    • camel_catalog_doc returns the start of a component's page, so the rule is now in every answer about http.
  • "How to set the http method" names the httpMethod option first, then the header.
  • The error for a body that is not a request body (CAMEL-25309, CAMEL-25749): when neither the option nor the header set the method, the BodyFacts message (what the body is, the step that set it, and the marshal that writes it) now says "The call is a POST because the message has a body and neither the httpMethod option nor the CamelHttpMethod header sets the method: for a GET, set httpMethod GET on the endpoint (a GET sends no body); for a POST, marshal it first ...". With an explicit method the message stays as on main.

The catalog copy of the page is updated.

Checks

  • The examples were run with camel run in all three DSLs, against a small stub: the stock lookup arrives as a GET with a Map body in the message, and the order arrives as a POST with JSON. The same split route without httpMethod fails with the Map body error, as in the benchmark.
  • HttpProducerMapBodyTest: the new test, and the explicit-POST test checks that the GET advice is left out. HttpMethodsTest passes.
  • All camel-http tests pass (297, 9 skipped, and 9 more).
  • Rebased on main after CAMEL-25749: camel-support - BodyFacts says what the body is, the step that set it, and what to write #28059 (BodyFacts): the GET/POST advice now sits on top of the BodyFacts message, and HttpProducerMapBodyTest passes again (4 tests).

🤖 Generated with Claude Code

https://claude.ai/code/session_01STT6whBgK1AqsSsUKrnE8m

@davsclaus davsclaus added this to the 4.24.0 milestone Oct 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@gnodet-bot gnodet-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM. Clean documentation enhancement and error-message improvement for the body-as-POST surprise in camel-http.

The mandatoryBodyStream static→instance refactor is safe (private method, single call site). The methodFromBody detection logic is correct — the new branch gives users targeted guidance based on whether the method was inferred from the body or set explicitly. Test coverage for both branches is solid.

One minor nit below (not a blocker).

This review was generated by an AI agent, Hermès on behalf of @gnodet.

Comment thread components/camel-http/src/main/docs/http-component.adoc Outdated
@github-actions

github-actions Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • catalog/camel-catalog
  • components/camel-http

ℹ️ Dependent modules were not tested because the total number of affected modules exceeded the threshold (50). Use the test-dependents label to force testing all dependents.


🔬 Scalpel shadow comparison — Scalpel: 76 of 706 tested, 26 compile-only — current: 76 all tested

Maveniverse Scalpel detected 76 affected modules (current approach: 76).

Skip-tests mode would test 76 modules (2 direct + 75 downstream), skip tests for 26 (generated code, meta-modules)

Modules Scalpel would test (76)
  • camel-a2a ← downstream of org.apache.camel:camel-vertx-http
  • camel-ai-observability ← downstream of org.apache.camel:camel-telemetry
  • camel-as2 ← downstream of org.apache.camel:camel-jetty
  • camel-clickup ← downstream of org.apache.camel:camel-netty-http
  • camel-consul ← downstream of org.apache.camel:camel-http
  • camel-cxf-rest ← downstream of org.apache.camel:camel-http
  • camel-cxf-soap ← downstream of org.apache.camel:camel-http
  • camel-cxf-spring-rest ← downstream of org.apache.camel:camel-http
  • camel-cxf-spring-soap ← downstream of org.apache.camel:camel-http
  • camel-cxf-spring-transport ← downstream of org.apache.camel:camel-cxf-transport
  • camel-cxf-transport ← downstream of org.apache.camel:camel-undertow
  • camel-graphql ← downstream of org.apache.camel:camel-http
  • camel-http ← components/camel-http/src/main/docs/http-component.adoc, components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java, components/camel-http/src/test/java/org/apache/camel/component/http/HttpProducerMapBodyTest.java
  • camel-java-joor-dsl ← downstream of org.apache.camel:camel-telegram
  • camel-jbang-mcp ← downstream of org.apache.camel:camel-catalog
  • camel-jbang-plugin-mcp ← downstream of org.apache.camel:camel-jbang-core
  • camel-jbang-plugin-tui ← downstream of org.apache.camel:camel-catalog
  • camel-jbang-plugin-validate ← downstream of org.apache.camel:camel-yaml-dsl-validator
  • camel-jetty ← downstream of org.apache.camel:camel-http
  • camel-jsonpath ← downstream of org.apache.camel:camel-platform-http-vertx
  • camel-kamelet ← downstream of org.apache.camel:camel-http
  • camel-knative-http ← downstream of org.apache.camel:camel-http
  • camel-kubernetes ← downstream of org.apache.camel:camel-http
  • camel-langchain4j-agent ← downstream of org.apache.camel:camel-telemetry
  • camel-langchain4j-chat ← downstream of org.apache.camel:camel-telemetry
  • camel-langchain4j-embeddings ← downstream of org.apache.camel:camel-telemetry
  • camel-langchain4j-embeddingstore ← downstream of org.apache.camel:camel-langchain4j-embeddings
  • camel-launcher-container ← downstream of org.apache.camel:camel-launcher
  • camel-lra ← downstream of org.apache.camel:camel-undertow
  • camel-mcp-server ← downstream of org.apache.camel:camel-platform-http-vertx
  • camel-micrometer-observability ← downstream of org.apache.camel:camel-undertow
  • camel-micrometer-prometheus ← downstream of org.apache.camel:camel-platform-http-main
  • camel-netty-http ← downstream of org.apache.camel:camel-http
  • camel-oauth ← downstream of org.apache.camel:camel-netty-http
  • camel-observability-services ← downstream of org.apache.camel:camel-opentelemetry2
  • camel-odata ← downstream of org.apache.camel:camel-http
  • camel-openai ← downstream of org.apache.camel:camel-platform-http-vertx
  • camel-openapi-validator ← downstream of org.apache.camel:camel-rest-openapi
  • camel-opentelemetry ← downstream of org.apache.camel:camel-undertow
  • camel-opentelemetry2 ← downstream of org.apache.camel:camel-undertow
  • camel-platform-http ← downstream of org.apache.camel:camel-http
  • camel-platform-http-jolokia ← downstream of org.apache.camel:camel-platform-http
  • camel-platform-http-main ← downstream of org.apache.camel:camel-platform-http-vertx
  • camel-platform-http-vertx ← downstream of org.apache.camel:camel-http
  • camel-quickfix ← downstream of org.apache.camel:camel-jetty
  • camel-rest-openapi ← downstream of org.apache.camel:camel-http
  • camel-rest-postman ← downstream of org.apache.camel:camel-http
  • camel-restdsl-openapi-plugin ← downstream of org.apache.camel:camel-jetty
  • camel-sap-netweaver ← downstream of org.apache.camel:camel-http
  • camel-semantic ← downstream of org.apache.camel:camel-xml-io-dsl
  • camel-semantic-openai ← downstream of org.apache.camel:camel-openai
  • camel-semantic-typesafe-ai ← downstream of org.apache.camel:camel-xml-io-dsl
  • camel-semantic-wolf-defender ← downstream of org.apache.camel:camel-semantic
  • camel-slack ← downstream of org.apache.camel:camel-undertow
  • camel-soap ← downstream of org.apache.camel:camel-cxf-soap
  • camel-spring-ai-chat ← downstream of org.apache.camel:camel-telemetry
  • camel-spring-rabbitmq ← downstream of org.apache.camel:camel-http
  • camel-state-store ← downstream of org.apache.camel:camel-test-main-junit5
  • camel-telegram ← downstream of org.apache.camel:camel-netty-http
  • camel-telemetry ← downstream of org.apache.camel:camel-undertow
  • camel-telemetry-dev ← downstream of org.apache.camel:camel-undertow
  • camel-test-main-junit5 ← downstream of org.apache.camel:camel-xml-io-dsl
  • camel-test-main-junit6 ← downstream of org.apache.camel:camel-xml-io-dsl
  • camel-typesafe-ai ← downstream of org.apache.camel:camel-xml-io-dsl
  • camel-undertow ← downstream of org.apache.camel:camel-http
  • camel-undertow-spring-security ← downstream of org.apache.camel:camel-undertow
  • camel-vertx-http ← downstream of org.apache.camel:camel-http
  • camel-webhook ← downstream of org.apache.camel:camel-netty-http
  • camel-whatsapp ← downstream of org.apache.camel:camel-netty-http
  • camel-xml-io-dsl ← downstream of org.apache.camel:camel-kamelet
  • camel-xml-jaxb-dsl ← downstream of org.apache.camel:camel-telegram
  • camel-xml-jaxb-dsl-test-definition ← downstream of org.apache.camel:camel-telegram
  • camel-xml-jaxb-dsl-test-spring ← downstream of org.apache.camel:camel-telegram
  • camel-yaml-dsl-validator ← downstream of org.apache.camel:camel-catalog
  • camel-yaml-dsl-validator-maven-plugin ← downstream of org.apache.camel:camel-yaml-dsl-validator
  • camel-zookeeper ← downstream of org.apache.camel:camel-http
Modules with tests skipped (26)
  • apache-camel
  • camel-allcomponents
  • camel-catalog-console
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

Build reactor — dependencies compiled but only changed modules were tested (2 modules, 20.3s total)

Total reactor time: 20.3s

Module Duration Status
Camel :: Catalog :: Camel Catalog 20.3s SUCCESS
Camel :: HTTP n/a

Top 20 slowest modules:

  • Camel :: Catalog :: Camel Catalog (20.3s)

⚙️ View full build and test results

davsclaus and others added 2 commits October 18, 2026 18:08
…y is sent as a POST unless httpMethod is set

The http page opens its Usage section with which HTTP method is used: the
rule, the trap after unmarshal, split or setBody, the fix (httpMethod GET;
a GET sends no body unless getWithBody is true), the order, and examples
in Java, XML and YAML. camel_catalog_doc returns the start of the page, so
the rule is in its answers too. How to set the http method names the
option first, and its YAML example is canonical.

The error for a Map or List body says, when neither the option nor the
header set the method, that the call is a POST because the message has a
body, and how to make it a GET.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STT6whBgK1AqsSsUKrnE8m
…other examples on the page

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STT6whBgK1AqsSsUKrnE8m

@gnodet-bot gnodet-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Previous findings are all addressed. LGTM.

The nit on the YAML setHeader compact form — ✅ addressed in both .adoc copies (commit dd81ea07).

The static → instance change on mandatoryBodyStream is safe (private method, single call site). The error-message branching correctly mirrors the actual POST-by-body decision in HttpProducer — the new hint fires only when neither httpMethod nor CamelHttpMethod is set, which is exactly the ambiguous case (CAMEL-25745). Both branches have test coverage.

This review was generated by an AI agent, Hermès on behalf of @gnodet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants