Birthday Week: Looking to the future

Benjie Gillam
Graphile
Published in
7 min readFeb 1, 2019

This week we’re celebrating the 1 year anniversary of our incorporation; each day we’re celebrating something, culminating with having a PostGraphile stall at FOSDEM in Brussels on Saturday and Sunday — do swing by if you’re in the area!

PostGraphile is now in production use by many companies, with applications in industries ranging from farming to aerospace. We’ve always had a strong focus on stability, and we do our utmost to ensure you don’t have to rewrite your stack as we introduce new features (assuming you stick to the official releases!)

One of the biggest aims for the release of version 4 was to maintain as much compatibility with version 3 as we possibly could whilst completely re-writing the core engine, and we were very successful at this. Another big aim was to stop trying to be a “one size fits all” GraphQL solution and instead focus on handling the repetitive tasks and allowing users to customise and extend the resulting schema as they saw fit. Our plugin system has been very successful at this and is proving very powerful, with community members making available a number of plugins that enhance PostGraphile, and businesses writing their own private plugins to handle their own specific needs.

With all these people relying on us, it’s critical that we balance the needs to improve PostGraphile with the needs to remain stable for our users, and I think we’ve done a great job of this since the release of v4.0.0. However, many of the great improvements we’ve made since the launch of v4 are not available to users by default — they have to “opt in” via flags or plugins — and many don’t get that far in our documentation.

With that in mind, the next major version of PostGraphile, v5, will aim to improve the out-of-the-box experience, whilst making the upgrade from v4 as painless as possible for existing users via the addition of a v4 compatibility plugin.

Below, you’ll find in detail a list of most of the planned breaking changes, but in summary:

Changes which (probably) won’t have backwards compatible solutions include:-

  • Overhauling the introspection system (only affects plugin authors)
  • Introducing plugin priorities (only affects plugin authors)
  • Type generation during `build` will be banned (only affects a small number of plugin authors)
  • Postgraphilerc will be changed to use library options (affects people using a postgraphilerc file)

The other planned changes will probably be solvable by using a — v4 flag or similar to revert to the previous behaviour. These changes include:

  • Simpler generated names
  • Will mount to the root path (“/”) by default in CLI
  • GraphQL schema will be responsible for managing PostgreSQL connections/transactions
  • NodeIDs will use GraphQL type names rather than database table names
  • `pgSettings` will be upgraded to deal with JWTs
  • `postgraphile` CLI will use first available port if port 5000 is busy

More detail on these changes can be read in detail below at your leisure, and they’re still in the planning stages so do come chat with us on Discord if you have any thoughts!

And so we come to the end of our Birthday Week celebrations. We have released a Medium article every day this week to celebrate, with a different focus each day. You can see them all in our new Graphile Medium Publication. We’ve had a fantastic time this past year, growing both PostGraphile the project and PostGraphile the community. I’m now pressing publish just as I am waiting for my plane to depart to Brussels for FOSDEM (so excuse typos!) and, as always, want to take this opportunity to send a HUGE THANK YOU to all our sponsors, contributors, evangelists and other supporters — this would not be possible without you!

Remember, if you don’t already, you can sponsor PostGraphile on Patreon, and join our community on Discord.

Backwards Incompatible Breaking Changes

Introspection

We’ll be changing the introspection system to be extensible via plugins; we’ll also probably switch to getter methods for retrieving things rather than (or in addition to) object traversal. A hook will probably be added to enable you to augment introspection results before they are “baked” (interlinked/cached/etc).

Hook priorities

Hooks will define priorities (or provides/depends — it’s not been decided yet) that allow you to control the order in which they are applied without the user having to reference plugins in a particular order.

Type generation during `build` will be banned

And type generation during `init` will be dissuaded. Sadly, I learned that building types during `build` was not optimal only after the release of 4.0.0. The issue is that it makes it a lot harder for other plugins to hook these objects since the build object may not be finalised (so not all the helpers are present yet). It can also result in building “orphaned” objects that are never used, wasting processing time and memory. In v5 we’ll probably switch to registering type generator functions that are executed “Just In Time” rather than generating types up front (we already do this with table, view and compound types and it works brilliantly).

