Mojolicious::Plugin::GraphQL - a plugin for adding GraphQL route handlers


  my $schema = GraphQL::Schema->from_doc(<<'EOF');
  schema {
    query: QueryRoot
  type QueryRoot {
    helloWorld: String

  # 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
      { helloWorld => 'Hello, world!' }, # $root_value
      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;
      undef, # $root_value
      $user, # per-request info
      undef, # $field_resolver
      $subscribe_fn ? (undef, $subscribe_fn) : (), # only passed for subs

  # With GraphiQL, on /graphql
  plugin GraphQL => {schema => $schema, graphiql => 1};


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. 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 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.

  • The action built matches POST / GET requests.

  • Returns GraphQL results in JSON form.


Mojolicious::Plugin::GraphQL supports the following options.


Array-ref. First element is a classname-part, which will be prepended with "GraphQL::Plugin::Convert::". The other values will be passed to that class's "to_graphql" in GraphQL::Plugin::Convert method. The returned hash-ref will be used to set options, particularly schema, and probably at least one of resolver and root_value.


String. Defaults to /graphql.


A GraphQL::Schema object. As of 0.15, must be supplied.


An optional root value, passed to top-level resolvers.


An optional field resolver, replacing the GraphQL default.


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.


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};


Defaults to 0, which means do not send. Otherwise will send a keep-alive packet over websocket every specified number of seconds.


Mojolicious::Plugin::GraphQL inherits all methods from Mojolicious::Plugin and implements the following new ones.


  my $route = $plugin->register(Mojolicious->new, {schema => $schema});

Register renderer in Mojolicious application.


Exportable is the function promise_code, which returns a hash-ref suitable for passing as the 8th argument to "execute" in GraphQL::Execution.


To use subscriptions within your web app, just insert this JavaScript:

  <script src="//"></script>
  # ...
  const subscriptionsClient = new window.SubscriptionsTransportWs.SubscriptionClient(websocket_uri, {
    reconnect: true
    query: "subscription s($c: [String!]) {subscribe(channels: $c) {channel username dateTime message}}",
    variables: { c: channel },
    next(payload) {
      var msg =;
      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,



GraphQL::Plugin::Convert - Apollo documentation


Ed J

Based heavily on Mojolicious::Plugin::PODRenderer.


This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.