views:

63

answers:

5

Is it more or less acceptable (i.e. standard) to create a publicly-exposed web service with these method signatures:

ThisMethodDoesSomething(ComplexType param)

ThisMethodDoesSomethingElse(AnotherComplexType param)

Or this:

ThisMethodDoesSomethingAndSomethingElse(string xml)

Where the operation being performed depends upon the XML string passed to a single does-it-all method? I have always gone with the former, but a coworker of mine prefers the latter and I'm trying to weigh pros and cons of both strategies before we begin a new project. Which is more accepted and easier for the public to work with and why?

A: 

I prefer (and that is the operative word, prefer, for there is no standard for this) a complex XML string that explains the action. You can see this from my open-source project.

Some of the reasons I prefer it...

  1. Your actions are an interpreted language that can flex.
  2. Actions can be compounded into a single network trip.
  3. XML allows expansion of the feature set while not breaking past features.
  4. XML hierarchy allows actions to act upon actions server-side.
dacracot
Thanks for the reply.On the surface, this just feels wrong to me, sort of like: why should I pass int or double around in my program when object will do? Object is more flexible, right?The other reason I don't gravitate toward this approach is Method(string) is not as self-documenting as Method(int) or Method(otherType).Your points 1 and 3 make sense.Could you expand upon points 2 and 4 a bit?
Brad Wesley
+1  A: 

Formerly I would have prefered the latter, because I wasn't sure, if in cross platform situation, every SOAP client would be able to consume the complex types properly. So I thought a SOAP call, that just takes and returns (XML-)Strings will give me no headache. In the meantime I experienced there is generally no problem with the first approach at least for .Net interoperating with JAVA/AXIS and vice versa. I'm still watching to make the complex type not too complex though.

I assume that ThisMethodDoesSomething() and ThisMethodDoesSomethingElse() are atomic operations? If this not the case (ThisMethodDoesSomethingElse() requires a call to ThisMethodDoesSomething() to execute), the first approach is a no go.

huo73
A: 

Your question sounds to me like a question of coarse grained vs fine grained interfaces at first glance. On the other hand, I feel like the second approach is taking coarse grained to the extreme, if you know what I mean. You lose all type checking. You make the implementation very difficult - you would need a lot of if cases inside the backing code to actually figure out what the request is about. What will the method return? I'm guessing if you are just getting a string as a parameter, you will return another string. Since it is a String, and I'm guessing it is a string representation of an XML document, you will have to make parsing part of your backing code. As the interface gets bigger, I presume these will turn into god methods. The list goes on :)

As a side note, don't think that I'm advocating very fine grained interfaces. There must be a balance between the two. A rule of thumb for me would be to always pass an element.

Selim
A: 

I typically create an xml schema to describe the messages that will form my interface. Then, using an xsd to class generator such as Castor or Microsoft xsd.exe, I create my implementation classes.

KC
+1  A: 

I would never send an XML string. First of all, "XML" is not the same thing as "string". They do not follow the same rules.

Any reasonable client can accept a complex type consisting of primitive types and lists or arrays of primitive types, recursively (C# syntax):

public class ComplexType1
{
    public int IntegerProperty {get;set;}
    public int[] ArrayOfIntegers {get;set;}
    public List<int> ListOfIntegers {get;set;} // Same as ArrayOfIntegers
}

public class ComplexType2
{
    public ComplexType1 CT1 {get;set;}
    public List<ComplexType1> LCT1 {get;set;}
}

Frankly, any client that can't deal with something like the above deserves to be retired.

John Saunders