Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,41 +44,52 @@
import static com.predic8.membrane.core.util.text.StringUtil.maskNonPrintableCharacters;

/**
* @description <p>API proxy with several routing options.</p>
* <p>Multiple APIs on the same port are discriminated by host, path, or a <code>test</code>
* expression. Incoming requests are probed from the top API to the bottom. The first API that
* matches the request will process it.</p>
* <b>OpenAPI Support</b>
* <p>When <code>openapi</code> children are present, Membrane auto-wires a publisher at
* <code>/api-docs</code> and an OpenAPI rewriter; see <code>tutorials/getting-started/80-OpenAPI.yaml</code>
* and <code>tutorials/getting-started/90-OpenAPI-Validation.yaml</code>.</p>
* @description <p>The main API configuration. Extends <code>serviceProxy</code> with REST and OpenAPI
* support and expression-based routing.</p>
* <p>Several APIs can share one port and are told apart by host, path, or a <code>test</code>
* expression. Incoming requests are probed from the first API to the last; the first one that matches
* handles the request.</p>
* <p>When <code>openapi</code> children are present, Membrane deploys the described API: it publishes
* the specifications at <code>/api-docs</code> and routes to the target from the OpenAPI
* <code>servers</code> field. See <code>tutorials/getting-started/80-OpenAPI.yaml</code> and
* <code>tutorials/getting-started/90-OpenAPI-Validation.yaml</code>.</p>
Comment on lines +52 to +55

@coderabbitai coderabbitai Bot Jul 8, 2026

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Mention the explicit target fallback in the OpenAPI summary.

The class Javadoc says OpenAPI APIs route from the document servers field, but runtime routing prefers an explicit target element and only falls back to servers when no target is configured. Please make that caveat explicit so the docs match behavior.

Proposed wording
- * specifications at <code>/api-docs</code> and routes to the target from the OpenAPI
- * <code>servers</code> field.
+ * specifications at <code>/api-docs</code> and routes using an explicit <code>target</code>
+ * when present, otherwise the OpenAPI <code>servers</code> field.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* <p>When <code>openapi</code> children are present, Membrane deploys the described API: it publishes
* the specifications at <code>/api-docs</code> and routes to the target from the OpenAPI
* <code>servers</code> field. See <code>tutorials/getting-started/80-OpenAPI.yaml</code> and
* <code>tutorials/getting-started/90-OpenAPI-Validation.yaml</code>.</p>
* <p>When <code>openapi</code> children are present, Membrane deploys the described API: it publishes
* the specifications at <code>/api-docs</code> and routes using an explicit <code>target</code>
* when present, otherwise the OpenAPI <code>servers</code> field. See <code>tutorials/getting-started/80-OpenAPI.yaml</code> and
* <code>tutorials/getting-started/90-OpenAPI-Validation.yaml</code>.</p>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxy.java`
around lines 52 - 55, Update the Javadoc summary in APIProxy so it matches the
routing behavior: clarify that OpenAPI deployments route to an explicit target
when present, and only fall back to the OpenAPI servers field if no target is
configured. Keep the existing references to openapi children and /api-docs, but
adjust the wording around the target/servers behavior so the documentation is
accurate.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

!

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.

@rrayst Could you clarify your comment? Not sure if you meant to express agreement, disagreement, or something else regarding the suggested Javadoc wording about target vs servers fallback. Happy to adjust the wording or drop the suggestion if it doesn't apply here.

(・_・)?

*
* @topic 1. Proxies and Flow
* @yaml <pre><code>
*
* # Basic path routing
* api:
* port: 2000
* path:
* uri: /orders/{id}
* uri: /products
* target:
* url: https://api.predic8.de/shop/orders/{pathParam.id}
* url: https://api.predic8.de
*
* ---
* # URI template routing
* api:
* port: 2000
* path:
* uri: /orders/
* uri: /orders/{id}
* target:
* url: https://api.predic8.de
* url: https://api.predic8.de/shop/orders/{pathParam.id}
*
* ---
* # Custom routing with expression
* api:
* port: 2000
* test: header.SOAPAction == 'https://predic8.de/city-service/get'
* target:
* url: https://api.predic8.de
* url: https://api.predic8.de/city-service
*
* ---
* # OpenAPI support
* api:
* port: 2000
* openapi:
* - location: openapi/fruitshop-api.yaml
* validateRequests: true
* validateResponses: true
* </code></pre>
*/
@MCElement(name = "api", topLevel = true, component = false)
Expand Down Expand Up @@ -113,7 +124,8 @@ public List<OpenAPISpec> getOpenapi() {
}

/**
* @description Deploys an API from an OpenAPI document.
* @description Deploys the API described by an OpenAPI document: the document is published under
* <code>/api-docs</code> and, when configured, requests and responses are validated against it.
*/
@MCChildElement(order = 25)
public void setOpenapi(List<OpenAPISpec> specs) {
Expand Down Expand Up @@ -269,6 +281,11 @@ public String getTest() {
return test;
}

/**
* @description Expression evaluated against each request; the API matches only when it returns
* true. Used to discriminate APIs on the same port beyond host and path, e.g. by header or method.
* @example header.SOAPAction == 'https://predic8.de/city-service/get'
*/
@MCAttribute
public void setTest(String test) {
this.test = test;
Expand All @@ -282,16 +299,28 @@ public ApiDescription getDescription() {
return description;
}

/**
* @description Identifier for this API. Overrides the auto-generated entry id used for this API
* in the published <code>apis.json</code> catalog; otherwise an id is derived from the API's key.
* @example order-api
*/
@MCAttribute
public void setId(String id) {
this.id = id;
}

/**
* @description Human-readable description of the API.
*/
@MCChildElement
public void setDescription(ApiDescription description) {
this.description = description;
}

/**
* @description Expression language used to evaluate the <code>test</code> attribute.
* @default SpEL
*/
@MCAttribute
@Override
public void setLanguage(Language language) {
Expand All @@ -313,8 +342,8 @@ public String getContent() {
}

/**
* XML Configuration e.g. declaration of XML namespaces for XPath expressions, ...
* @param xmlConfig
* @description XML configuration for the API, such as namespace declarations used by XPath
* expressions.
*/
@MCChildElement(allowForeign = true,order = 10)
public void setXmlConfig(XmlConfig xmlConfig) {
Expand Down
Loading