ruby / xmlrpc

The Ruby standard library package 'xmlrpc'
Other
37 stars 26 forks source link

Easier way to serialize objects over XMLRPC #15

Open herwinw opened 7 years ago

herwinw commented 7 years ago

Currently there is no simple way to transport a non-default object over XMLRPC with this lib.

Contrived example

We have a Money class, with 3 values: currency (like Dollar, Euro, Yen), whole and cents. With Money.new(:dollar, 13, 37) we'd create a new object to represent $ 13.37.

Current ways to transfer this over XMLRPC:

Convert it to a more basic structure

We could convert this object manually to the String "$ 13.37" and transfer this. This means manual intervention on every XMLRPC call.

Use XMLRPC::Marshallable

This would result in marshalled objects that look pretty specific to Ruby, which would stop interoperability with other languages. This same problem arises when using Marshall or YAML to dump the structure.

Use Structs

There is logic to write structs over XMLRPC, but this loses the class name. If we had an abstract Money class that didn't save the currency, but instead had a Dollar, Euro and Yen subclass (like I said: contrived example), everything would be marshalled as the value only, without the currency. It basicly converts a Struct to a Hash

Override XMLRPC::Create#wrong_type

We could include duck typing here, but that feels cumbersome

Proposed solutions

I think there are two possible options to improve this:

Duck typing on to_xmlrpc

Allow classes to implement a #to_xmlrpc method, call that if applicable and use that converted value. This is comparable with things like #to_json. A point of discussion here is we'd have to have the method create an XMLRPC element, or if it just enough to create a String, Integer, Hash or whatever and feed that back into conv2value

Register classes in XMLRPC::Create

A different solution would be to register a class and conversion block in XMLRPC::Create, syntax would be a bit like this:

XMLRPC::Create.register_serializer(Money) { |obj| "MONEY: #{obj}" }

Where the exact value would depend upon agreements between client and server