Releases: graphile/crystal
4.4.4 - maintenance release
General maintenance release.
Features:
- Add experimental plugin generators for adding conditions, orders (graphile/graphile-engine#517)
readCachecan now pass an object to be used as the cache (@garcianavalon, graphile/graphile-engine#479)
Fixes:
- Fixed a 3 year old bug in the introspection query (means correct CRUD mutations are generated for views with triggers) (@rudism, graphile/graphile-engine#508)
- Improved the error message when orderBy is not unique and before/after are attempted (@soutot, graphile/graphile-engine#515)
- Improved error messages for smart comments (graphile/graphile-engine#525)
- Remove sortable/filterable from functions that require args (@mattbretl, graphile/graphile-engine#519)
- Ensure X-GraphQL-Event-Stream is domain relative (@mathroc, #1148)
- Recommend using
--initwith Docker; turn off progress bars
Chores:
- Updated to latest GraphQL, so @types/graphql is no longer required (@none23, graphile/graphile-engine#511)
- Updated to latest Flow (@none23, graphile/graphile-engine#514)
- Standardise database setup instructions (@ab-pm, graphile/graphile-engine#512, #1145)
- Move from TSLint to ESLint (graphile/graphile-engine#526)
4.4.3 - directives hotfix
makeExtendSchemaPlugin in the last release disabled the built-in directives @include and @skip; this hotfix restores them.
v4.4.2 - various fixes
Benjie has been approved for GitHub Sponsors and for a limited time GitHub are match-funding, so there has never been a better time to support development of this software!
Talking of sponsorship, please check out our new featured sponsor, Timescale!
This is mostly a maintenance release, no major new features.
Features:
- updated to the latest version of GraphiQL explorer (see their release post)
- you can now pass
jwtSignOptionsto PostGraphile, thanks to @speller makeExtendSchemaPluginnow supports defining unions, directives and scalars (required to support Apollo Federation, which you can try out with @graphile/federation); unions only work in certain places and are currently undocumented (and thus unsupported)- new
hideIndexWarningsoption for when you haveignoreIndexes: falsethanks to @tinymarsracing - various code has been tidied/fixed/modernised thanks to @singingwolfboy
- auto-coerce numeric field names to begin with an underscore (shouldn't affect existing users)
Fixes:
- node identifiers have been made safer:
- If you have identically named tables in different schemas and you use relay global object identifiers (on by default) you'll be warned, and encouraged to disable the
PgNodeAliasPostGraphileplugin to solve it - If you use
bigintorbigserialin your primary key, values greater than 9 quadrillion (technically> 9,007,199,254,740,991) are now treated as strings in the node identifier, sonodeIdis now valid for these - 🚨 BREAKING: if you use
money, ordecimal/numericor some other weird numeric type in your primary keys these will now also be represented as a string within the base64-encoded node IDs, so your node IDs will change. If this affects you (unlikely?) please get in touch with Benjie (to be clear: int, int2, int4, float, float4 and float8 are unaffected; and int8/bigint only changes node IDs for values over 9 quadrillion)
- If you have identically named tables in different schemas and you use relay global object identifiers (on by default) you'll be warned, and encouraged to disable the
- fix issue with default values for orderBy argument on edge fields on mutation payloads when printing the schema
- mark fake constraints (e.g.
@foreignKeysmart comment) as indexed so it works nicer withignoreIndexes: false - @graphile/pg-pubsub now uses exponential back-off when server shuts down, rather than giving up after 9 attempts
- more validation is applied to cursors in connections
- fix misleading description of queryCacheMaxSize
- fix docs for
jwtRole, thanks to @bidoubiwa
v4.4.1 - Performance improvements, versioned docker tags
The main feature of this release is significant performance improvements — enjoy!
We also overhauled how Docker builds work, so they're now tagged in a more sensible manner. Almost all previous tags have been deleted. From now onwards we have versioned Docker images:
graphile/postgraphile:4will give you the latest stable in the "v4.x.x" line (no alphas, betas, rcs); this is the recommended version to use- Every new
vX.Y.Zgit tag (i.e. no alpha/beta/rc) will automatically releasegraphile/postgraphile:X-Yandgraphile/postgraphile:X-Y-Z graphile/postgraphile:latestwill give you the latest stable (but beware of major version bumps!)graphile/postgraphile:nextwill give you the equivalent of what's onmasterright now (i.e. pre-release/bleeding edge/nightly)
We're currently in a teething period for this, so there may be some bumpiness - if you face any issues, please let me know via GitHub issues or discord.
NOTE: this only applies to future releases; we are not back-filling previous releases, so there's not many tags to choose from right now.
Other changes:
- update various dependencies
- significant performance improvements
- fix a bug with standalone LDS server announcements for insert/update (thanks @pepijnverburg)
- export more TypeScript interfaces from
graphile-utils - add missing dependencies (thanks @michaelbeaumont)
- respect
externalUrlBasefor websockets (thanks @DvdGiessen) - typo fixes (thanks @angelosarto, @ludwigbacklund)
- add support for
PGHOSTADDRenvvar ifPGHOSTis not present (thanks @encima) - 🚨 Remove invalid fields from payloads for
SETOFfunction mutations (these fields were never valid, so any client using them would already be broken, thus I am not classing this as a breaking change).
v4.4.0 - Subscriptions and Live Queries now OSS 🎉
Please sponsor development (anything from $1/mo) or take out a support contract to help fund ongoing development on the project. PostGraphile is liberally licensed and relies on crowd-funding to advance.
Thanks to the continuing sponsorship from PostGraphile's community, we've added to PostGraphile core what you've all been waiting for - GraphQL Subscriptions, and Live Queries!
GraphQL Subscriptions
We've enhanced PostGraphile with subscriptions / websockets functionality, including adding subscriptions support to our built in GraphiQL IDE (no more need to test with external GraphQL clients!). To get this you have to opt-in via the --subscriptions flag (library: subscriptions: true).
You can use our simple subscriptions listen endpoint, or easily write your own subscription endpoints using makeExtendSchemaPlugin - it's all documented on our website. PostGraphile subscriptions can use Postgres' LISTEN/NOTIFY, or any other source of realtime data — you decide what makes sense for your application.
Subscriptions are the recommended way for adding realtime features to PostGraphile.
PostGraphile Live Queries
More experimental and much heavier on the database is our live queries support — suitable for use in internal tooling within your company, but perhaps not for the internet at large. You can opt-in via the --live flag.
We've built into the core of PostGraphile the ability to track when collections/records are referenced (and the filters that apply to them, such as foreign key constraints and conditions); you can then combine this with one or more realtime provider plugins which inform PostGraphile when these tracked resources change, triggering the query to be re-executed and the result sent to the user.
This feature is exposed over standard GraphQL subscription operations so you should be able to just switch out query with subscription at the beginning of your GraphQL document to make it live. No need for specific client support — it supports all clients that support subscriptions. (We plan to support the @live directive optimisation available in Apollo Client in a future release, should demand be sufficient.)
We recommend using simple request documents with live queries because each time a relevant row is changed the entire document is recalculated and sent to the user: more complex queries will consume more resources when recalculated and will likely be triggered more frequently, leading to non-linear performance costs. (Note: we throttle updates to prevent overwhelming the client or the server, and this throttle period is configurable.)
Our first live queries provider plugin, @graphile/subscriptions-lds uses PostgreSQL's extremely efficient logical decoding functionality to stream changes out of the database using the replication interface. It requires you to tweak a couple of settings in postgresql.conf but is otherwise simple to set up - see the documentation on the website which also includes instructions for Amazon RDS.
Note that live queries are still experimental, and have not been performance optimised yet - please let us know of any issues you face!
Other features
Docker compose/kubernetes users may appreciate the new --retry-on-init-fail flag that means PostGraphile will keep trying to rebuild the initial schema, so with this flag it can be started before the database is ready. (Uses exponential backoff with a 30s cap.)
We've increased performance for queries that use large offset values (so long as the relevant table is not using column-level select grants, which are not recommended with PostGraphile).
makeExtendSchemaPlugin now has support for re-using existing Relay Connections; it can also be used with the @pgQuery directive to add connections deeper into the schema. The documentation has been updated with more details.
You can now add your own aggregates to connections using our new aggregates infrastructure. totalCount on connections has been re-written to use this, and there are more examples (e.g. exposing SUM(...)) in the PR description: graphile/graphile-engine#415; if you require certain aggregates please get in touch.
Thanks to @dijam we now accept Buffer objects as jwtSecret in addition to strings.
build.scopeByType was added to enable plugin authors to get from a GraphQL type the scope it was created with - useful for finding the PostgreSQL table associated with a GraphQL object type, for example.
Plugins now have a dependency ordering system, so we can move to using --append-plugins for everything and have hooks register their own positions. This system is not yet documented (or final) so is not officially supported yet, but it's a good way to easily enable features that previously involved a complex setup.
Many more tests were added.
--owner-connection / ownerConnectionString setting added, to give PostGraphile access to a privileged Postgres account. It is needed for logical decoding, but it's now also used (if present) to install watch fixtures and avoid the "Failed to setup watch fixtures in Postgres database" error. It is recommended in development for the watch schema, but only recommended in production if you are using live queries.
Newly introduced @simpleCollections smart comment enables you to override the simpleCollections setting on a per-table, per-relation and per-function basis. I.e. you can now opt-in to using the list interface (rather than Relay connection interface) in certain places without affecting the rest of your schema.
Filterable, filter-by-able, sortable and sort-by-able functions support was introduced in 4.3.1.
GraphiQL Explorer support added in 4.3.2;
🚨 Breaking fixes
These are fixes that might break you schema if you were relying on the broken behaviour (please don't do that!). We've added flags to some of them so you can maintain the old (broken) behaviour should you need to.
- Fixed issues with arrays of certain types (
interval, etc) incorrectly having aStringinput type (opt out withdisableIssue390Fix- ref graphile/graphile-engine#405) - If you're using
--simple-collections onlywe still used to add Relay edges to mutation payloads (these edges are pointless without the connections they applied to). We've corrected this oversight by removing them, but you can add them back with thedisableIssue397Fixflag - ref graphile/graphile-engine#408) graphile-utils: if you were usingmakeExtendSchemaPluginto add a field returning aConnectiontype, this will not have been working correctly. Instead of returningreturn {data: await selectGraphQLResultFromTable(...)}from your custom resolver you should now just return the result of selectGraphQLResultFromTable directly:return await selectGraphQLResultFromTable(...), and thenpageInfoand the rest will work correctly. The makeExtendSchemaPlugin docs have been updated, worth a re-read. If you're affected by this and don't make this change, you'll see errors likeTypeError: data.data.map is not a function.
Fixes
- PostGraphile handles PostgreSQL server restart much more gracefully
- Improved error messages when no values were deleted/updated because of RLS
- Fully qualify reference to
hstoreto handle issues insearch_path - Lots of improvements to TypeScript typings
- Domains with defaults now exposed as nullable (thanks @mattbretl)
- Fixed an issue with relations on custom mutation payloads when the custom mutation returned null without an error
- Fixed an issue with an entire record being returned as null when you only request nullable columns. The fix requires you to provide
--subscriptionsor--liveflags as it requires you to have granted select to at least the primary keys of the tables you expose makeWrapResolversPlugincan now replace the arguments that are pass to PostgreSQL function calls for root-level custom queries and mutations.totalCountis now non-nullable because I couldn't find any justification for it being nullable and no issues came up during the beta and RC phase- Fixed a bug in the times generated by the PostGraphile logs
- Exposed the
X-GraphQL-Event-Streamheader (thanks @imolorhe) - Stricter pool validation
- Fixed an issue with HTTP2 support in Fastify
- Fixed
hasVersionto allow pre-releases - Include
namespaceNamein introspection for extensions
v4.3.3: patch issue with DEBUG + pgPool.query
Fixes an issue one of the PostGraphile sponsors had where sharing the PgPool between their own code and PostGraphile, using pgPool.query, and setting DEBUG with the SQL-outputting debug variables caused an error to be produced. #987
v4.3.2 - GraphiQL Explorer
The lovely folks over at OneGraph sent a PR to integrate their GraphiQL Explorer into PostGraphile — this awesome feature really helps users get started with GraphQL. Make sure you're using --enhance-graphiql to use it! #981
Additionally @mlipscombe discovered an issue where your PgPool could become exhausted if an enough errors were thrown on COMMIT, and sent over a PR to fix: #978
v4.3.1 - filterable and sortable functions, fixed complex ranges
Important note: pgInflection should not appear anywhere in your code or that of your plugins; see below. (If it does, you'll get some warning messages, but things should continue to work for the time being.)
The main feature in this release is you can now opt-in to filtering and sorting function results (so long as they return setof table type), and enabling you to filter-by and sort-by scalar computed columns. This is opt-in behaviour on a per-function basis using smart comments because if used incautiously it could result in significant performance woes (basically: in many cases database functions are black boxes to PostgreSQL, so the full function result may have to be calculated before it can then be sorted, and if it returns millions of rows that might take a moment).
Also in this release are a number of small fixes and enhancements detailed below. See the 🚨 for a fix that may impact your schema if you were relying on broken behaviour.
PostGraphile is crowd-funded, we ask the individuals and businesses that use PostGraphile to please sponsor ongoing maintenance and development.
- functions can now be opted into filtering and sorting via
@filterableand@sortablesmart comments; you can also mark the result as non-nullable via@notNullsmart comment (graphile/graphile-engine#378) makeWrapResolversPluginhas been enhanced to allow wrapping all resolvers that match a filter functionmakeAddInflectorsPluginhas been enhanced to allow you to access previous inflectors (e.g. if you only want to override them in certain circumstances)- yet more things are named via the inflector (and thus can have their names customised) including
Query,MutationandSubscription- just override theinflection.builtin(name)inflector - more server plugin hooks added, enabling custom logging and tweaking GraphiQL's HTML (e.g. to add dark mode)
- accidentally passing
undefinedas any of PostGraphile's options now throws an error to help you more rapidly spot issues in your code (thanks @marshall007); the PostGraphile call signature has not changed - adds compatibility with
intarrayPostgreSQL extension - fixes formatting of PostgreSQL ranges, ranges that require extra processing (arbitrary precision numeric, bigint, timestamps) are now processed correctly (thanks @mathroc); 🚨 if you were using the broken ranges, please test related code
- fixed typo where the CRUD plugins used
pgInflectionwhere they meantpgIntrospection; have kept the old name too to prevent this being a breaking change, but please update your plugins to use the correct name - the ancient
inflectionoption to PostGraphile (which becamepgInflectioninternally) that was deprecated in 4.0.0-beta.6 now generates warning messages if you use it, which you should not. Instead migrate to the plugin-capable inflection system - added additional index information to introspection in case your plugin needs that (@mlipscombe 😉 )
- doc fixes (thanks @petetnt, @SiM07)
- support for Windows CRLF line-breaks in smart comments
v4.3.0 (never @latest)
4.3.0 was never promoted to @latest due to a couple of issues:
- more people (specifically, plugins) were using the long-deprecated
pgInflectorargument than expected; this has been restored in 4.3.1: graphile/graphile-engine#381 - a small issue was introduced when implementing
@sortablethat broke a plugin; this is also resolved in 4.3.1: graphile/graphile-engine#386 - too many new inflectors were introduced (all taking zero arguments); this has been replaced with a single
builtininflector: graphile/graphile-engine#387
We're going to look into extending the release tests to running against some popular community plugins to ensure future releases don't introduce backwards-incompatible changes. If you'd like your plugin to be included in this effort, please get in touch.
v4.2.0 - constraints on views / materialized views
Thanks to sponsorship from ULTA.io, this release introduces support for defining constraints (e.g. foreign keys, primary keys, etc) via "smart comments". This means that VIEWs and MATERIALIZED VIEWs can now act a lot more like regular tables when viewed by PostGraphile - you can define a @primaryKey for your view, or have a @foreignKey that references another table (or another view!). You can also mark fields as @notNull For more information, see the documentation:
The other change in this release is that we now surface a warning message if a foreign key constraint is skipped because it lacks an index and you're using --no-ignore-indexes or ignoreIndexes: false.
