Created
April 27, 2018 02:43
-
-
Save taiyoh/c9aa7a6db938d4f0ad9abae4e25836a5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!perl | |
use 5.014; | |
use warnings; | |
use GraphQL::Schema; | |
use GraphQL::Execution qw/execute/; | |
use Data::Dumper; | |
package Person { | |
use Moo; # GraphQLがMoo依存なので使わせてもらう | |
has name => ( | |
is => 'ro', | |
required => 1, | |
); | |
has favorite_fruit_ids => ( | |
is => 'ro', | |
required => 1, | |
); | |
}; | |
package Fruit { | |
use Moo; | |
has id => ( | |
is => 'ro', | |
required => 1, | |
); | |
has name => ( | |
is => 'ro', | |
required => 1, | |
); | |
}; | |
package MyApp::GraphQL::Resolver::Query { | |
sub person { | |
my ($root_value, $args, $context, $info) = @_; | |
my $person = main::get_person(); | |
return { name => $person->name, favorite_fruit_ids => $person->favorite_fruit_ids }; | |
} | |
}; | |
package MyApp::GraphQL::Resolver::Person { | |
sub favoriteFruits { | |
my ($root_value, $args, $context, $info) = @_; | |
my $fruits = main::get_fruits($root_value->{favorite_fruit_ids}); | |
return [ map +{ name => $_->name }, @$fruits ]; | |
} | |
}; | |
my $idx = 1; | |
my @fruits = map { Fruit->new(id => $idx++, name => $_) } qw/apple banana orange grape kiwifruit/; | |
my $person = Person->new(name => 'taiyoh', favorite_fruit_ids => [1, 5]); | |
sub get_person { $person } | |
sub get_fruits { | |
my $ids = shift; | |
my %id_map = map { $_ => 1 } @$ids; | |
return [ grep { $id_map{$_->id} } @fruits ]; | |
} | |
my $schema = GraphQL::Schema->from_doc(<<'EOF'); | |
type Person { | |
name: String! | |
favoriteFruits: [Fruit!]! | |
} | |
type Fruit { | |
name: String! | |
} | |
type Query { | |
person: Person | |
} | |
schema { | |
query: Query | |
} | |
EOF | |
my $query = <<'EOQ'; | |
{ | |
person { | |
name | |
favoriteFruits { | |
name | |
} | |
} | |
} | |
EOQ | |
my $res = execute( | |
$schema, | |
$query, | |
{}, # root_value | |
{}, # context_value | |
{}, # variables | |
undef, # operation_name, | |
sub { # resolver | |
my ($root_value, $args, $context, $info) = @_; | |
my $field_name = $info->{field_name}; | |
my $parent_type = $info->{parent_type}->name; | |
my $pkg = sprintf('MyApp::GraphQL::Resolver::%s', $parent_type); | |
if (my $resolver = $pkg->can($field_name)) { | |
return $resolver->($root_value, $args, $context, $info); | |
} | |
# https://metacpan.org/source/ETJ/GraphQL-0.26/lib/GraphQL/Execution.pm#L668-688 より | |
my $root_ref = ref $root_value; | |
if ($root_ref eq 'CODE') { | |
return $root_value->($args, $context, $info); | |
} elsif ($root_ref ne 'HASH' && $root_value->can($field_name)) { | |
return $root_value->$field_name($args, $context, $info); | |
} | |
return $root_value->{$field_name}; | |
} | |
); | |
local $Data::Dumper::Indent = 1; | |
say Dumper($res); | |
__END__ | |
$VAR1 = { | |
'data' => { | |
'person' => { | |
'favoriteFruits' => [ | |
{ | |
'name' => 'apple' | |
}, | |
{ | |
'name' => 'kiwifruit' | |
} | |
], | |
'name' => 'taiyoh' | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment