Recently I started doing some work for a client for some integration between Salesforce and VerisonOne. When I first looked at how they were doing it, it was pretty clear there were some serious struggles which I kind of take personally (I was on the dev team for quite a while).

With the imposed limits of Apex, reusability is a must and for this case specifically, we were doing a lot of writes (POST). Since Apex now has an XML object that helps with creating those, I came up with a set of objects that handle creating the proper payload for posts to the VersionOne API.

First, I started off with creating a simple interface -- V1ApiXmlSetterNode that demands AddSetterAttributeNode and accepts a Dom.XmlNode. As of this writing, that's how VersionOne's API takes new content via a post to the rest-1.v1, for instance /rest-1.v1/Data/Story with an XML payload (query.v1 is in the works, so I'm told -- so stay tuned).

One thing worth noting here is if there's a null value, it's skipped. I did this just to keep junk across the wire and if I remember right, VersionOne cares about null vs empty string. For a multi-relation, such as tasks on a story, and there's nothing to relate, it also skips it -- simply ...

if (this.Value.size() == 0)

return;

It's also done for the relational attributes because of validation problems which could happen. On the lookup, I added in two other checks to determine if there's anything to lookup and if the key contains the value it's expected to set.

if (this.Value == null || lookup.size() == 0)

return;

if (!Lookup.containsKey(Value)) // possible error condition?

return;

I feel like if the key is missing, this is probably some kind of error condition and may need a notification sent. It's also possible to insert that value into VersionOne directly but I found that to be quite dangerous and could end up dumping a bunch of values into a system that really should never be there, so I highly recommend against it.

Inside of a Story for instance, the wiring between these two things look something like this...

The method XmlNodes builds up the necessary types for consuming later within the post back to VersionOne. I also put in a custom field example because those are used quite widely across our customers. This one in particular used 7 or so but others will vary.

So what does it look like when the HTTPRequest is ready to go? This is a bit of sudo code, but could easily be adapted to an existing request

public class V1Api {

public void SendStory(V1Story story)

{

Dom.Document doc = new Dom.Document();

dom.XmlNode root = doc.createRootElement('Asset', null, null);

for (V1ApiXmlSetterNode node: story.XmlNodes())

{

node.AddSetterAttributeNode(root);

}

//build up HTTPRequest

String body = doc.toXmlString();

request.setHeader('Content-Length', String.valueOf(body.length()));

request.setBody(doc);

//send request

}

}

The key on this the root node needs to be created and used as the container. Otherwise its really straight forward.

Next steps would be to create a simple process to build the classes up instead of having to manually write them up by using the meta.v1 and using that to parse out the files, which time permitting, I think its something worth doing and could help others make their integration a lot easier.