Hi,
By googling the Web for an XML-RPC implementation in Common Lisp, I found S-XML-RPC and other one for Corman Lisp. I'm glad that S-XML-RPC is now part of Common-Lisp.net.
By the way, looking at the Corman Lisp API for XML-RPC, I found interesting that it have the ability to define a standard function embedding an XML-RPC call. How about implementing this kind of thing in S-XML-RPC? I wrote the following lines of code:
(defmacro define-xmlrpc-method (name args &key url method) `(defun ,name ,args (xml-rpc-call (encode-xml-rpc-call ,method ,@args) :url ,(puri:uri-path url) :host ,(puri:uri-host url) :port ,(cond ((puri:uri-port url)) (t 80)))))
(define-xmlrpc-method get-state-name (state) :url #u"http://betty.userland.com/RPC2" :method "examples.getStateName")
(define-xmlrpc-method get-time () :url #u"http://time.xmlrpc.com/RPC2" :method "currentTime.getCurrentTime")
? (get-state-name 41) "South Dakota"
? (get-time) #<XML-RPC-TIME 20040617T10:47:31>
I rely on the great PURI package to parse URL. Quite straightforward. Of course, we should also wrap and unwrap some type convertions not to see anything about the XML-RPC types. I guess the function should also accept HASHTABLEs to be converted in XML-RPC structs.
What do you think?
On 17 Jun 2004, at 20:20, Frédéric Brunel wrote:
Hi,
By googling the Web for an XML-RPC implementation in Common Lisp, I found S-XML-RPC and other one for Corman Lisp. I'm glad that S-XML-RPC is now part of Common-Lisp.net.
By the way, looking at the Corman Lisp API for XML-RPC, I found interesting that it have the ability to define a standard function embedding an XML-RPC call. How about implementing this kind of thing in S-XML-RPC? I wrote the following lines of code:
(defmacro define-xmlrpc-method (name args &key url method) `(defun ,name ,args (xml-rpc-call (encode-xml-rpc-call ,method ,@args) :url ,(puri:uri-path url) :host ,(puri:uri-host url) :port ,(cond ((puri:uri-port url)) (t 80)))))
(define-xmlrpc-method get-state-name (state) :url #u"http://betty.userland.com/RPC2" :method "examples.getStateName")
(define-xmlrpc-method get-time () :url #u"http://time.xmlrpc.com/RPC2" :method "currentTime.getCurrentTime")
? (get-state-name 41) "South Dakota"
? (get-time) #<XML-RPC-TIME 20040617T10:47:31>
I rely on the great PURI package to parse URL. Quite straightforward.
I do like the general idea, maybe we could add the macro to extension.lisp - I would like to have some more time to think over all possible implications.
Of course, we should also wrap and unwrap some type convertions not to see anything about the XML-RPC types. I guess the function should also accept HASHTABLEs to be converted in XML-RPC structs.
What do you think?
There is a kind of problem with xml-rpc concering type conversions: xml-rpc itself supports only a limited number of types with no possibility to annotate them. I you want automatic conversions (like we have implemented it now), this will only take you one part of the way: for example, now cl sequences (lists and vectors) map to xml-rpc arrays, but when you get back an xml-rpc array you always get a list. Mapping cl structs, clos objects and hashtables to xml-rpc structs would work, but there would only be one return type.
The alternative (which is a lot more verbose) would be explicitely specify the xml-rpc call signature so that more complex (and usefull) conversions could be done (much like ffi). You could then say for example that a certain clos object is expected and converted to and from an xml-rpc struct. But this would then need to be extended to composite types, like arrays of a certain element type, or member types for slots ...
All this could be a very interesting and usefull extension. But one of the strengths of xml-rpc is its simplicity, especially in a dynamic language like lisp.
-- Frederic Brunel
Thanks for the feedback, frederic,
Sven
I do like the general idea, maybe we could add the macro to extension.lisp - I would like to have some more time to think over all possible implications.
You're right, I didn't think about the weak points of this method. I try to do more experiment with it.
Of course, we should also wrap and unwrap some type convertions not to see anything about the XML-RPC types. I guess the function should also accept HASHTABLEs to be converted in XML-RPC structs.
What do you think?
There is a kind of problem with xml-rpc concering type conversions: xml-rpc itself supports only a limited number of types with no possibility to annotate them. I you want automatic conversions (like we have implemented it now), this will only take you one part of the way: for example, now cl sequences (lists and vectors) map to xml-rpc arrays, but when you get back an xml-rpc array you always get a list. Mapping cl structs, clos objects and hashtables to xml-rpc structs would work, but there would only be one return type.
You're right but IMO you should decide a fixed number of types to be accepted by the XML-RPC interface. The Java implementation of XML-RPC accept only Hashtables when dealing with XML-RPC structures. I think you can do the same. Instead of building a XML-RPC-STRUCT, use a HASHTABLE. The only problem is with TIME since there is no TIME object in ANSI CL (too bad) you'll have to do it yourself like you did.
The alternative (which is a lot more verbose) would be explicitely specify the xml-rpc call signature so that more complex (and usefull) conversions could be done (much like ffi). You could then say for example that a certain clos object is expected and converted to and from an xml-rpc struct. But this would then need to be extended to composite types, like arrays of a certain element type, or member types for slots ...
All this could be a very interesting and usefull extension. But one of the strengths of xml-rpc is its simplicity, especially in a dynamic language like lisp.
Hmm. I think it's not a good idea. SOAP for example do this kind of thing and is too complex and too verbose. XML is good as far as simplicity is concerned. Keep it simple or it won't be used and from my experience, using XML Web services to send complex data and structures is just insane.
Thanks for the feedback, frederic,
You're welcome.
On 17 Jun 2004, at 20:20, Frédéric Brunel wrote:
Hi,
By googling the Web for an XML-RPC implementation in Common Lisp, I found S-XML-RPC and other one for Corman Lisp. I'm glad that S-XML-RPC is now part of Common-Lisp.net.
By the way, looking at the Corman Lisp API for XML-RPC, I found interesting that it have the ability to define a standard function embedding an XML-RPC call. How about implementing this kind of thing in S-XML-RPC? I wrote the following lines of code:
(defmacro define-xmlrpc-method (name args &key url method) `(defun ,name ,args (xml-rpc-call (encode-xml-rpc-call ,method ,@args) :url ,(puri:uri-path url) :host ,(puri:uri-host url) :port ,(cond ((puri:uri-port url)) (t 80)))))
(define-xmlrpc-method get-state-name (state) :url #u"http://betty.userland.com/RPC2" :method "examples.getStateName")
(define-xmlrpc-method get-time () :url #u"http://time.xmlrpc.com/RPC2" :method "currentTime.getCurrentTime")
? (get-state-name 41) "South Dakota"
? (get-time) #<XML-RPC-TIME 20040617T10:47:31>
I rely on the great PURI package to parse URL. Quite straightforward. Of course, we should also wrap and unwrap some type convertions not to see anything about the XML-RPC types. I guess the function should also accept HASHTABLEs to be converted in XML-RPC structs.
What do you think?
-- Frederic Brunel
I added your code in a file called define-xmlrpc-method.lisp that is not part of the project itself (because of its dependency on puri), but more an extension like aserve.lisp
Thanks for the contribution,
Sven
s-xml-rpc-devel@common-lisp.net