Postgraphilerc will be changed to use library options

Currently postgraphilerc uses the options that come out of the CLI library that we use, which do not always use the names documented in the CLI or Library pages. We’ll change it so that it uses the library option names instead. This should also mean that a postgraphilerc could be shared between library and CLI usage which would be awesome!

Enhanced GraphiQL will be the only GraphiQL

GraphiQL, the GraphQL IDE, is an excellent tool for exploring your GraphQL API, and with recent enhancements such as GraphQL Explorer from OneGraph it’s better than ever. Since it’s easy to add your own bespoke GraphiQL route should you so desire, we’re going to focus on PostGraphiQL (our flavour) as a development tool, and as such we’ll be changing it and enhancing it over time. You can still use it in production if you want, but it will be PostGraphile branded 😉

Backwards Compatible Breaking Changes

Isn’t that an oxymoron? Well, thanks to our powerful plugin system: no. We’re able to make changes to defaults and the schema in v5 whilst offering a flag/plugin that restore the behaviours of v4 that your application uses.

Simpler names by default

Anyone who has been following along with @graphile-contrib/pg-simplify-inflector will know that one of my obsessions is simplifying our generated GraphQL schemas down from having fields like `personByAuthorId` to simply `author`. It’s a challenge to do this in an auto-generated schema without causing field name conflicts, but pg-simplify-inflector has done a great job and I believe we can do even better… If we can, without causing a significant drop in compatibility with existing databases, then I definitely plan to bake this in as default behaviour in v5 (but it will be made backwards compatible via a plugin). For now, you can use @graphile-contrib/pg-simplify-inflector to get a feel for this, just beware of semver-major updates changing names of things.

Will mount to the root path (/) by default in CLI

We currently mount to /graphql and /graphiql for legacy reasons, this sometimes causes user confusion. We will change this to `/` by default for the CLI (and maybe also the library) but you can still use the relevant GraphQL route options to configure this back to its old behaviour.

PostgreSQL connections baked into the schema

In all previous versions of PostGraphile, when you run a query you first get a PG client from the pool, start a transaction, configure the transaction for the user, and then you pass that client to the GraphQL schema (via the `context` argument) for use during resolution. Once the GraphQL request has resolved you then commit the transaction and release the client back to the pool. This has worked really well for PostGraphile’s own server/middleware, but unfortunately it works less well with various other software in the GraphQL ecosystem that do not have support for guaranteed (and asynchronous) active releasing of the GraphQL context. This means that when you combine PostGraphile with other GraphQL tools you sometimes have to use it as a remote schema.

In version 5 we’re going to change how this behaves a little: if you pass a pgClient on `context` then all will work as before, but if you do not (which will be the default for the PostGraphile server) then the schema will manage allocating and configuring PG clients and transactions. This should greatly increase our compatibility with other GraphQL tooling such as Apollo Server and GraphQL Weaver.

Node IDs

Graphile Engine uses the GraphQL type name in the generated NodeIDs, but as part of maintaining compatibility with version 3, we had to add a plugin (PgNodeAliasPostGraphile) that overrode these NodeIDs to instead use the actual table names. This means if you base64 decode a NodeID in PostGraphile currently you can see the underlying table name (even if you’ve renamed the resource using smart comments or an inflector plugin).

Version 5 will using the Graphile Engine native NodeIDs by default, but you will be able to add a small plugin to restore the v3-flavoured NodeIDs.

pgSettings will be enhanced or replaced

We’re going to change how pgSettings interacts with JWTs slightly, and try and make it work better with other transports such as websockets. If necessary we’ll introduce a new interface, but we’re hoping to avoid this.

The CLI `postgraphile` will find first available port

If port 5000 is in use and you don’t specify a port number, we’ll find an available port. To stop this being a breaking change, ensure you explicitly set the port number on the command line: `-p 5000`

Wow, thanks for reading this far! If you have any feedback, come chat to me on Discord (but don’t expect fast responses this weekend as we’re at FOSDEM!)

--

--

Benjie Gillam
Graphile

Maintainer of PostGraphile: instant, secure and super-fast GraphQL API for your PostgreSQL database.