Mike Taulty's Blog
Bits and Bytes from Microsoft UK
Message Request/Response Patterns in Web Services

Blogs

Mike Taulty's Blog

Elsewhere

Archives

I keep getting bogged down in what I’d call a “technology” gap between web services implemented on top of HTTP and web services implemented (potentially) on top of other protocols. I’ve been having a lot of discussions around this lately and I thought I’d blog what I’ve been thinking about as a means of getting my thoughts in order and, thereby, preserving my sanity J

 

The problem arises for me because HTTP is implicitly a request-response protocol and the technologies that we have for building web services today take “advantage” of that fact to implement their services in a particular way.

 

Imagine a scenario where I have a distributor of products who orders their products from a number of suppliers. The suppliers implement a web-service interface that allows the distributor to order from them.

 

So, for discussion, imagine that the supplier will need to send a request message something like;

 

<?xml version="1.0" encoding="utf-8" ?>

<Order xmlns="urn:supplies-com">

      <WidgetOrder Quantity="500" WidgetName="Buttons"/>

</Order>

 

And that seems fine and then I’d imagine that the supplier might send back a message that looks something like;

 

<?xml version="1.0" encoding="utf-8" ?>

<Supply xmlns="urn:supplies- com">

      <Goods HoldDays="2" Quantity="50" WidgetName="Buttons"/>

</Supply>

 

So, that all seems fine. If we’re modelling this kind of interaction with web services then we’d probably go ahead and build a WSDL operation that described this interchange;

 

<portType name="OrderWidgetsPort">

  <operation name="OrderWidgets">

    <input message="WidgetOrderMessage" />

    <output message="WidgetOrderResponseMessage" />

  </operation>

</portType>

 

And this is where I start to hit problems. It’s not immediately obvious so let me explain why.

 

The WSDL document says that we have an operation that consumes one message and produces another message. What is does not say is whether, as a consumer of the service, you should assume that the response is produced synchronously with respect to the receipt of the request.

 

If we go and implement this kind of WSDL operation on top of HTTP/ASMX then we’d end up with a service implementation (and, proxy clients for it) which assumed that the response to the request message is available within the timeout period of the HTTP protocol. That is, we’d submit a request message and the client would then sit and wait for the WidgetOrderResponseMessage to be returned down the HTTP response stream. If no response was available then the client will fail. ASMX does have asynchronous support both in server-side implementation and client-side proxies but, still, if the HTTP request is left to time out then we will still fail and so this asynchronous support will only allow us to delay for a short period of time.

 

If we go and implement this kind of WSDL operation on top of TCP/WSE2.0 then we can make a choice and have a service implementation which does not assume that the response to the request message is available within a particular period. The supplier service can receive an order message, store its ReplyTo address and, at some later point, send a response back to that end point reference using a RelatesTo header field so that the sender can tie together request and response.

 

From a business (or, arguably to my way of thinking, Service Oriented) perspective it seems unreasonable to assume that the Supplier would be able to produce an order response message here in a particular timeframe. If the supplier has to wait for an overnight batch job to return before determining their stock levels then we’re not going to be able to leave an HTTP request hanging for 24 hours.

 

So, what would be reasonable from a business point of view? It seems to me that what we could legitimately expect would be a receipt from the supplier service. This ties up with the business scenario where I order something over the telephone and I get back an order number (a receipt). During the process of waiting for delivery of the goods I’ve ordered I can phone the supplier again, give them the order number and they’ll give me some more information as to what my order status is. When the order is finally delivered I usually get some kind of documentation that describes who supplied it, who delivered it, who packed it, who checked it and so on but, at any earlier point in the ordering process, I only get limited visibility of this set of information.

 

We can change our messages in order to reflect this. Our request still looks the same;

 

<?xml version="1.0" encoding="utf-8" ?>

<Order xmlns="urn:supplies-com">

      <WidgetOrder Quantity="500" WidgetName="Buttons"/>

</Order>

 

But our response needs to be changed. We could either have a response that was purely a receipt or we could have a response which would contain one of two things (via xs:choice) – one would be a receipt and the other would (in the case where the supplier could perform a synchronous operation for us) be the actual reply message. So, following that second scheme, a valid response message would be;

 

