ckage Kelp::Module::JSON;
use Kelp::Base 'Kelp::Module::Encoder';
use JSON::MaybeXS;
sub encoder_name { 'json' }
sub build_encoder
{
my ($self, $args) = @_;
return JSON::MaybeXS->new(%$arg
;
$self->SUPER::build(%args);
$self->register(json => $self->get_encoder);
}
1;
__END__
=head1 NAME
Kelp::Module::JSON - Simple JSON module for a Kelp application
=head1 SYNOPSIS
pa
json configured to UTF-8
$self->res->set_charset('UTF-8');
$self->res->render_binary(
$self->json->encode({ yes => 1 })
);
}
=head1 DESCRIPTION
Standard JSON
for encoders which want to be compilant with the new
L<Kelp/get_encoder> method. L<Kelp::Module::JSON> is one of such modules.
This allows to have all encoders in one easy to reach spot rather than
<Kelp::Response>
object for the current route.
# Inside a route
res->code(403);
res->json->render({ message => "Forbidden" });
=head2 template
A shortcut to C<$self-E<gt>res-E<gt>templa
ule
Loads a Kelp module. The module options may be specified after the module name.
module 'JSON::XS', pretty => 1;
=head2 config
Provides procedural interface to the configuration.
get '
ub is_html
{
return $_[0]->content_type_is('text/html');
}
sub is_json
{
return $_[0]->content_type_is('application/json');
}
sub is_xml
{
return $_[0]->content_type_is('application/xml'
$self->SUPER::content(@_));
}
sub json_content
{
my $self = shift;
return undef unless $self->is_json;
return try {
$self->app->get_encoder(json => 'internal')->decode($self->con
undef;
};
}
sub param
{
my $self = shift;
if ($self->is_json && $self->app->can('json')) {
return $self->json_param(@_);
}
# safe method without calling Plack::Request::
# app.psgi
use Kelp::Less;
module 'JSON';
get '/api/:user/?action' => sub {
my ( $self, $user, $action ) = @_;
my $json = {
success => \1,
use
r => $user,
action => $action // 'ask'
};
return $json;
};
run;
=head2 Using the C<kelp-generator> script
The easiest way to create the directory structure a
my $key = 'parameter_name';
# fetch parameters from query form, body form or JSON body
my $json_or_body_or_query = $self->param($key);
my $always_query = $self->res->query_pa
onfiguration.
=head2 register
C<register( %items )>
Registers one or many methods into the web application.
$self->register(
json => JSON->new,
yaml => YAML->new
);
=cut
lhost:5000',
# Modules to load
modules => [qw/JSON Template/],
# Encoders
encoders => {
json => {
internal => {
utf8 =
$self->app->path . '/../views'
]
},
# JSON
JSON => {
allow_blessed => 1,
convert_blessed => 1,
ill remove the elements from the array:
# in config.pl
{
modules => [qw/Template JSON Logger/]
}
# in test.pl
{
'-modules' => [qw/Logger/] # Remove the Logger mo
elf->charset || $self->app->charset);
return $self;
}
sub json
{
my $self = shift;
$self->set_content_type('application/json', $self->charset || $self->app->charset);
return $self;
}
self->content_type;
if (!$ct || $ct =~ m{^application/json}i) {
$self->json if !$ct;
return $self->app->get_encoder(json => 'internal')->encode($body);
}
else {
cr
der("<h1>It works!</h1>");
}
# Render a mysterious JSON structure
sub json {
my $self = shift;
$self->res->json->render({ why => 'no' });
}
# Render the stock 404
|| $self->diag_headers();
return $self;
}
sub json_content
{
my $self = shift;
my $result;
my $decoder = $self->app->get_encoder(json => 'internal');
try {
$result = $deco
ormatted JSON");
};
return $result;
}
sub json_cmp
{
my ($self, $expected, $test_name) = @_;
local $Test::Builder::Level = $Test::Builder::Level + 1;
$test_name ||= "JSON structu
r('content-type'), qr/json/, 'Content-Type is JSON'
or return $self;
my $json = $self->json_content;
cmp_deeply($json, $expected, $test_name) or diag explain $json;
return $self;
}
nd JSON responses.
=item
B<JSON encoder/decoder>. Kelp can handle JSON-formatted requests and responses
automatically, making working with JSON much more enjoyable. On top of that, it
uses L<JSON::M
Template and JSON, then a dump of
the C<loaded_modules> hash will look like this:
{
Template => Kelp::Module::Template=HASH(0x208f6e8),
JSON => Kelp::Module::JSON=HASH(0x209d4
p::Request> instance.
sub some_route {
my $self = shift;
if ( $self->req->is_json ) {
...
}
}
This attribute is a proxy to the same attribute in L</contex