Explore using serializer and adaptor objects.
Add some docs re choosing ActiveModel vs JSONAPI vs HAL even if just links
Eg see http://discuss.emberjs.com/t/should-we-keep-using-ember-d
ta/7405/10
Add tests and docs for RouteMaker make_routes_for args and options
TODOs for JSON API:
- provide "links" separately to prefetch logic
- support collection urls, e.g. /phot
pplication/vnd.api+json media type
- support updating resources via the application/vnd.api+json media type
- support updating relationships via the application/vnd.api+json media type
Te
code_json';
requires 'item';
around '_build_content_types_provided' => sub {
my $orig = shift;
my $self = shift;
my $types = $self->$orig();
unshift @$types, { 'application/json' =>
vemodel' };
return $types;
};
#sub to_json_as_activemodel { return $_[0]->encode_json($_[0]->render_item_as_activemodel_hash($_[0]->item)) }
sub to_json_as_activemodel {
my $self = shift;
# XXX this narrowing ought to be moved elsewhere
# it's a bad idea to be a side effect of to_json_as_activemodel
my @id_cols = $self->set->result_source->unique_constraint_columns( $self->id_
RSION = '0.004002';
use Scalar::Util qw(blessed);
use Moo::Role;
requires 'decode_json';
requires 'encode_json';
requires 'render_item_as_plain_hash';
requires 'throwable';
requires 'item';
has m
uest content-type not application/json")
unless $self->request->header('Content-Type') =~ 'application/.*?json';
my $invoke_body_data = $self->decode_json($self->request->content);
$se
lf->throwable->throw_bad_request(400, errors => "Request content not a JSON hash")
unless ref $invoke_body_data eq 'HASH';
my @method_args;
if (my $args = delete $invoke_body_data->{a
e Moo::Role;
requires 'render_set_as_plain';
requires 'render_item_into_body';
requires 'decode_json';
requires 'set';
requires 'prefetch';
requires 'writable';
requires 'path_for_item';
requires 'a
=> 'lazy',
);
sub _build_content_types_accepted {
return [ {'application/vnd.wapid+json' => 'from_plain_json'} ]
}
around 'allowed_methods' => sub {
my $orig = shift;
my $self = shift;
create_path_after_handler { return 1 }
sub from_plain_json {
my $self = shift;
my $item = $self->create_resource( $self->decode_json($self->request->content) );
return $self->item($item
_json';
requires 'render_item_as_plain_hash';
has content_types_provided => (
is => 'lazy',
);
sub _build_content_types_provided {
return [ { 'application/vnd.wapid+json' => 'to_plain_json'
} ]
}
sub to_plain_json { return $_[0]->encode_json($_[0]->render_set_as_plain($_[0]->set)) }
sub allowed_methods { return [ qw(GET HEAD) ] }
# Avoid complaints about $set:
## no critic (NamingConv
quests representing set resources, e.g.
the rows of a database table.
Supports the C<application/json> content type.
=head1 NAME
WebAPI::DBIC::Resource::Role::Set - methods related to handling requ
rce::Role::DBIC::VERSION = '0.004002';
use Carp qw(croak confess);
use Devel::Dwarn;
use JSON::MaybeXS qw(JSON);
use Moo::Role;
requires 'uri_for';
requires 'throwable';
requires 'request';
requir
request->headers->header('Accept') =~ /hal\+json/) {
$body = $item_resource->to_json_as_hal;
}
else {
$body = $item_resource->to_json_as_plain;
}
$self->response->body
s = $self->request->query_parameters;
my @params = (%$override_params);
# XXX turns 'foo~json' into 'foo', and 'me.bar' into 'me'.
my %override_param_basenames = map { (split(/\W/,$_,2))[
IC::Role::JsonEncoder;
$WebAPI::DBIC::Role::JsonEncoder::VERSION = '0.004002';
use JSON::MaybeXS qw(JSON);
use Moo::Role;
has _json_encoder => (
is => 'ro',
builder => '_build_json_encoder',
handles => {
encode_json => 'encode',
decode_json => 'decode',
},
);
sub _build_json_encoder {
my $codec = JSON->new->ascii;
$codec->canonical->pretty if $ENV{WEBAPI_DBIC_D
ad1 NAME
WebAPI::DBIC::Role::JsonEncoder
=head1 VERSION
version 0.004002
=head1 NAME
WebAPI::DBIC::Resource::Role::JsonEncoder - provides encode_json and decode_json methods
=head1 AUTHOR
Tim B
equires 'encode_json';
has content_types_provided => (
is => 'lazy',
);
sub _build_content_types_provided {
return [
{ 'application/vnd.wapid+json' => 'to_plain_json' },
{ '
path");
return \302;
}
sub to_plain_json {
return $_[0]->encode_json($_[0]->render_root_as_plain());
}
sub render_root_as_plain { # informal JSON description, XXX liable to change
my
HEAD requests for requests representing the root resource, e.g. C</>.
Supports the C<application/json> content type.
=head1 NAME
WebAPI::DBIC::Resource::Role::Root - methods to handle requests for
004002';
use Carp qw(croak confess);
use Scalar::Util qw(blessed);
use Devel::Dwarn;
use JSON::MaybeXS qw(JSON);
use Moo::Role;
requires 'response';
sub finish_request {
my ($self, $metadata
e formal error structure, such as
# application/vnd.error+json => https://github.com/blongden/vnd.error
my $json = JSON->new->ascii->pretty;
my $response = $self->response;
;
my $body = $json->encode($error_data);
$response->body($body);
$response->content_length(length $body);
$response->content_type('application/json');
}
else {
also WebAPI::HTTP::Throwable::Role::JSONBody
use strict;
use warnings;
use parent 'HTTP::Throwable::Factory';
use Carp qw(carp cluck);
use JSON::MaybeXS qw(JSON);
sub extra_roles {
return (
'WebAPI::HTTP::Throwable::Role::JSONBody', # remove HTTP::Throwable::Role::TextBody
'StackTrace::Auto'
);
}
sub throw_bad_request {
my ($class, $status, %opts) = @_;
cluc
$json_body = JSON->new->ascii->pretty->encode($data);
# [ 'Content-Type' => 'application/hal+json' ],
$class->throw( BadRequest => {
status_code => $status,
message => $json_
le::JsonParams;
$WebAPI::DBIC::Role::JsonParams::VERSION = '0.004002';
use Moo::Role;
use Carp qw(croak);
use Hash::MultiValue;
use JSON::MaybeXS qw(JSON);
requires 'request';
my $json = JSON->n
# Note that this is transparent to duplicate query parameter names
# i.e., foo=7&foo=8&foo~json=9 will result in the same set of duplicate
# parameters as if the parameters were foo=7&foo=8
# parameter names with a ~json suffix have JSON encoded values
my $is_json;
(my $key_base = $key_raw) =~ s/~json$//
and $is_json = 1;
for my $v ($raw_para
confess);
use Devel::Dwarn;
use Moo::Role;
requires 'render_item_into_body';
requires 'decode_json';
requires 'item';
requires 'param';
requires 'prefetch';
requires 'request';
requires 'response'
epted {
return [ {'application/vnd.wapid+json' => 'from_plain_json'} ]
}
sub from_plain_json {
my $self = shift;
my $data = $self->decode_json( $self->request->content );
$self->upda
WebAPI::DBIC (or "WAPID" for short) provides the parts you need to build a
feature-rich RESTful JSON web service API backed by DBIx::Class schemas.
WebAPI::DBIC features include:
* Built as fine-g
ding ActiveModel / Ember-Data
(C<application/json>), JSON API (C<application/vnd.api+json>)
and HAL (C<application/hal+json>).
The Collection+JSON and JSON-LD hypermedia types could be added in future
dia type' of a request, and the desired response. In the case of JSON
types, the media type defines not only that the content is a JSON data structure,
but the semantics (meaning) of the the scructure
# Enable JSON API support:
'WebAPI::DBIC::Resource::JSONAPI::Role::DBIC', # XXX move out?
'WebAPI::DBIC::Resource::JSONAPI::Role::Set',
'WebAPI::DBIC::Resource::JSONAPI::Role:
type (or HAL for short)
is a simple JSON format that gives a consistent and easy way to hyperlink
between resources in your API. It uses the C<application/hal+json> media type.
Adopting HAL makes th
gramming languages. It's also simple
enough that you can just deal with it as you would any other JSON.
See L<http://stateless.co/hal_specification.html>
for more details of the specification.
=head
kage WebAPI::DBIC::Resource::JSONAPI;
$WebAPI::DBIC::Resource::JSONAPI::VERSION = '0.004002';
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
WebAPI::DBIC::Resource::JSONAPI
=head1 VERSION
version
bAPI::DBIC::Resource::JSONAPI - JSON API support for WebAPI::DBIC
=head2 Media Type
These roles respond to the C<application/vnd.api+json> media type.
=head2 JSONAPI
The JSON API media type is des
compromising readability, flexibility, and discoverability.
See L<http://jsonapi.org/> for more details.
Development of JSON API support for WebAPI::DBIC has stalled due to instability
of the specif
'WebAPI::DBIC::Role::JsonEncoder',
'WebAPI::DBIC::Resource::Role::Router',
'WebAPI::DBIC::Resource::Role::DBICException',
# for application/hal+json
'WebAPI::DBIC::
ActiveModel support for WebAPI::DBIC
=head2 Media Type
These roles respond to the C<application/json> media type.
(This is a very common 'default' media type for web data services.)
=head2 ActiveMo
# Enable JSON API support:
'WebAPI::DBIC::Resource::JSONAPI::Role::DBIC',
'WebAPI::DBIC::Resource::JSONAPI::Role::Item',
'WebAPI::DBIC::Resource::JSONAPI::Role::ItemWr
RSION = '0.004002';
use Scalar::Util qw(blessed);
use Moo::Role;
requires 'decode_json';
requires 'encode_json';
requires 'render_item_as_plain_hash';
requires 'throwable';
requires 'set';
has me
uest content-type not application/json")
unless $self->request->header('Content-Type') =~ 'application/.*?json';
my $invoke_body_data = $self->decode_json($self->request->content);
$se
lf->throwable->throw_bad_request(400, errors => "Request content not a JSON hash")
unless ref $invoke_body_data eq 'HASH';
my @method_args;
if (my $args = delete $invoke_body_data->{a