• Plone Web Services discussion

  • Re: Making wsapi4plone.core speak JSON-RPC in addition to XML-RPC

    from nateaune on Sep 12, 2009 12:34 PM
    I'm at the jQuery conference (http://events.jquery.com) and during Paul
    Irish's talk, I started poking around his code repository, and found JSON-P
    DB which utilizes Google App Engine's datastore in order to provide a
    persistent warehouse for arbitrary JSON objects that are made easily
    accessible from client-side javascript code via
    JSON-P<http://www.json.com/2007/12/24/jsonp-header-transfer-proposal/>
    
    check it out here:
    http://jsonpdb.appspot.com/index.html
    
    the code for this is here:
    http://code.paulirish.com/jsonpdb.appspot.com/
    
    Nate
    
    On Thu, Sep 10, 2009 at 1:52 PM, Michael Mulich <mrm41@...> wrote:
    
    > Michael Mulich wrote:
    >
    >> How do we make a XML-RPC view method a JSON-RPC view method.  I had an
    >> idea that the view's method could simply be decorated, thereby adding
    >> functionality to the call without obscuring the code readability.  There are
    >> some problems with this approach that I'd like to discuss.
    >>
    >> I've created a new package called wsapi4plone.transport.[1]  At the moment
    >> the package only contains a decorator.  It is being used i another new
    >> package, wsapi4plone.remotemgmt.[2]  This is how a view would look like with
    >> the transport in use:
    >>
    >> from Products.Five import BrowserView
    >> from wsapi4plone.transport import transport
    >>
    >> class MyCallWithOutParams(BrowserView):
    >>   @transport
    >>   def __call__(self):
    >>       return None
    >>
    >> class MyCallWithParams(BrowserView):
    >>   @transport
    >>   def __call__(self, param, additonal_stuff=None):
    >>       return None
    >>
    >> The transport decorator wraps the call in order to decode the request and
    >> encode the response.  The decorator works great in the first example, no
    >> matter what is returned, because the results are simply sent through
    >> simplejson.
    >>
    >> The second example (MyCallWithParams) causes two problems:
    >> 1) ZPublisher.mapply was preventing the calls from publishing, because
    >> they either had to few or to many arguments. The issue was resolved by
    >> faking the positional arguments. This was done by providing the correct
    >> argument count via lambda functions. The default arguments must also be
    >> declared in the lambda; therefore, a two dimensional dictionary of argument
    >> count to default argument count was created. However, this approach has its
    >> limit and is not an exhausted list of possibilities. As it stands, the
    >> arguments count dictionary will only supports argument counts less than or
    >> equal to THREE and raise a RuntimeError during startup if there are more. 2)
    >> The arguments are relabeled (a, b, c, ...) in the lambda code, which is a
    >> problem in JSON-RPC, because JSON-RPC requests pass parameters as urlencoded
    >> values.  So where http://example.com/index?param=foo&additional_stuff=barwould normally be valid, it must now be
    >> http://example.com/index?b=foo&c=bar.  Again this is because the
    >> arguments names have been changed to basically say something like "lambda a,
    >> b, c=None: __call__(self=a, param=b, additional_stuff=c)".
    >>
    >> Both of these problems are serious deal breakers.  The first problem was
    >> worked around, but caused the second problem.  If I happen to fix the second
    >> problem, I have a feeling it was cause a third.
    >>
    >> Thoughts about this approach or a better one would be great. =D
    >>
    >> -Michael Mulich (pumazi)
    >>
    >>
    >> [1]
    >> https://weblion.psu.edu/trac/weblion/browser/weblion/wsapi4plone.transport/trunk
    >> [2]
    >> https://weblion.psu.edu/trac/weblion/browser/weblion/wsapi4plone.remotemgmt/trunk
    >>
    >>
    > The first two issues are fixed for now.  The solution is alright, but far
    > from perfect.  Building the lambda as a string and evaluating it to get the
    > correct argument names fixed the issue.  Yes, that is ugly, but it only
    > happens once on startup.  So, I sheepishly say "hurray!"
    >
    > I'm using jQuery to make JSON-RPC request.  Let's have a look at what I'm
    > doing (example extracted from the wsapi4plone.remotemgmt index view):
    >
    > var siteId = "muppets";
    > var params = {"title": "Muppets in Outer Space", "description": "Fan site
    > for the the Muppets"}
    > var data = {id_: siteId, params: $.toJSON(params)};
    > $.getJSON("createSite", data, function(json) { alert(json); });
    >
    > So far so good!
    >
    > I'm playing with the thought of using martian instead of the decorator to
    > help in providing the transport code.  I'm going to think about it a bit
    > before attempting to code that.
    >
    > -Michael Mulich (pumazi)
    >
    >
    >
    > --
    > Archive:
    > http://www.coactivate.org/projects/plone-web-services/lists/plone-web-services-discussion/archive/2009/09/1252605161715
    >
    > To unsubscribe send an email with subject "unsubscribe" to
    > plone-web-services-discussion@....  Please contact
    > plone-web-services-discussion-manager@... for questions.
    >
    >
    
    
    -- 
    Nate Aune - natea@...
    http://www.jazkarta.com
    http://card.ly/natea
    +1 (617) 517-4953
    
    ** Learn best practices for deploying your Plone sites at our upcoming Plone
    Deployment Training in Budapest **
    http://plonedeployment-natesig.eventbrite.com
    
    
    Thread Outline:
  • Re: Making wsapi4plone.core speak JSON-RPC in addition to XML-RPC

    from nateaune on Sep 12, 2009 02:46 PM
    This is also a cool javascript widget for editing JSON data in the browser:
    http://blog.andrewcantino.com/2009/02/17/javascript-json-editor/
    
    Nate
    
    On Sat, Sep 12, 2009 at 12:33 PM, Nate Aune <natea@...> wrote:
    
    > I'm at the jQuery conference (http://events.jquery.com) and during Paul
    > Irish's talk, I started poking around his code repository, and found JSON-P
    > DB which utilizes Google App Engine's datastore in order to provide a
    > persistent warehouse for arbitrary JSON objects that are made easily
    > accessible from client-side javascript code via JSON-P<http://www.json.com/2007/12/24/jsonp-header-transfer-proposal/>
    >
    > check it out here:
    > http://jsonpdb.appspot.com/index.html
    >
    > the code for this is here:
    > http://code.paulirish.com/jsonpdb.appspot.com/
    >
    > Nate
    >
    >
    > On Thu, Sep 10, 2009 at 1:52 PM, Michael Mulich <mrm41@...> wrote:
    >
    >> Michael Mulich wrote:
    >>
    >>> How do we make a XML-RPC view method a JSON-RPC view method.  I had an
    >>> idea that the view's method could simply be decorated, thereby adding
    >>> functionality to the call without obscuring the code readability.  There are
    >>> some problems with this approach that I'd like to discuss.
    >>>
    >>> I've created a new package called wsapi4plone.transport.[1]  At the
    >>> moment the package only contains a decorator.  It is being used i another
    >>> new package, wsapi4plone.remotemgmt.[2]  This is how a view would look like
    >>> with the transport in use:
    >>>
    >>> from Products.Five import BrowserView
    >>> from wsapi4plone.transport import transport
    >>>
    >>> class MyCallWithOutParams(BrowserView):
    >>>   @transport
    >>>   def __call__(self):
    >>>       return None
    >>>
    >>> class MyCallWithParams(BrowserView):
    >>>   @transport
    >>>   def __call__(self, param, additonal_stuff=None):
    >>>       return None
    >>>
    >>> The transport decorator wraps the call in order to decode the request and
    >>> encode the response.  The decorator works great in the first example, no
    >>> matter what is returned, because the results are simply sent through
    >>> simplejson.
    >>>
    >>> The second example (MyCallWithParams) causes two problems:
    >>> 1) ZPublisher.mapply was preventing the calls from publishing, because
    >>> they either had to few or to many arguments. The issue was resolved by
    >>> faking the positional arguments. This was done by providing the correct
    >>> argument count via lambda functions. The default arguments must also be
    >>> declared in the lambda; therefore, a two dimensional dictionary of argument
    >>> count to default argument count was created. However, this approach has its
    >>> limit and is not an exhausted list of possibilities. As it stands, the
    >>> arguments count dictionary will only supports argument counts less than or
    >>> equal to THREE and raise a RuntimeError during startup if there are more. 2)
    >>> The arguments are relabeled (a, b, c, ...) in the lambda code, which is a
    >>> problem in JSON-RPC, because JSON-RPC requests pass parameters as urlencoded
    >>> values.  So where
    >>> http://example.com/index?param=foo&additional_stuff=bar would normally
    >>> be valid, it must now be http://example.com/index?b=foo&c=bar.  Again
    >>> this is because the arguments names have been changed to basically say
    >>> something like "lambda a, b, c=None: __call__(self=a, param=b,
    >>> additional_stuff=c)".
    >>>
    >>> Both of these problems are serious deal breakers.  The first problem was
    >>> worked around, but caused the second problem.  If I happen to fix the second
    >>> problem, I have a feeling it was cause a third.
    >>>
    >>> Thoughts about this approach or a better one would be great. =D
    >>>
    >>> -Michael Mulich (pumazi)
    >>>
    >>>
    >>> [1]
    >>> https://weblion.psu.edu/trac/weblion/browser/weblion/wsapi4plone.transport/trunk
    >>> [2]
    >>> https://weblion.psu.edu/trac/weblion/browser/weblion/wsapi4plone.remotemgmt/trunk
    >>>
    >>>
    >> The first two issues are fixed for now.  The solution is alright, but far
    >> from perfect.  Building the lambda as a string and evaluating it to get the
    >> correct argument names fixed the issue.  Yes, that is ugly, but it only
    >> happens once on startup.  So, I sheepishly say "hurray!"
    >>
    >> I'm using jQuery to make JSON-RPC request.  Let's have a look at what I'm
    >> doing (example extracted from the wsapi4plone.remotemgmt index view):
    >>
    >> var siteId = "muppets";
    >> var params = {"title": "Muppets in Outer Space", "description": "Fan site
    >> for the the Muppets"}
    >> var data = {id_: siteId, params: $.toJSON(params)};
    >> $.getJSON("createSite", data, function(json) { alert(json); });
    >>
    >> So far so good!
    >>
    >> I'm playing with the thought of using martian instead of the decorator to
    >> help in providing the transport code.  I'm going to think about it a bit
    >> before attempting to code that.
    >>
    >> -Michael Mulich (pumazi)
    >>
    >>
    >>
    >> --
    >> Archive:
    >> http://www.coactivate.org/projects/plone-web-services/lists/plone-web-services-discussion/archive/2009/09/1252605161715
    >>
    >> To unsubscribe send an email with subject "unsubscribe" to
    >> plone-web-services-discussion@....  Please contact
    >> plone-web-services-discussion-manager@... for questions.
    >>
    >>
    >
    >
    > --
    > Nate Aune - natea@...
    > http://www.jazkarta.com
    > http://card.ly/natea
    > +1 (617) 517-4953
    >
    > ** Learn best practices for deploying your Plone sites at our upcoming
    > Plone Deployment Training in Budapest **
    > http://plonedeployment-natesig.eventbrite.com
    >
    
    
    
    -- 
    Nate Aune - natea@...
    http://www.jazkarta.com
    http://card.ly/natea
    +1 (617) 517-4953
    
    ** Learn best practices for deploying your Plone sites at our upcoming Plone
    Deployment Training in Budapest **
    http://plonedeployment-natesig.eventbrite.com