Exploring REST Capabilities of BizTalk Server 2013 (Part 2: Consuming REST Endpoints)

In my previous post, I looked at how the BizTalk Server 2013 beta supports the receipt of messages through REST endpoints. In this post, I’ll show off a couple of scenarios for sending BizTalk messages to REST service endpoints. Even though the BizTalk adapter is based on the WCF REST binding, all my demonstrations are with non-WCF services (just to prove everything works the same).

Scenario #1 Consuming “GET” Service From an Orchestration

In this first case, I planned on invoking a “GET” operation and processing the response in an orchestration. Specifically, I wanted to receive an invoice in one currency, and use a RESTful currency conversation service to flip the currency to US dollars.  There are two key quirks to this adapter that you should be aware of:

  • Consumed REST services cannot have an “&” symbol in the URL. This meant that I had to find a currency conversion service that did NOT use ampersands. You’d think that this would be easy, but many services use a syntax like “/currency?from=AUD&to=USD”, and the adapter doesn’t like that one bit. While “?” seems acceptable, ampersands most definitely are not.
  • The adapter throws an error on GET. Neither GET nor DELETE requests expect a message payload (as they are entirely URL driven), and the adapter throws an error if you send a GET request to an endpoint. This is a problem because you can’t natively send an empty message to an adapter endpoint. Below, I’ll show you one way to get around this. However, I consider this an unacceptable flaw that deserves to be fixed before BizTalk Server 2013 is released.

For this demonstration, I used the adapter-friendly currency conversion service at Exchange Rate API. To get started, I created a new schema for “Invoice” and a property schema that held the values that needed to be passed to the send adapter.

2012.11.19rest01

Next, I built an orchestration that received this message from a (FILE) adapter, routed a GET request to the currency conversion service, and then multiplied the source currency by the returned conversion rate. In the orchestration, I routed the original Invoice message to the GET service, even though I knew I’d have to strip out the body before completing the request. Also, the Exchange Rate API service returns its result as text (not XML or JSON), so I set the response message type as XmlDocument. I then built a helper component that took in the service response message and returned a string.

public static class Utilities
    {
        public static string ConvertMessageToString(XLANGMessage msg)
        {
            string retval = "0";

            using (StreamReader reader = new StreamReader((Stream)msg[0].RetrieveAs(typeof(Stream))))
            {
                retval = reader.ReadToEnd();
            }

            return retval;
        }
    }

Here’s the final orchestration.

2012.11.19rest02

After building and deploying this BizTalk project (with the two schemas and one orchestration), I created a FILE receive location to pull in the original invoice. I then configured a WCF-WebHttp send port. First, I set the base address to the Exchange Rate API URL, and then set an operation (which matched the name of the operation I set on the orchestration send port) that mapped to the GET verb with a parameterized URL.

2012.11.19rest03

I set those URL parameters by clicking the Edit button under Variable Mapping and choosing which property schema value mapped to each URL parameter.

2012.11.19rest04

This scenario was nearly done. All that was left was to strip out the body of message so that the GET wouldn’t fail. Fortunately, Saravana Kumar already built a simple pipeline component that erases the message body. I built the pipeline component, added it to a custom pipeline, and deployed the pipeline.

2012.11.19rest05

Finally, I made sure that my send port used this new pipeline.

2012.11.19rest06

With all my receive/send ports created and configured, and my orchestration enlisted, I dropped a sample file into a folder monitored by the FILE receive adapter. This sample invoice was for 100 Australian dollars, and I wanted the output invoice to translate that amount to U.S. dollars. Sure enough, the REST service was called, and I got back a modified invoice.

<ns0:Invoice xmlns:ns0="http://Seroter.BizTalkRestDemo">
  <ID>100</ID>
  <CustomerID>10022</CustomerID>
  <OriginalInvoiceAmount>100</OriginalInvoiceAmount>
  <OriginalInvoiceCurrency>AUD</OriginalInvoiceCurrency>
  <ConvertedInvoiceAmount>103.935900</ConvertedInvoiceAmount>
  <ConvertedInvoiceCurrency>USD</ConvertedInvoiceCurrency>
</ns0:Invoice>

So we can see that GET works pretty well (and should prove to be VERY useful as more and more services switch to a RESTful model), but you have to be careful on both the URLs you access, and the body you (don’t) send.

