[Catalyst] How to de-serialize json?

J. Shirley jshirley at gmail.com
Sat Jan 23 21:40:30 GMT 2010


On Sat, Jan 23, 2010 at 10:16 AM, Bill Moseley <moseley at hank.org> wrote:
> Following up on our recent simulating discussion on adding an API to an
> application, I wonder is someone can help me understand something:
>
> Catalyst uses HTTP::Body to parse body content.  It currently handles these
> request content types:
>
> our $TYPES = {
>     'application/octet-stream'          => 'HTTP::Body::OctetStream',
>     'application/x-www-form-urlencoded' => 'HTTP::Body::UrlEncoded',
>     'multipart/form-data'               => 'HTTP::Body::MultiPart',
>     'multipart/related'                 => 'HTTP::Body::XFormsMultipart',
>     'application/xml'                   => 'HTTP::Body::XForms'
> };
>
> But, Catalyst::Controller::DBIC::API and Catalyst::Controller::Rest both use
> Catalyst::Action::Deserialize.
>
> My question is this:  why use an action class instead of extending
> HTTP::Body to deserialize the content?  Isn't it HTTP::Body's job to decode
> the body based on the content-type of the request?
>
> I'm just wondering if I'm missing some important reason why these other
> request content types are handled differently.
>
> Seems like HTTP::Body is the correct place to do all decoding.  Decoded
> JSON, for example, would just end up in $c->req->params and controllers
> could be oblivious to the encoding of the request (similar to how we don't
> really care how params are decoded if the body is x-www-form-urlencoded or
> form-data).   True, could end up with a request parameter that is a hashref,
> but I don't see anything wrong with that as long as parameters are validated
> correctly.
>
> So, why different approaches to decoding request body content?
>
>

Well, I never really equated deserialization to decoding, so my answer
may not be fully satisfactory.

If I assume that decoding is synonymous with de-serialization, it
makes more sense.  At first thought, I just don't think they're that
similar, though.  Maybe in implementations (comparing JSON to HTTP
POST parameters) it is, but in the case of HTTP::Body decoding a
mime64-encoded JPEG, it isn't at all.

>From a behavior standpoint, having a POST/PUT'd JSON segment that ends
up in ->params would be maddening to me.  They aren't parameters, not
even in the loosest of the RFC interpretations.

I can appreciate wanting to increase the reusability, and having a
deserialization component in HTTP::Body (which, in turn could be used
for Form, etc).

If HTTP::Body could support this, Catalyst::Action::REST wouldn't be
tremendously different, it has the Deserialize action so you can
specify arbitrary deserialization schemes (after the body is decoded).
 You'd still need this behavior, still have the action.

Not a bad idea, those are my thoughts on it... and to summarize in one
sentence: it does seem like a good idea that could end up with a lot
of hacking and not a lot of practical savings.

-J



More information about the Catalyst mailing list