JSON::XS for json responses

414 views
Skip to first unread message

njzt

unread,
Nov 25, 2014, 4:53:40 AM11/25/14
to mojol...@googlegroups.com
Hi guys, do you have any idea how JSON::XS can be used to handle json responses in Mojolicious? MOJO::JSON works fine but switching to JSON::XS can increase the performance when large datasets are serialized to response. I have checked few threads here but there is no recommended solution.

Alberto Mijares

unread,
Nov 25, 2014, 5:31:22 AM11/25/14
to Mojo Users Group
What about Mojo::JSON::XS?

Regards


Alberto Mijares

sri

unread,
Nov 25, 2014, 10:32:34 AM11/25/14
to mojol...@googlegroups.com
There's a lot of modules for this already on CPAN, sadly most of them are terrible, it would be great if someone released one that actually worked most of the time.

    package Mojo::JSONXS;

    use Cpanel::JSON::XS;
    use Mojo::JSON;
    use Mojo::Util 'monkey_patch';

    my $BINARY = Cpanel::JSON::XS->new->utf8(1)->allow_nonref(1)->allow_blessed(1)
      ->convert_blessed(1);
    my $TEXT = Cpanel::JSON::XS->new->utf8(0)->allow_nonref(1)->allow_blessed(1)
      ->convert_blessed(1);

    monkey_patch 'Mojo::JSON', 'encode_json', sub { $BINARY->encode(shift) };
    monkey_patch 'Mojo::JSON', 'decode_json', sub { $BINARY->decode(shift) };

    monkey_patch 'Mojo::JSON', 'to_json',   sub { $TEXT->encode(shift) };
    monkey_patch 'Mojo::JSON', 'from_json', sub { $TEXT->decode(shift) };

    monkey_patch 'Mojo::JSON', 'true',  sub { Cpanel::JSON::XS::true() };
    monkey_patch 'Mojo::JSON', 'false', sub { Cpanel::JSON::XS::false() };

    1;

It's not even very hard, this one for example should cover pretty much all use cases.

    perl -MMojo::JSONXS -Mojo -E 'say app->build_controller->render_to_string(json => {foo => "/bar/baz", yada => Mojo::JSON->true})'

--
sebastian

sri

unread,
Nov 25, 2014, 10:38:23 AM11/25/14
to mojol...@googlegroups.com
    perl -MMojo::JSONXS -Mojo -E 'say app->build_controller->render_to_string(json => {foo => "/bar/baz", yada => Mojo::JSON->true})'

Btw. I'm intentionally using "/bar/baz" here, because *::JSON::XS encodes that value differently, due to a new security feature in Mojo::JSON.


--
sebastian

njzt

unread,
Nov 27, 2014, 6:40:39 AM11/27/14
to mojol...@googlegroups.com
    package Mojo::JSONXS;
 
Thanks for quick response, I will try with this one.

Jeremy Zawodny

unread,
Dec 3, 2014, 6:30:14 PM12/3/14
to mojol...@googlegroups.com
I have just uploaded Mojo-JSONXS-0.001-TRIAL.tar.gz to PAUSE and it should appear on CPAN sites soon.

If nobody screams, I'll release a non-trial version in a couple of days.

(This has been on my TODO list anyway, but sri's message prompted me to cut-n-paste and get it done finally).

Jeremy

sri

unread,
Dec 3, 2014, 6:37:47 PM12/3/14
to mojol...@googlegroups.com
If nobody screams, I'll release a non-trial version in a couple of days.

Not sure why it hasn't been announced here, but there's Mojo::JSON_XS already.


--
sebastian

Jeremy Zawodny

unread,
Dec 3, 2014, 6:40:36 PM12/3/14
to mojol...@googlegroups.com
Well, on the plus side I have a working Dist::Zilla setup finally. :-)

Jeremy

Dan Book

unread,
Dec 30, 2014, 2:13:59 AM12/30/14
to mojol...@googlegroups.com
FYI (now that I am on this group) I uploaded Mojo::JSON::MaybeXS a while back also based on sri's earlier post, which will use the fallback behavior of JSON::MaybeXS and default to Cpanel::JSON::XS. On a related note Cpanel::JSON::XS has recently fixed the handling of upgraded numbers and inf/nan so if you have the newest version it works even better.

njzt

unread,
Mar 11, 2015, 8:59:00 AM3/11/15
to mojol...@googlegroups.com

Not sure why it hasn't been announced here, but there's Mojo::JSON_XS already.


--
sebastian

I use this mentioned solution and recently I found one issue. There is monkeypatch on MOJO::JSON::true (and false) which looks like:

monkey_patch 'Mojo::JSON', 'true',  sub { Cpanel::JSON::XS::true() };

and Mojo::JSON has following method:

sub true () {$TRUE}

The problem is that in _decode_value Mojo::JSON still uses $TRUE variable instead of calling correctly monkeypatched true() method,

return $TRUE if /\Gtrue/gc; # seems that it would work with "return true()"

 As the result all Boolean values are still decoded to Mojo::JSON::_Bool which later are not handled correctly by JSON::XS encoder (with allow_bleseed & convert_blessed enabled). Do you have some idea how can I easily handle these boolean values? 

Dan Book

unread,
Mar 11, 2015, 10:06:12 AM3/11/15
to mojol...@googlegroups.com
I submitted a PR for this issue. https://github.com/kraih/mojo/pull/758
Thanks!

--
You received this message because you are subscribed to the Google Groups "Mojolicious" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mojolicious...@googlegroups.com.
To post to this group, send email to mojol...@googlegroups.com.
Visit this group at http://groups.google.com/group/mojolicious.
For more options, visit https://groups.google.com/d/optout.

Dan Book

unread,
Mar 11, 2015, 12:04:57 PM3/11/15
to mojol...@googlegroups.com
Actually _decode_value from Mojo::JSON should also be overridden by the monkey patching. Are you sure you have used the modules correctly?

njzt

unread,
Mar 11, 2015, 12:25:52 PM3/11/15
to mojol...@googlegroups.com
You are right, out of my app it works like expected. I have a helper in my plugin where $self->req->json still returns MOJO::JSON::_bool. I need to investigate it deeper. Sorry for this confusion.
Reply all
Reply to author
Forward
0 new messages