Error Handling in HTTP APIs
This topic explains how to handle HTTP errors in a mapping that calls an HTTP API. If you want to handle HTTP errors (e.g., Not Found, Unauthorized), you need to define a corresponding body node in the response part of the Web service call (see details below). Otherwise, HTTP errors will always terminate the execution of the mapping.
Web service call implementation
In the sample mapping shown below, a CSV file called products.csv supplies the IDs of products to the Request part of the Web service call. When the Web service is called, the response containing the retrieved details is mapped to an XML file called output.xml.
If the products with the supplied IDs exist on the server, their details will be mapped from the body with the status code 200 (success). If there are no products with such IDs on the server, the Web service call will return the 404 status code (not found), and the response will be mapped from the body with the status code 404 to the ErrorMessage node in the output.
Bodies and response structures
To handle different HTTP responses from the Web service in the same mapping, you can create multiple Body items as follows: Right-click the Body item in the Web service component and select Add Body Node Before/After from the context menu. In our example, there are two bodies, each handling a particular type of HTTP response: the body with the status code 200 handles successful responses, and the body with the status code 404 handles Not Found errors.
Each of the response Body items are configurable via their respective buttons. When you click this button, the Response Structure dialog opens (screenshots below). Both bodies have response structures in XML format. The bodies can also accept content of other types (e.g., JSON).
Body status=200
Body status=404
Processing order
This subsection explains how the mapping processes the request and outputs the response to the target document.
Common target context
According to one of the fundamental rules in MapForce, processing always starts from the target root node and progresses down the hierarchy. In our example, the target root is ProductList. The target root is not connected, so the processing continues with the Product element that is connected to the Response node of the Web service call. With this connection, a common target context is established for all the descendents of the Product node. This means that the descendents will have access to their parent's data, which will help avoid unnecessary calls.
One product for each response
According to another fundamental rule in MapForce, for each source item, one item is created in the target. In our example, this means that for each response, one Product item will be created in the output. As a general rule, especially with multiple Body nodes configured, you will typically want to connect the Response node to some common parent in the target. This will help avoid making too many calls.
Processing request/response
When the connection is traced from the Product node to the Response node, MapForce knows that it needs to make a Web service call, but first it needs a request. Then the request part is processed. The id parameter accepts values from the ProductID node of the source CSV file.
The CSV file contains a sequence of values that we are trying to map to the parameter that expects only one value. In this case, the Web service function will be called as many times and produce as many results as there are items in the sequence. This means that if there are 5 product IDs, a call will be made for each ID.
When the connection from the id node is traced to the ProductID node, MapForce brings its parent, the Rows node, into the context and loops through each row (ProductID). For each row, a request will be sent to the server. MapForce will then receive a response from the server and create a Product item that has the same ID as the one sent to the request.
Notice that the ProductID node in the target receives data not from the Response structure but directly from the source CSV file. The reason is, we want to get a response for every single product ID that may or may not exist on the server.
Bodies
The bodies are processed from top to bottom. The first body that matches the response is processed first. Then MapForce moves down the tree. If none of the bodies match, MapForce will throw an exception, and the execution of the mapping will stop.
If a product with the ID supplied from the CSV file exists on the server, the Product element will be populated with the data from the body with the status code 200. If there is no product with such an ID on the server, the second body with the status code 404 will be processed, and the Product element will get only the product ID and an error message.
Output
Below is the output that shows that the details of the products with the IDs 1, 5, and 7 have successfully been retrieved. The product with the ID 6 has not been found, therefore, the body with the status code 404 has been processed, and the value of the Message node has been mapped to the ErrorMessage node of the target.
<ProductList xsi:noNamespaceSchemaLocation="output.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Product ProductID="1" Description="This lightweight linen blouse blends sustainability with effortless style. Made from 100% organic linen, it offers a breathable, airy feel ideal for warm weather." CurrentStock="50"/> <Product ProductID="5" Description="These cargo pants bring a retro twist to modern utility wear. Constructed from a durable cotton canvas, they feature multiple oversized pockets for both functionality and style. Available in earthy tones like olive and sand, they blend seamlessly with both casual and adventurous looks." CurrentStock="0"/> <Product ProductID="6" ErrorMessage="Product not found"/> <Product ProductID="7" Description="Crafted for maximum comfort, this oversized knit cardigan wraps you in warmth without compromising on style. Available in soft, neutral shades like cream and heather gray, it's an ideal companion for effortless layering over everything from casual jeans to loungewear." CurrentStock="1"/> </ProductList> |