Saturday, October 15, 2005
Broke ground w/SOAP, found Rubies and still not happy
Being new to SOAP, XFire and Ruby, I finally got my first SOAP call the way I wanted it:
- No SOAP specific code
- No getting dirty w/writing WSDL or reading/writing XML the wire
- Unit tests that are quick and easy to write

Java Service Implementation:

So I have a Service

class UserServiceImpl implements UserService {
public void createUser(String username, String pin) {
// do it

Unit test in ruby:

class UserServiceTestApi < Test::Unit::TestCase
def setup
@userService =

def test_createUser
@userService.createUser(:in0 => 'testApiUser', :in1=> '1234')

Wow, that's hot.

But I'm still not happy. Now I have to start passing objects: user objects, phone objects. And object graphs would be nice: users and their phones. SOAP can handle objects, that's why you'd use SOAP in the first place over XML-RPC or the like. I've seen XFire automatically describe objects I use in my API in the WSDL, but how does it do the object graph. Collections of other objects. Xfire can do all this, but I'll need to understand more here. This is where I fear the community arguments like "SOAP is not pure RPC, it's a way to send XML back and forth" come into play. I'll be fighting the WSDL and giving up 1 XML element at a time.

On a different note, up until now we've been writing a web site. I've been happy with the natural layers of abstraction :

[HTML Templates] + [Business Objects]
[Web Components] + [Business Objects]
[Data Access Objects] + [Business Objects]

Notice [Business Objects] live thru all layers

So a natural copy would be

[Web Client] + [Business Objects]
[Web Service] + [Business Objects]
[Data Access Objects] + [Business Objects]

Two problems with this:
1.) [Business Objects] contain code, that doesn't get sent over the wire. They turn into dumb bags of data, linking to other dumb bags of data.
2.) [Web Service] ends up duplicating every method in the [Data Access Objects] layer and end up being dumb data movers. Anying good in the [Web Service] layer you could argue would be more reusable in the [Data Access Object] layer.

This is what I want:
[Web Client] + [Business Data]
[Data Access Objects - Stuff] + [Business Data]
[Data Access Objects] + [Business Objects]

So I want to stip off methods in DAO that shouldn't be accessable via web service, and I need to strip business objects of all functionality, typically non-accessor methods so it's just a bag of properties.

I just have to write code that unwrites code.

The Data Access Objects, Xfire already does this via annotations, let's you take an existing DAO and mark methods as @WebMethods. Great, now I have to figure out how to describe the objects. Annotations seem like a good way, but hard part would be getting inside xfire wsdl and xml marshalling code to translate.

This is a lot of design in new areas for me and w/o a lot of examples, so I'm going to trudge thru a few DAOs and see how it goes.

So I started to write something on how bad of an idea it is to make objects into "dumb bag of data" and then I realized something...
I am actually not that crazy about what we do now: exposing bussiness in WEB layer. I like the convenience sometimes ("look it's a call group object - just call add user function on it") but I never know which functions I am allowed to call directly and which are only to be used through the particular service/context.
Also we would face similar issues working on a fat client application.
Ultimately though I am for pragmatic approach too that. SOAP API is for API users: it should offer interface that is convenient and easy for us to maintain. The division of labor between services and objects needs to be such that we can easily implement it. In other words the architecture should support whatever users want. And if it does not: too bad for architecture.
Post a Comment

<< Home

Powered by Blogger