PostGraphile Server Plugins

Stability: unstable, may change in semver minor versions.

NOTE: This page relates to changing how the PostGraphile HTTP server and CLI work. If you're instead looking to change the generated GraphQL schema (e.g. to add fields or types), see Schema Plugins.

In addition to the Graphile Engine plugin system which builds the GraphQL schema in PostGraphile, PostGraphile also has a plugin system for the CLI and web layer. This plugin system is less mature, help documenting it is welcome!

First-party plugins

There are a couple of first-party plugins that you may want to use that can be purchased on the Graphile Store:

  • @graphile/supporter supporter
    (pay what you want, from $1/mo+)
  • @graphile/pro pro

To use these plugins you will need a GRAPHILE_LICENSE environmental variable to be present, as in these examples:

# GNU/Linux and macOS bash:
export GRAPHILE_LICENSE="license_key_from_graphile_store"
postgraphile -c postgres://...

# Heroku
heroku config:set GRAPHILE_LICENSE="license_key_from_graphile_store" -a my_heroku_app

# Windows Console
set GRAPHILE_LICENSE="license_key_from_graphile_store" & postgraphile -c postgres://...

# Windows PowerShell
$env:GRAPHILE_LICENSE="license_key_from_graphile_store"; postgraphile -c postgres://...

For more information, see the FAQ at the bottom of the Go Pro! page.

Installing

You can install plugins with yarn add or npm install, e.g.

yarn add @graphile/operation-hooks

Enabling via CLI flag

PostGraphile plugins can be specified with the --plugins CLI flag; however this flag must be the first flag passed to PostGraphile as plugins can register additional CLI flags. Multiple plugins can be specified with comma separation:

postgraphile --plugins \
  @graphile/operation-hooks,@graphile/supporter,@graphile/pro \
  -c postgres:///my_db

Enabling via .postgraphilerc.js

If you're using the CLI version, plugins can also be enabled via .postgraphilerc.js file; for example:

module.exports = {
  options: {
    plugins: [
      "@graphile/operation-hooks",
      "@graphile/supporter",
      "@graphile/pro",
    ],
    connection: "postgres:///my_db",
    schema: ["app_public"],
    // ...
  },
};

Enabling via middleware options

This will likely get easier in future, but for now enabling via the middleware is a slightly more involved process:

To include the dependencies using CommonJS (Node 8):

const { postgraphile, makePluginHook } = require("postgraphile");
const { default: OperationHooks } = require("@graphile/operation-hooks");
const { default: GraphileSupporter } = require("@graphile/supporter");
const { default: GraphilePro } = require("@graphile/pro");

If you're using ES2015 Modules (ESM) then this syntax may be more to your taste:

import { postgraphile, makePluginHook } from "postgraphile";
import OperationHooks from "@graphile/operation-hooks";
import GraphileSupporter from "@graphile/supporter";
import GraphilePro from "@graphile/pro";

To enable the plugins, use makePluginHook to create a pluginHook function to pass via the PostGraphile options:

// Only include as many plugins as you need. An empty array is also valid.
const pluginHook = makePluginHook([
  OperationHooks,
  GraphileSupporter,
  PostGraphilePro,
]);

const postGraphileMiddleware = postgraphile(databaseUrl, "app_public", {
  pluginHook,
  // ...
});

app.use(postGraphileMiddleware);

Writing your own plugins

The hook methods available can be viewed in pluginHook.ts. Note that these may change in semver minor releases of PostGraphile as this is not an officially stable API yet.

Each hook method is passed two parameters:

  • subject: the thing being hooked
  • context: an object containing some relevant helpers

The hooks are expected to return either the thing being hooked (subject), or a derivative of it. Multiple plugins may register for the same hooks, in these cases the output of one hook function will be fed as input to the next. Hooks are synchronous.

Your plugin will export a single object which defines the hook methods; e.g.:

const MyPlugin = {
  ["cli:greeting"](messages, { chalk }) {
    return [...messages, `Hello ${chalk.blue("world")}!`];
  },
};

module.exports = MyPlugin;
// or, for ES6 modules:
// export default MyPlugin;

An example of a PostGraphile server plugin is @graphile/operation-hooks:

  • uses cli:flags:add:schema to add --operation-messages and --operation-messages-preflight CLI options
  • uses cli:library:options to convert these CLI options to library options
  • uses postgraphile:options to a) convert the library options into graphileBuildOptions (Graphile Engine plugin options), and b) load the OperationHooksPlugin

If you need help writing your own PostGraphile server plugins, ask in our Discord chat.