The BizTalk Server 2013 beta is out there now and I thought I’d take a look at one of the key additions to the platform. In this current age of lightweight integration and IFTTT simplicity, one has to wonder where BizTalk will continue to play. That said, a clean support of RESTful services will go a long way to keeping BizTalk relevant for both on-premises and cloud-based integration scenarios. Some smart folks have messed around with getting previous version of BizTalk to behave RESTfully, but now there is REAL support for GET/POST/PUT/DELETE in the BizTalk engine.
I decided to play with two aspects of REST services and BizTalk Server 2013: exposing REST endpoints and consuming REST endpoints. In this first post, I’ll take a look at exposing REST endpoints.
Scenario #1: Exposing Synchronous REST Service with Orchestration
In this scenario, I wanted to use the BizTalk-provided WCF Service Publishing Wizard to generate a REST endpoint. Let’s assume that I want to let modern web applications send new “account” records into our ESB for further processing. Since these accounts are associated with different websites, we want a REST service URL that identifies which website property they are part of. The simple schema of an account looked like this:

I also added a property schema that had fields for the website property ID and the account ID. The “property ID” node’s source was set to MessageContextPropertyBase because its value wouldn’t exist in the message itself, but rather, it would solely exists in the message context.

I could stop here and just deploy this, but let’s explore a bit further. Specifically, I want an orchestration that receives new account messages and sets the unique ID value before returning a message to the caller. This orchestration directly subscribes to the BizTalk MessageBox and looks for any messages with a target operation called “CreateAccount.”

After building and deploying the project, I then started up the WCF Service Publishing Wizard. Notice that we can now select WCF-WebHttp as a valid source adapter type. Recall that this is the WCF binding that supports RESTful services.

After choosing the new web service address, I located my new service in IIS and a new Receive Location in the BizTalk Engine.

The new Receive Location had a number of interesting REST-based settings. First, I could choose the URL and map the URL parameters to message property (schema) values. Notice here that I created a single operation called “CreateAccount” and associated with the HTTP POST verb.

How do I access that “{pid}” value (which holds the website property identifier) in the URL from within my BizTalk process? The Variable Mapping section of the adapter configuration lets me put these URL values into the message context.

With that done, I bound this receive port/location to the orchestration, started everything up, and fired up Fiddler. I used Fiddler to invoke the service because I wanted to ensure that there was no WCF-specific stuff visible from the service consumer’s perspective. Below, you can see that I crafted a URL that included a website property (“MSWeb”) and a message body that is missing an account ID.

After performing an HTTP POST to that address, I immediately got back an HTTP 200 code and a message containing the newly minted account ID.

There is a setting in the adapter to set outbound headers, but I haven’t seen a way yet to change the HTTP status code itself. Ideally, the scenario above would have returned an HTTP 202 code (“accepted”) vs. a 200. Either way, what an easy, quick way to generate interoperable REST endpoints!
Scenario #2: Exposing Asynchronous REST Service for Messaging-Only Solution
Let’s do a variation on our previous example so that we can investigate the messages a bit further. In this messaging-only solution (i.e. no orchestration in the middle), I wanted to receive either PUT or DELETE messages and asynchronously route them to a subsequent system. There are no new bits to deploy as I reused the schemas that were built earlier. However, I did generate a new, one-way WCF REST service for getting these messages into the engine.
In this receive location configuration, I added two operations (“UpdateAccount”, “DeleteAccount”) and set the corresponding HTTP verb and URI template.

I could list as many service operations as I wanted here, and notice that I had TWO parameters (“pid”, “aid”) in the URI template. I was glad to see that I could build up complex addresses with multiple parameters. Each parameter was then mapping to a property schema entry.

After saving the receive location configuration, I configured a quick FILE send port. I left this port enlisted (but not started) so that I could see what the message looked like as it traveled through BizTalk. On the send port, I had a choice of new filter criteria that were related to the new WCF-WebHttp adapter. Notice that I could filter messages based on inbound HTTP method, headers, and more.

For this particular example, I filtered on the BTS.Operation which is set based on whatever URL is invoked.

I returned to Fiddler and changed the URL, switched my HTTP method from POST to PUT and submitted the request.

I got an HTTP 200 code back, and within BizTalk, I could see a single suspended message that was waiting for my Send Port to start. Opening that message revealed all the interesting context properties that were available. Notice that the operation name that I mapped to a URL in the receive adapter is there, along with various HTTP header and verbs. Also see that my two URL parameters were successfully promoted into context.

Summary
That was a quick look at exposing REST endpoints. Hopefully that gives you a sense of the native aspect of this new capability. In the next post, I’ll show you how to consume REST services.



Larry Smith
December 30, 2012
I got an error – Receive location for address “/GPS/Service1.svc” not found ,
when entering the following url on my browser: http://localhost/gps/Service1.svc?wsdl
I also received this error when submitting POST via Fiddler (http://localhost/gps/Service1.svc )
Orchestration Datasmith.Samples.BizTalkRest1.MsgOrchestration
Port: WcfReceivePort_gps/Service1
receive Location Name: WcfService_gps/Service1
URI: /gps/Service1.svc
Mapping:
In web.config, I noticed no entries for receiveLocationMappings – not sure if this is an issue.
Larry Smith
December 30, 2012
btw, The following was used to create the Receive Port via the Biztalk WCF publishing wizard:
Larry Smith
December 30, 2012
The following was used to create the Receive Port via the Biztalk WCF publishing wizard:
Richard Seroter
January 11, 2013
Can you browse the endpoint via IIS? Are you sure that the Receive Location is enabled?
Larry Smith
February 15, 2013
I fixed this, thanks.
another issue.
I installed Biztalk 2013 Beta on Windows 2008 R2. I also installed .Net Framework 4.5.
My problem is that when i select WCF_Custom, the UDP Binding is not present in the drop-down combo box on the Bindings tab.
Any suggestions on how to resolve this?
Larry Smith
February 19, 2013
Apparently, 32 bit & 64 bit machine.config needs to be updated, since Biztalk admin application is 32 bit, whereas, adapter is 64 bit.
MS documentation doesn’t remind developer that both locations need to be updated, it usually just states update machine.config.
MS should have a common\machine.config for configurations that both 32-bit & 64-bit rely on.
Maarten
February 20, 2013
Hey Larry
I’m sorry, but it is the .net 4.5 machine.config files that need to be edited, I guess?
Can you explain shortly what and where needs to be addes,
Tnx!
Maarten
February 20, 2013
*added
Barathan K
March 1, 2013
Great Article!, Can you please explain on what the SetUnitque ID Message Assignment shape does? Based on the screenshot it looks like the UserName property has been promoted but not ID property. How are you setting the ID Property? Please advise.
Barathan K
March 1, 2013
I am trying to implement the Scenario 1 of this Article and i am getting the Routing Failure Report and the Message is getting suspended. When i see the error report the BTS.Operation have been promoted to have value of CreateAccount but the message Type is blank. Please advice on what could be the problem here.
Richard Seroter
March 8, 2013
The unique ID is just a random GUID that acts as the account ID on the returned message. Simply used System.Guid.NewGuid().ToString() to generate it.