【发布时间】:2017-06-29 10:44:36
【问题描述】:
我一直在试图弄清楚如何让 WSO2 的 ESB 调用两个不同的 API,并将它们的结果组合成一个响应,结果却遇到了麻烦。在最基本的情况下,我有两个后端请求响应如下:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<response xmlns="http://example.com/response">
<query name="items" xmlns="http://example.com/query">
<row>
<id>1</id>
<name>Item 1</name>
</row>
<row>
<id>2</id>
<name>Item 2</name>
</row>
</query>
</response>
</soapenv:Body>
</soapenv:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<response xmlns="http://example.com/response">
<query name="parts" xmlns="http://example.com/query">
<row>
<id>1</id>
<part>Part 1.1</part>
</row>
<row>
<id>1</id>
<part>Part 1.2</part>
</row>
<row>
<id>1</id>
<part>Part 1.3</part>
</row>
<row>
<id>2</id>
<part>Part 2.1</part>
</row>
<row>
<id>2</id>
<part>Part 2.2</part>
</row>
</query>
</response>
</soapenv:Body>
</soapenv:Envelope>
我想请求这两个,然后将它们的结果结合起来看起来像这样:
<items>
<item>
<id>1</id>
<name>Item 1</name>
<parts>
<part>
<id>1</id>
<name>Part 1.1</name>
</part>
<part>
<id>1</id>
<name>Part 1.2</name>
</part>
<part>
<id>1</id>
<name>Part 1.3</name>
</part>
</parts>
</item>
<item>
<id>2</id>
<name>Item 2</name>
<parts>
<part>
<id>2</id>
<name>Part 2.1</name>
</part>
<part>
<id>2</id>
<name>Part 2.2</name>
</part>
</parts>
</item>
</items>
基本上,来自两个 API 的每个响应都有一个 rows 列表,每个列表都包含一个 id 元素。调用ids 中的/items 在该响应中是唯一的,并且来自parts 的响应中的每一行都有一个id,它将它与来自/items 的一行联系起来。
我在 ESB 中有以下 API 定义:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/item_list" name="ItemList" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" uri-template="/">
<inSequence>
<header name="Content-Type" scope="transport" value="text/xml; charset=utf-8"/>
<clone>
<target>
<sequence>
<send>
<endpoint>
<address format="soap11" uri="http://example.com/items"/>
</endpoint>
</send>
</sequence>
</target>
<target>
<sequence>
<send>
<endpoint>
<address format="soap11" uri="http://example.com/parts"/>
</endpoint>
</send>
</sequence>
</target>
</clone>
</inSequence>
<outSequence>
<aggregate>
<correlateOn expression="//*[name()='response']/*[name()='query']/*[name()='row']/*[name()='id']" />
<completeCondition>
<messageCount max="2" min="2"/>
</completeCondition>
<onComplete expression="//*[name()='response']/*[name()='query']/*[name()='row']">
<send/>
</onComplete>
</aggregate>
</outSequence>
<faultSequence/>
</resource>
</api>
这里的 inSequence 被大大简化了,但它确实发送了两个有效的查询并返回了预期的响应。此处编写的 outSequence 永远不会向客户端发送响应或在服务器上记录错误。如果我从aggregate 中删除correlateOn 元素,我会从两个API 调用之一中返回一个看似随机的row。我认为 correlateOn 是我想在这里使用的东西,但是我无法从 WSO2 或 Apache 中找到任何有用的文档,所以我确定我使用不正确。我的 XPath 背景很弱,所以我确信表达式也可以使用一些工作。
我是否至少在克隆/聚合模式的正确轨道上?我将如何将这两个查询的结果组合成类似于我的示例的内容?如果我能得到一些更接近的东西,我应该可以用 XSLT 完成剩下的工作。
【问题讨论】:
标签: xpath wso2 wso2esb synapse