基于WSO2 ESB Aggregate Mediator按ID关联聚合响应的实现问询
Let's break down how to handle validation, correlation, and aggregation for your hotel data responses in a practical, developer-friendly way.
1. Validating hotelSet/id Fields
First, you'll want to ensure the integrity of the IDs in both responses before moving to aggregation. Here are key checks to implement:
Check for duplicate IDs in each response: Every entry in a
hotelSetshould have a uniqueid. Use a set to quickly detect duplicates:function checkDuplicateIds(response) { const idSet = new Set(); for (const hotel of response.hotelSet) { if (idSet.has(hotel.id)) { return `Duplicate ID detected: ${hotel.id}`; } idSet.add(hotel.id); } return null; // No duplicates found }Validate consistent hotel names for matching IDs: If an ID appears in both responses, it should map to the same hotel name (like ID 1000 being "hotel1" in both sets A and B).
function validateHotelNameConsistency(respA, respB) { const idToNameA = new Map(respA.hotelSet.map(h => [h.id, h.hotelname])); for (const hotel of respB.hotelSet) { if (idToNameA.has(hotel.id) && idToNameA.get(hotel.id) !== hotel.hotelname) { return `Mismatched name for ID ${hotel.id}: ${idToNameA.get(hotel.id)} vs ${hotel.hotelname}`; } } return null; // Names are consistent }Verify full ID coverage post-aggregation: After building the aggregated response, double-check that every ID from both original responses exists in the final
hotelSetsarray.
2. Using Correlation Expressions for Aggregation
Correlation expressions are widely used in API testing tools (like Postman or JMeter) to extract data from responses and reuse it for further processing. Here's how to apply them for this aggregation scenario:
Example with Postman:
Parse and store responses:
Usepm.response.json()to convert each API response into a JavaScript object, and store them in environment variables (or process them sequentially).Correlate IDs and build the aggregated structure:
In a Postman test script, use a map to correlate IDs across both sets and construct the desired output:// Fetch parsed responses (adjust based on your workflow) const respA = pm.environment.get("response1"); const respB = pm.environment.get("response2"); const hotelMap = new Map(); // Add hotels from Set A respA.hotelSet.forEach(hotel => { if (!hotelMap.has(hotel.id)) { hotelMap.set(hotel.id, { id: hotel.id, hotels: [] }); } hotelMap.get(hotel.id).hotels.push({ hotelname: hotel.hotelname, hotelcode: hotel.hotelcode, set: "A" }); }); // Add hotels from Set B respB.hotelSet.forEach(hotel => { if (!hotelMap.has(hotel.id)) { hotelMap.set(hotel.id, { id: hotel.id, hotels: [] }); } hotelMap.get(hotel.id).hotels.push({ hotelname: hotel.hotelname, hotelcode: hotel.hotelcode, set: "B" }); }); // Convert map to the final aggregated structure const aggregatedResponse = { hotelSets: Array.from(hotelMap.values()) }; pm.environment.set("aggregatedResponse", aggregatedResponse); console.log(JSON.stringify(aggregatedResponse, null, 2));
Example with JMeter:
- Use a JSON Extractor to extract
id,hotelname, andhotelcodevalues from each response, storing them in variables (e.g.,id_1,hotelname_1for the first entry). - Use a JSR223 PostProcessor with Groovy to aggregate the data, following a similar mapping approach as the JavaScript example above.
3. Alternative Implementation Approaches
If you're working outside of testing tools, here are other efficient ways to implement the aggregation:
Plain JavaScript (Node.js)
Use vanilla JS to process the responses directly—this is lightweight and doesn't require external dependencies, just like the Postman script example.
Using Lodash for Simplified Grouping
Lodash's groupBy function simplifies grouping by ID significantly:
const _ = require('lodash'); function aggregateHotels(respA, respB) { // Combine all hotels with their set label const allHotels = [ ...respA.hotelSet.map(h => ({ ...h, set: "A" })), ...respB.hotelSet.map(h => ({ ...h, set: "B" })) ]; // Group by ID and transform to the desired structure const grouped = _.groupBy(allHotels, 'id'); const hotelSets = Object.entries(grouped).map(([id, hotels]) => ({ id, hotels: hotels.map(({ hotelname, hotelcode, set }) => ({ hotelname, hotelcode, set })) })); return { hotelSets }; }
Backend-side Aggregation
If you control the backend, modify the API to either accept both sets as input or fetch them internally, then return the aggregated structure directly. This shifts the work to the server, which can be more efficient if this aggregation is a frequent requirement.
内容的提问来源于stack exchange,提问作者Estimate