<?xml version="1.0" encoding="utf-8" ?>

<Supply xmlns="urn:supplies-com">

      <Goods HoldDays="2" Quantity="50" WidgetName="Buttons"/>

</Supply>

 

And another valid response message would be;

 

<?xml version="1.0" encoding="utf-8" ?>

<Supply xmlns="urn:supplies-com">

      <Receipt id="unique id"/>

</Supply>

 

So I end up with a schema that looks something like;

 

<?xml version="1.0" encoding="utf-8" ?>

<xs:schema id="Supply"

                  targetNamespace="urn:supplies-com"

                  elementFormDefault="qualified"

                  xmlns="urn:supplies-mt.com"

                  xmlns:mstns="urn:supplies-com"

                  xmlns:xs="http://www.w3.org/2001/XMLSchema">

                 

      <xs:complexType name="SupplyType">

            <xs:attribute name="WidgetName" type="xs:string"/>

            <xs:attribute name="Quantity" type="xs:integer"/>

            <xs:attribute name="HoldDays" type="xs:integer"/>

      </xs:complexType>

 

      <xs:complexType name="ReceiptType">

            <xs:attribute name="id" type="xs:uuid"/>       

      </xs:complexType>

     

      <xs:complexType name="SupplyDocumentType">

            <xs:choice>

<xs:element name="Goods"

type="mstns:SupplyType"/>

<xs:element name="Receipt"

type="mstns:ReceiptType"/>

            </xs:choice>

      </xs:complexType>

     

      <xs:element name="Supply"

type="mstns:SupplyDocumentType"/>

</xs:schema>

 

We now need an additional operation on our web service to support this kind of pattern.

 

<portType name="OrderWidgetsPort">

 

  <operation name="OrderWidgets">

    <input message="WidgetOrderMessage" />

    <output message="WidgetOrderReceiptOrFulfillmentMessage" />

  </operation>

 

  <operation name="CheckWidgetOrderStatus">

    <input message="WidgetOrderStatusMessage" />

    <output message="WidgetOrderReceiptOrFulfillmentMessage" />

  </operation>

 

</portType>

 

Note that in the second operation here, CheckWidgetOrderStatus I’ve lazily used the same message type as was present in the original OrderWidgets operation as the response message type. So, when we check order status we will (once again) either get back the real order status or we will get back a receipt telling us to come back later on.

 

So, I’m happy now with what I have here but there’s one thing that’s leaving me puzzled at this point and that’s this – doesn’t every web service need to be implemented in this fashion? Is it ever reasonable to design an interface that will allow for an HTTP implementation that will assume a synchronous response message and, thereby, couple the “client” and “service” provider in terms of expectation around response time?

 

Would it make sense for every Response message in a web service operation to include a “receipt” portion or have I just lost the plot again?


Posted Fri, Jul 30 2004 6:07 AM by mtaulty

Comments

mtaulty wrote re: Message Request/Response Patterns in Web Services
on Fri, Jul 30 2004 7:04 AM
Can the response not be taken as a receipt. If you receive a response back then this is the receipt to inform you that the request has been received. If there is not response back then you have received a receipt to confirm that the action is not going to take place. The implementation of the additional xml required is minimal to implement and gives semantic richness to the messages being passed. What is interesting is that the receipt confirms the order rather than simply assuming the order will be processed based on the fact that you received a response. May be you should create a specification for WS-Receipt.
mtaulty wrote re: Message Request/Response Patterns in Web Services
on Fri, Jul 30 2004 7:14 AM
Interesting comments Richard, thanks very much for them.

When you're saying "Can the response not be taken as a receipt" which response do you mean? Are you thinking of an HTTP response (i.e. a 200 status code) ?

If so then what do we do in the absence of HTTP (e.g. over the WSE2.0 TCP transport which provides no real "response" code as such).

It seems like we need something in the real message back from the service to indicate a response.
mtaulty wrote re: Message Request/Response Patterns in Web Services
on Fri, Jul 30 2004 12:52 PM
First of all an answer to your question. I think that any service request that causes modification of business state/information on the provider should not assume a synchronous pattern. When it comes to pure queries that have no side effects in the service provider, synchronous invocations might be acceptable, but only if the amount of server-side processing is limited. If a service aggregates info from other services the synchronous model breaks down fairly quickly as well.

Secondly, I would consider defining 2 port types in the WSDL for the scenario you describe. 1 port type with the request/request acknowledge pair to be implemented by the service and 1 port type with the response/response acknowledge message pair to be implemented by the client.

Alternatively you would create 1 port type that contains a request <input>/request acknowledge <output> message pair and a response <output>/response acknowledge <input> message pair. However, I'm not sure whether (and how) tools would generate proxy and stub code for such WSDL.
mtaulty wrote re: Message Request/Response Patterns in Web Services
on Fri, Jul 30 2004 5:10 PM
Hi Gerke,

Thanks for the comments.

The only problem I'd have with implementing the response/response acknowledgement pair in the client is that in a lot of cases today clients aren't reachable because they're behind a firewall. Now, clearly it depends on what we mean by "client" but what I was thinking here is that;

1) We know the client can reach the service because it posted the original order message to it.
2) We don't know whether the service can reach the client.

Therefore, the safest assumption would be to implement the response/response pair on the service because we _know_ that the client can talk to us.

Thoughts?
mtaulty wrote re: Message Request/Response Patterns in Web Services
on Sat, Jul 31 2004 12:55 AM
Hi Mike,

You're right that the scenario you described does not work if the server cannot send messages to the client other than through a connection that is initiated by the client. This situation resembles the situation where a service needs human interaction to proceed: the software cannot assume the relevant person is around and willing to directly provide the input. It is not even safe to assume which presentation channel will be used by people to interact with the service.

My general solution for the 'service needing human interaction' problem is to introduce a work item management service. Services that need human intervention "humbly ask" (Pat Hellands terminology) the work item management service to create a work item for a particular user or user group. When people are ready to do some work they can get a list of outstanding work items from the work item management service (think Outlook task lists). From the service point of view the work item management service represents human services as automated services. Each work item essentially represents a request from a service to a person to submit a well-defined piece of information to the service.

Back to the main topic. I consider it undesirable to have client limitations drive my service design. In this case the limitation is that the client can only retrieve service responses by polling. If I need to cater for polling clients I would use a similar solution as for polling people. Implement a core service that expects to live in an ideal service world with a WSDL as described in my first comment. Then create a second service that represents the polling client, acts as an adapter for the core service and has a WSDL as you propose. Polling clients would talk to the adapter service, non-polling clients (peer services) would talk directly to the core service without being forced to poll for their information.

What do you think?

Regards,
Gerke.
mtaulty wrote re: Message Request/Response Patterns in Web Services
on Sun, Aug 1 2004 1:56 AM
That's an interesting point. Clemens Vasters, on his product (FABRIQ), doesn't implement request/response message pattern at all. From his poi of view a web service should be always one-way for several reasons, some of them are long running methods (timeout), as you pointed out, and scalability.

You suggested to poll the web server asking if it has finished. But if the service can request a short or long time (from 1 to 10 hours) depending on the back-end availability, the polling consumes a lot of resources (web server, network, etc.)

Clemens's solution (if I well remember) is based on a duplex message pattern, when ready the service will send the response to the consumer. This introduces some complexities when you have firewalls.

I personally think, that we need all the above solutions: request/response (give mi the list of products you sell), duplex and polling. Just because with distributed applications we have many scenario.

What do you think ?

Regards,
Pierre
mtaulty wrote re: Message Request/Response Patterns in Web Services
on Mon, Aug 2 2004 1:01 AM
Gerke,

I agree in that it would be ideal to not have to consider how the client(s) would work when designing the service but if you were trying to design a generally accessible service today you would have to factor this in or else you'd have very few service-users because most clients will not accept incoming connections.

Pierre,

I agree - polling's not a great solution (although we could mitigate polling by having the service issue some idea of response time when it issues the receipt). You're right in that we need all 3 message exchange patterns.

I think I'm still with my original point that if you want to design this kind of thing today and have it work with today's technologies and today's clients then the response message to requests needs to look something like;

<response>
<receipt callback="1 hour" id="xyz"/>
</response>

or

<response>
<businessResponse>
..
</businessResponse>
</response>