The catalyst-action-rest branch from shlevy/hydra was an exploration of using Catalyst::Action::REST to create a JSON API for hydra. This commit merges in the best bits from that experiment, with the goal that further API endpoints can be added incrementally. In addition to migrating more endpoints, there is potential for improvement in what's already been done: * The web interface can be updated to use the same non-GET endpoints as the JSON interface (using x-tunneled-method) instead of having a separate endpoint * The web rendering should use the $c->stash->{resource} data structure where applicable rather than putting the same data in two places in the stash * Which columns to render for each endpoint is a completely debatable question * Hydra::Component::ToJSON should turn has_many relations that have strings as their primary keys into objects instead of arrays Fixes NixOS/hydra#98 Signed-off-by: Shea Levy <shea@shealevy.com>
44 lines
1.4 KiB
Perl
44 lines
1.4 KiB
Perl
use utf8;
|
|
package Hydra::Component::ToJSON;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use base 'DBIx::Class';
|
|
|
|
sub TO_JSON {
|
|
my $self = shift;
|
|
my $json = { $self->get_columns };
|
|
my $rs = $self->result_source;
|
|
my @relnames = $rs->relationships;
|
|
RELLOOP: foreach my $relname (@relnames) {
|
|
my $relinfo = $rs->relationship_info($relname);
|
|
next unless defined $relinfo->{attrs}->{accessor};
|
|
my $accessor = $relinfo->{attrs}->{accessor};
|
|
if ($accessor eq "single" and exists $self->{_relationship_data}{$relname}) {
|
|
$json->{$relname} = $self->$relname->TO_JSON;
|
|
} else {
|
|
unless (defined $self->{related_resultsets}{$relname}) {
|
|
my $cond = $relinfo->{cond};
|
|
if (ref $cond eq 'HASH') {
|
|
foreach my $k (keys %{$cond}) {
|
|
my $v = $cond->{$k};
|
|
$v =~ s/^self\.//;
|
|
next RELLOOP unless $self->has_column_loaded($v);
|
|
}
|
|
} #!!! TODO: Handle ARRAY conditions
|
|
}
|
|
if (defined $self->related_resultset($relname)->get_cache) {
|
|
if ($accessor eq "multi") {
|
|
$json->{$relname} = [ map { $_->TO_JSON } $self->$relname ];
|
|
} else {
|
|
$json->{$relname} = $self->$relname->TO_JSON;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $json;
|
|
}
|
|
|
|
1;
|