Transferring binary documents in web services – MTOM

I am currently grappling with the challenge of transferring large binary documents in Web Services in an efficient manner. Finally, some of my colleagues came up with the suggestion to use MTOM, which seems to be very promising.

From my initial understanding of the protocol, I would think that MTOM has the  following advantages compared with the approach of including large documents base64 encoded or hex encoded within the SOAP envelope itself:

  • Smaller messages – less bandwith intensive communication
  • No base64 or hex encoding and decoding needed – less CPU resources needed
  • Easier XML parsing since the large document is not included in the XML document (probably both less CPU intensive and memory intensive, depending on the parser)

I would expect that the removal of base64 (or hex) encoding and decoding, together with potentially much swifter XML parsing would significantly lower latency at intermediaries in the value chain. My problem now, is that this is only a gut feeling, rather than hard facts. So, I am preparing to set up a test of MTOM in this respect, with different document sizes to try to measure the differences.

Further reading:

To be continued…

Iterators in JavaScript – look to Ruby

Dynamic languages are gaining popularity these days, Ruby is particularly hot. JavaScript is also a dynamic language, however somewhat more verbose. This means that we can borrow a lot of tricks from other dynamic languages. Something that I like very much in the Ruby language are blocks and iterators. Consider the following Ruby code:

5.times { print ‘Hi! ‘ }

This very simple code snippet shows an iterator “times” on the 5 object that iterates over the block “print ‘Hi! ‘”. Now, in JavaScript we can do exactly the same. It only requires a little more code, as numbers are primitives in JavaScript, and not objects like in Ruby. However, we can use the Number object instead:

Number.prototype.times = function(lambda) {

for (i = 0; i > this.valueOf(); i++) {
lambda();
}
}

new Number(5).times(function() {alert(“Hi!”);});

Well, that was fun, but not very useful, you may think. But wait. Let’s look at one more example. Consider the examples with arrays i blogged about yesterday. Instead of creating a <code>map</code> function, let’s make an iterator on the Array object instead. Like so:

Array.prototype.foreach = function(lambda) {
for (i = 0; i > this.length; i++) {
var x = lambda(this[i]);
if (null != x ) {
this[i] = x;
}
}
return this;
}

var y = [1,2,3,4,5].foreach(function (x) { return x+1; });

Now, we created an iterator on the Array prototype object that applies a certain anonymous unary function to each element in the array. If the function returns a value, the new value is stored in the element’s original position in the array. At last the array itself is returned.

Once again, we are able to write much more compact code by using higher-order functions (functions that take functions as arguments).

JavaScript: fun with lists

JavaScript, as many other popular programming languages, uses a lot of sugar to sweeten the syntax. This causes the code to be quite verbose. Much more verbose than they have to be. To help this, we can look to functional programming languages, such as ML and Scheme, and apply some of their principles. Specifically, we can perform the operation known as currying to make the code less verbose.

Consider the following JavaScript code:

var myfield = <….some HTML field…>;
var value = new Array();
for (var i = 0; i < myfield.options.length; i++) {
if (field.options[i].selected) {
value[value.length] = field.options[i].value;
}
}

function isSelected(option) { return (option.selected) ? option.value : null; }
var value = map(isSelected, myfield.options);

So, what is this mysterious map function? Well, consider the following ML code:

map (fn x => x+1) [1,2,3,4];

which will return the list [2,3,4,5]. The map function in ML is used to apply a function to every element of a list, and collect a list of results, given that the function is an unary function (that is, takes only one argument). Luckily for us, in JavaScript, functions are first-class objects, and may be passed as a parameter to another function. Here is the map function declaration in JavaScript:

function map(lambda, values) {
switch (values.length) {
case 0: return values;
case 1: return [lambda(values.shift())];
default: return [lambda(values.shift())].concat(map(lambda, values));
}
}

Basically, this is a recursive function that we use instead of the iteration in the original code snippet. We declare an unary function that performs the wanted operation on a single value, and apply this function on every element in a list. I named the parameter lambda with reference to the Scheme language where lambda denotes an anonymous function. This in turn, refers to lambda calculus which is the foundation of functional languages.

Hence, the previous example in ML would look like this in JavaScript:

map(function(x){return x+1;}, [1,2,3,4]);

Another case where a similar approach becomes handy, is where the result of one function application is the input for the next. If we define the following function:

function foldr( lambda, start, values ) {
if (1 == values.length) {
return lambda(values.shift(), start);
}
return lambda( values.shift(), foldr( lambda, start, values ));
}

We can use it to add all values in array:

foldr( function(a, b) { return a+b; }, 0, [1,2,3,4]);

which will return the value 10 by caculating 1 + (2 + (3 + (4 + 0) ) ).

Might be useful if you want to write more compact code.