Scenario #2 Invoking a “DELETE” Command Via Messaging Only

Let’s try a messaging-only solution that avoids orchestration and calls a service with a DELETE verb. For fun, I wanted to try using the WCF-WebHttp adapter with the “single operation format” instead of the XML format that lets you list multiple operations, verbs and URLs.

In this case, I wrote an ASP.NET Web API service that defines an “Invoice” model, and has a controller with a single operation that responds to DELETE requests (and writes a trace statement).

public class InvoiceController : ApiController
    {
        public HttpResponseMessage DeleteInvoice(string id)
        {
            System.Diagnostics.Debug.WriteLine("Deleting invoice ... " + id);
            return new HttpResponseMessage(HttpStatusCode.NoContent);
        }
    }

With my REST service ready to go, I created a new send port that would subscribe directly on the input message and call this service. The structured of the “single operation format” isn’t really explained, so I surmised that all it included was the HTTP verb that would be executed against the adapter’s URL. So, the URL must be fixed, and cannot contain any dynamic parameter values. For instance:

2012.11.19rest08

To be sure, the scenario above make zero sense. You’d never  really hardcode a URL that pointed to a specific transaction resource. HOWEVER, there could be a reference data URL (think of lists of US states, or current currency value) that might be fixed and useful to embed in an adapter. Nonetheless, my demos aren’t always about making sense, but about flexing the technology. So, I went ahead and started this send port (WITHOUT changing it’s pipeline from “passthrough” to “remove body”) and dropped an invoice file to be picked up. Sure enough, the file was picked up, the service was called, and the output was visible in my Visual Studio 2012 output window.

2012.11.19rest09

Interestingly enough, the call to DELETE did NOT require me to suppress the message body. Seems that Microsoft doesn’t explicitly forbid this, even though payloads aren’t typically sent as part of DELETE requests.

Summary

In these two articles, we looked at REST support in the BizTalk Server 2013 (beta). Overall, I like what I see. SOAP services aren’t going anywhere anytime soon, but the trend is clear: more and more services use a RESTful API and a modern integration bus has to adapt. I’d like to see more JSON support, but admittedly haven’t tried those scenarios with these adapters.

What do you think? Will the addition of REST adapters make your life easier for both exposing and consuming endpoints?

Comments

