This post is the fifteenth in a weekly series intended to briefly spotlight those things that you need to know about new features in BizTalk Server 2013. It is also the third part of a five-part series on REST support in BizTalk Server 2013.
Last week’s post worked through how one would use BizTalk Server to host a RESTful endpoint that would support multiple “operations” (i.e., expose multiple resources). This week we’re going to be trying to do something quite the opposite – consume a RESTful endpoint (using the POST verb) that only represents a single resource (and as such will not require operation mapping). In the process we will deal with formatting a form encoded message, and customizing the outgoing message headers.
This Week’s Scenario
This week we will be working on a ridiculously fictional integration with a home grown finance suite which exposes a RESTful API using a ASP.NET WebAPI service with an implementation that looks something like this.
Essentially the story goes that as new sales happen, the amounts of those sales are aggregated by POSTing them to the MonthlySales resource. Once the data has been collected, the aggregate information can be requested by issuing a GET request to the same resource indexed by month number.
While this week’s scenario is especially painfully contrived, it does serve to allow me to demonstrate simple POST requests and some of the fun that might surround them.
Dealing with Form Values
Whenever you POST data, it is contained in some form within the body of the http request. In the case of ASP.NET WebAPI, it is expected that this data is url encoded. The end result of a request body should look something like this. In order to ensure that a sale message received by the BizTalk application can be translated into this format, we will need not only a map (to transform the message) but also a schema and pipeline (to translate the message from XML to a flat-file format).
In order to translate to a flat-file format, I used the flat-file schema wizard to define a simple flat-file schema that splits first on the ampersand (&), and then on the equals sign (=) to create a message that resembles the following:
The one thing that this schema does NOT take into account is the escaping of special characters. For those considerations, one would have to resort to logic within a map – which will not be something that we encounter this week.
After this schema has been defined, we need a pipeline that can create flat-file messages from any XML message that conforms to this schema (nothing special, just a text-book flat-file transmit pipeline):
In order to get the data from the sale message into the flat-file format called for, we need to use a map. Mapping back and forth between URL encoded form data and XML ultimately feels like an EDI mapping involving code pairs – you’re dealing with data that is identified by a sibling node. As a result, for digging deep into advanced mapping techniques using a schema similar to this, I would recommend the discussion of EDI code pairs in the book Pro Mapping in BizTalk Server 2009 (ignore the version number in the title – the book is excellent) as it will provide a nice introduction to techniques that can be used to make this manageable.
For my map, it was fairly straightforward. We need to take a single value from the sale message, and map it over into key=value format:
Configuring the WCF-WebHttp Adapter to POST Form Data
We’re at the point now where we have a way to take an XML message and convert it into a format that would live nicely within the body of an http request as form data (readable quite nicely by an ASP.NET WebAPI service). However, we do need to make sure that when the data is sent, the format is identified. In order to do that, we need to ensure that the Content-Type header is transmitted alongside the body with a value of “application/x-www-form-urlencoded”.
So how do we make that happen? Through the Messages tab of the adapter configuration:
We can finish off the configuration on the General tab. Here I’m showing an operation mapping that only intends to ever call a single operation. Since all of the information is passed within the body, we don’t need to do any building out of the URL, we don’t have any variable mapping from the context into the URL, or anything like that. As such, configuration becomes very simple – we only need to specify the HTTP method in the mapping field:
Validating the Request
So what message was generated by our send port? Well after a quick tweak to the URL to ensure that Fiddler would capture it appropriately, we see the following:
We can see the POST verb is being used, the Content-Type has been specified correctly, and the body contains the urlencoded content of the original sale message. After submitting a few similar requests (to the correct URL), we can verify that the messages indeed are received and aggregated appropriately by executing a GET request against the resource:
We’ve made it 3/5 of the way through this mini-series on the WCF-WebHttp adapter, and have quite a few new powers at our disposal, but there are still a few things missing that we will be tackling over the next few posts – namely the ability to read that wonderful JSON response (or any JSON data for that matter), and also the oft-neglected in sample code: authentication.
The end for now!
If you would like to access sample code for this blog post, you can find it on github.