Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/graphql-perl/mojolicious-plugin-graphql
Mojolicious plugin to make GraphQL endpoints
https://github.com/graphql-perl/mojolicious-plugin-graphql
Last synced: 6 days ago
JSON representation
Mojolicious plugin to make GraphQL endpoints
- Host: GitHub
- URL: https://github.com/graphql-perl/mojolicious-plugin-graphql
- Owner: graphql-perl
- Created: 2017-10-15T04:07:10.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2021-02-10T19:41:26.000Z (almost 4 years ago)
- Last Synced: 2024-06-18T21:41:57.987Z (5 months ago)
- Language: Perl
- Homepage: https://metacpan.org/release/Mojolicious-Plugin-GraphQL
- Size: 78.1 KB
- Stars: 4
- Watchers: 3
- Forks: 5
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: Changes
Awesome Lists containing this project
README
# NAME
Mojolicious::Plugin::GraphQL - a plugin for adding GraphQL route handlers
# SYNOPSIS
my $schema = GraphQL::Schema->from_doc(<<'EOF');
schema {
query: QueryRoot
}
type QueryRoot {
helloWorld: String
}
EOF# for Mojolicious substitute "plugin" with $app->plugin(...
# Mojolicious::Lite (with endpoint under "/graphql")
plugin GraphQL => {
schema => $schema, root_value => { helloWorld => 'Hello, world!' }
};# OR, equivalently:
plugin GraphQL => {schema => $schema, handler => sub {
my ($c, $body, $execute, $subscribe_fn) = @_;
# returns JSON-able Perl data
$execute->(
$schema,
$body->{query},
{ helloWorld => 'Hello, world!' }, # $root_value
$c->req->headers,
$body->{variables},
$body->{operationName},
undef, # $field_resolver
$subscribe_fn ? (undef, $subscribe_fn) : (), # only passed for subs
);
}};# OR, with bespoke user-lookup and caching:
plugin GraphQL => {schema => $schema, handler => sub {
my ($c, $body, $execute, $subscribe_fn) = @_;
my $user = MyStuff::User->lookup($app->request->headers->header('X-Token'));
die "Invalid user\n" if !$user; # turned into GraphQL { errors => [ ... ] }
my $cached_result = MyStuff::RequestCache->lookup($user, $body->{query});
return $cached_result if $cached_result;
MyStuff::RequestCache->cache_and_return($execute->(
$schema,
$body->{query},
undef, # $root_value
$user, # per-request info
$body->{variables},
$body->{operationName},
undef, # $field_resolver
$subscribe_fn ? (undef, $subscribe_fn) : (), # only passed for subs
));
};# With GraphiQL, on /graphql
plugin GraphQL => {schema => $schema, graphiql => 1};# DESCRIPTION
This plugin allows you to easily define a route handler implementing a
GraphQL endpoint, including a websocket for subscriptions following
Apollo's `subscriptions-transport-ws` protocol.As of version 0.09, it will supply the necessary `promise_code`
parameter to ["execute" in GraphQL::Execution](https://metacpan.org/pod/GraphQL::Execution#execute). This means your resolvers
can (and indeed should) return Promise objects to function
asynchronously. As of 0.15 these must be "Promises/A+" as subscriptions
require `resolve` and `reject` methods.The route handler code will be compiled to behave like the following:
- Passes to the [GraphQL](https://metacpan.org/pod/GraphQL) execute, possibly via your supplied handler,
the given schema, `$root_value` and `$field_resolver`. Note as above
that the wrapper used in this plugin will supply the hash-ref matching
["PromiseCode" in GraphQL::Type::Library](https://metacpan.org/pod/GraphQL::Type::Library#PromiseCode).
- The action built matches POST / GET requests.
- Returns GraphQL results in JSON form.# OPTIONS
[Mojolicious::Plugin::GraphQL](https://metacpan.org/pod/Mojolicious::Plugin::GraphQL) supports the following options.
## convert
Array-ref. First element is a classname-part, which will be prepended with
"[GraphQL::Plugin::Convert](https://metacpan.org/pod/GraphQL::Plugin::Convert)::". The other values will be passed
to that class's ["to\_graphql" in GraphQL::Plugin::Convert](https://metacpan.org/pod/GraphQL::Plugin::Convert#to_graphql) method. The
returned hash-ref will be used to set options, particularly `schema`,
and probably at least one of `resolver` and `root_value`.## endpoint
String. Defaults to `/graphql`.
## schema
A [GraphQL::Schema](https://metacpan.org/pod/GraphQL::Schema) object. As of 0.15, must be supplied.
## root\_value
An optional root value, passed to top-level resolvers.
## resolver
An optional field resolver, replacing the GraphQL default.
## handler
An optional route-handler, replacing the plugin's default - see example
above for possibilities.It must return JSON-able Perl data in the GraphQL format, which is a hash
with at least one of a `data` key and/or an `errors` key.If it throws an exception, that will be turned into a GraphQL-formatted
error.If being used for a subscription, it will be called with a fourth
parameter as shown above. It is safe to not handle this if you are
content with GraphQL's defaults.## graphiql
Boolean controlling whether requesting the endpoint with `Accept:
text/html` will return the GraphiQL user interface. Defaults to false.# Mojolicious::Lite
plugin GraphQL => {schema => $schema, graphiql => 1};## keepalive
Defaults to 0, which means do not send. Otherwise will send a keep-alive
packet over websocket every specified number of seconds.# METHODS
[Mojolicious::Plugin::GraphQL](https://metacpan.org/pod/Mojolicious::Plugin::GraphQL) inherits all methods from
[Mojolicious::Plugin](https://metacpan.org/pod/Mojolicious::Plugin) and implements the following new ones.## register
my $route = $plugin->register(Mojolicious->new, {schema => $schema});
Register renderer in [Mojolicious](https://metacpan.org/pod/Mojolicious) application.
# EXPORTS
Exportable is the function `promise_code`, which returns a hash-ref
suitable for passing as the 8th argument to ["execute" in GraphQL::Execution](https://metacpan.org/pod/GraphQL::Execution#execute).# SUBSCRIPTIONS
To use subscriptions within your web app, just insert this JavaScript:
# ...
const subscriptionsClient = new window.SubscriptionsTransportWs.SubscriptionClient(websocket_uri, {
reconnect: true
});
subscriptionsClient.request({
query: "subscription s($c: [String!]) {subscribe(channels: $c) {channel username dateTime message}}",
variables: { c: channel },
}).subscribe({
next(payload) {
var msg = payload.data.subscribe;
console.log(msg.username + ' said', msg.message);
},
error: console.error,
});Note the use of parameterised queries, where you only need to change
the `variables` parameter. The above is adapted from the sample app,
[https://github.com/graphql-perl/sample-mojolicious](https://github.com/graphql-perl/sample-mojolicious).# SEE ALSO
[GraphQL](https://metacpan.org/pod/GraphQL)
[GraphQL::Plugin::Convert](https://metacpan.org/pod/GraphQL::Plugin::Convert)
[https://github.com/apollographql/subscriptions-transport-ws#client-browser](https://github.com/apollographql/subscriptions-transport-ws#client-browser)
\- Apollo documentation# AUTHOR
Ed J
Based heavily on [Mojolicious::Plugin::PODRenderer](https://metacpan.org/pod/Mojolicious::Plugin::PODRenderer).
# COPYRIGHT AND LICENSE
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.