Reference requirements

"Sadiq, Waqar" wrote:
>
> Ok.  I think I get it and sorry for not reading it like that.  In a sense
> that is also a requirement on the web services architecture work group that
> the web services should be able to support references.  For example, if I am
> not wrong, I think XMLP does not address specifying object references and
> how they can be passed back.  Would the underlying protocols have to support
> passing objects by reference before a description language can express it
> properly?
 
Well, yes, I think that SOAP is somewhat broken in this respect also.

But one can always pass a URI through SOAP so you can hack object
references. SOAP doesn't help you but it doesn't prevent you from
doing it either.

Once you have a URI, SOAP will not prevent you from calling methods on
the URIs that you retrieve as SOAP endpoints. Once again, SOAP doesn't
help you but it doesn't get in your way. (Most SOAP toolkits might get
in your way but that's a different issue).

But if WSDL does not let you describe the resulting service then you
really cannot realistically deploy it in a statically-typed programming
world. So it becomes quite hard to do anything beyond getStockQuote. ;)

All real web services need to deal with state somehow. Delegating that
to the application layer is a cop-out. WSDL is where the rubber will hit
the road. The cop-out will actually get in the way of people doing their
jobs and solving real-world problems. 

Consider the following use-case, call it UC0666 if you like:

I have many components that accept some kind of business document. All
of these business documents have certain common behaviors and in
particular they may be cancelled, approved or postponed. It must be
possible for one component (let's say the purchasing interface) to
report the existence of a document to another component (let's say the
purchasing approval workflow engine). The purchasing approval component
must be able to invoke the "cancel", "approve" or "postpone" methods on
the business document. 

Of course in simple cases one can always work around the lack of
references by passing around magic cookies to some kind of "purchase
order manager" but this scales very poorly because it means that ALL
access to purchase orders throughout the entire company must go through
a single component, just because it happens to implement the
cancel_based_on_cookie(), approve_based_on_cookie() and
postpone_based_on_cookie methods.

In programming terms the right way to do it is:

interface po:
   def approve():
      (do some authorization etc. and then change the state to cancel)

   def cancel():
      (do some authorization etc. and then change the state to cancel)

   def postpone():
      (do some authorization etc. and then change the state to cancel)

class purchasing_interface_1:
    def accept_purchase_order(address, items, etc. etc.):
        validate(address, items, etc. etc.)
        po = new PO(address, items, etc. etc.)
        my_list_of_purchase_orders.add(po)
        approval_engine.add(po)
        return po

class purchasing_interface_2: 
    # same basic thing but owned by different part of organization
    def our_accept_purchase_order(address, items, etc. etc.):
        validate(address, items, etc. etc.)
        po = new PO(address, items, etc. etc.)
        my_list_of_purchase_orders.add(po)
        approval_engine.add(po)
        return po


class approval_workflow_component:
    def ceo_says_approve(po):
        po.approve()

In programming terms the wrong way to do it is:

class po_manager:
   def new_po(address, item, etc.):
       cookie = make_new_cookie()
       my_list_of_purchase_orders.add(cookie, address, item)
       return cookie

   def approve(cookie):
      (do some authorization etc. and then change the state to cancel)

   def cancel(cookie):
      (do some authorization etc. and then change the state to cancel)

   def postpone(cookie):
      (do some authorization etc. and then change the state to cancel)

class purchasing_interface_1:
    def accept_purchase_order(address, items, etc. etc.):
        validate(address, items, etc. etc.)
        po_cookie = global_po_manager.new_po(address,item, etc.)
        approval_engine.add(po)
        return po_cookie

class purchasing_interface_2:
    def accept_purchase_order(address, items, etc. etc.):
        validate(address, items, etc. etc.)
        po_cookie = global_po_manager.new_po(address,item, etc.)
        approval_engine.add(po)
        return po_cookie

class approval_workflow_component:
    def ceo_says_approve(cookie):
        global_po_manager.approve(cookie)

Note how instead of just specifying the interface to purchase orders I
had to centralize everything through a single component that implemented
that interface for purchase orders from different parts of the company
that might not otherwise have had to be centralized. The centralization
decision should be a business decision and not forced by the weaknesses
of the description language.

WSDL needs to be able to define the abstract "purchase order" interface
and to describe methods like accept_purchase_order which return objects
of that type. At the SOAP level those would be URIs to dynamically
created endpoints representing those purchase orders.

 Paul Prescod

Received on Tuesday, 19 February 2002 06:41:11 UTC