24 responses to “Exploring REST Capabilities of BizTalk Server 2013 (Part 2: Consuming REST Endpoints)”

  1. Christian Dube Avatar

    Nice post Richard, thanks.

    Did you try Biztalk with OAuth, or have you seen anything regarding that topic. I’m trying not to build plumbing code…

    1. Richard Seroter Avatar

      Hi Christian. Given that BIzTalk 2013 works natively with the Service Bus (and ACS), I’d hope that you could use the ACS 2.0 support for OAuth http://msdn.microsoft.com/en-us/library/windowsazure/gg185937.aspx

  2. Charles Storm Avatar
    Charles Storm

    Hi Richard,

    Nice post. I have done some similar exploring and the BtsHttpUri mapping is actually quite simple. When your URL is invoked using GET or DELETE it will cause the adapter to put the corresponding operation in BTS.Operation and promote the content at the placeholders position into the property you can map in the Variable dialog.

    Did you also notice that the GET receive method produces a context only message? You can connect the receive to an outgoing WebHTTP port without using the RemoveMessageBody Plc and just be routing properties.

    1. Richard Seroter Avatar

      Interesting, thanks Charles. Yes, it makes sense that an inbound GET results i a context-only message. I wonder what new BizTalk scenarios/tools will pop up as a result of these lightweight request messages.

  3. […] Exploring REST Capabilities of BizTalk Server 2013 (Part 2: Consuming REST Endpoints) […]

  4. […] REST Capabilities of BizTalk Server 2013 (Part 2: Consuming REST Endpoints) https://seroter.wordpress.com/2012/11/19/exploring-rest-capabilities-of-biztalk-server-2013-part-2-co… This is a good feature but has a limit, you cannot use these property because is not promoted, so […]

  5. Etienne Bouchard Avatar
    Etienne Bouchard

    Hi Richard,

    We are experimenting scenarios with RESTful services (GET) consumed by BizTalk 2009 using custom wcf behavior. However, for some scenarios, we build our RESTful services with parameters. The ‘&’ sign is thus mandatory. I am very surprise and disappointed of this BizTalk 2013 beta limitation! Do you expect it to be a limitation on the CTP as well? In that case, BizTalk support for RESTful services would be very restrictive.

    1. Richard Seroter Avatar

      Hi Etienne, I hope this will be changed for the release as it is fairly common to see that symbol in REST services!

    2. Henry Houdmont Avatar

      Hi all,
      First of all, I don’t know if you’ve found this in the mean time but you can use the ‘&’ sign in your URL. However, you have to use ‘&’ as in: /currency?from=AUD&to=USD
      I’ve tested it and it works perfectly.

      Second, another issue that you might have encountered is that you can’t concatenate variables in your url. For instance you can’t use: /customer?id={customer_id}{specification} which is probably not often used but might be useful. It seems weird that you can’t do something as basic as concatenation there.

      And last but not least: did somebody find an easy way to process JSON responses? Is there a hidden built-in JSON parser or XML-JSON converter in the adapter or will we have to create custom helper classes for the orchestration or custom pipeline components? I think this is a basic feature that should be added as many REST replies are in JSON.
      It would be nice to have a checkbox: “Parse to XML” or something like that.

      1. Richard Seroter Avatar

        Thanks Henry. I just tried the “&” again, and while you can put that in the top “Address” box in the configuration window, you cannot add it to the “url mapping” section. I still get an error when I put one there, and no error once I remove it!

      2. akismet-cc10e1fc80740b34e84b8e5ec8df2c88 Avatar

        You can use the & sign, guys. The only thing you need to do is to ‘XML escape’ it.
        The following should work : /currency?from=AUD&to=USD

      3. Richard Seroter Avatar

        Thanks Sam. I’ll try it with the escaping instead. Good call.

      4. Henry Houdmont Avatar

        I’m sorry, I was trying to explain that you could use the XML escape character but did not notice that when submitting my message, the escaped character was processed and shown as the normal &. Thanks Sam for clarifying!

  6. […] Exploring REST Capabilities of BizTalk Server 2013: Consuming REST Endpoints – Second part of a nice tutorial. This time exploring how to consume services (Get, Delete). […]

  7. Lex Hegt Avatar

    Hi Richard,

    Thanks for the article! I considered it very useful for getting familiar with the WCF-WebHTTP-adapter.
    I noticed, by the way, that it looks like the exchange rate API you used isn’t free (anymore). It looks like you have to take a subscription, before you can enjoy a 14 days free trial. Strange, right??
    So instead I took the API at http://currencies.apps.grandtrunk.net/. You can also find it at Programmable Web. Because the syntax of the API is almost the same (same parameters, text response) as the one you used, only some minor modifications to the Send Port are needed (URL and no API key needed).

    Best regards,
    Lex

  8. […] few months back, I wrote up a pair of blog posts (part 1, part 2) about the new BizTalk Server 2013 REST adapter. Overall, I liked them, but I complained about […]

  9. […] adapter – Exploring REST Capabilities of BizTalk Server 2013 (Part 1: Exposing REST Endpoints) – Exploring REST Capabilities of BizTalk Server 2013 (Part 2: Consuming REST Endpoints) – Yes Richard, You Can Use Ampersands in the BizTalk REST Adapter (And Some ASP.NET Web API […]

  10. Larry Smith Avatar

    Hi,
    Any plans to publish a JSON update?

    1. Richard Seroter Avatar

      Larry, I was thinking about it! It requires the use of a custom pipeline or component as BizTalk isn’t particularly JSON-friendly.

  11. Prasad Avatar
    Prasad

    Hi Richard,
    Good article. I have a requirement to make a rest call from BizTalk 2013 with the entire message body in the URL instead of one or two elements from the message. The GET request should look like htttp://temp.com/getdata?. Is there any way i can accomplish this using WCF-WebHttp adapter? If not is there any other way?

    1. Prasad Avatar
      Prasad

      Correction for the above: The Get request should look like http://temp.com/GetData?Messagebodywithxmltags

Leave a reply to akismet-cc10e1fc80740b34e84b8e5ec8df2c88 Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.