Releases: graphile/crystal
New options and critical bugfixes
This release of PostGraphQL provides some new features like configuration options for body-parser
’s limit with bodySizeLimit
, the ability to add custom settings to a PostGraphQL transaction with pgSettings
, and a fresh new version of GraphiQL that comes with some nice enhancements to search and GraphQL field rendering.
This release also fixes a few bugs including a major regression introduced in 3.0.1 which was reported in #409.
For a full list of features and bugfixes along with their associated pull requests, see the list below.
Features
- Add option so that you may inject custom settings into the database. (#399)
- Add option to configure the limit for
body-parser
. (#372) - Update GraphQL and GraphiQL to 0.9.3 and 0.9.1 respectively. (#377 and #410)
Fixes
Schema exports and GraphiQL live schema reloading
This release comes with a few new features that should make the PostGraphQL developer experience much better.
The first feature is support for auto-exporting the PostGraphQL schema by @MaienM. This has been a long-requested feature as GraphQL ecosystem tools like Relay often ask for the user to provide a schema. Now instead of setting up a script to manually pull down the latest PostGraphQL schema into your project with the GraphQL introspection query, you can pass in --export-schema-json [path]
or --export-schema-graphql [path]
arguments to postgraphql
and PostGraphQL will automatically export your schema in a JSON or GraphQL format to the provided path! This feature even works in watch mode, so if you are changing your schema on the fly you will get the latest schema file in your directory.
Another feature that was added in this release to make watch mode even more powerful is live schema reloading in GraphiQL. Before whenever your schema updated you would need to manually reload the GraphiQL browser window you were using to run queries against your database. Well no longer! Now PostGraphQL will let GraphiQL know when there is a new schema, and GraphiQL will live-reload appropriately. Keeping your state in the documentation viewer as well.
Breaking Changes
Unfortunately, this release also contains two breaking changes that were caused by a breaking change in the GraphQL specification.
- When graphql/graphql-spec#244 was merged it meant that PostGraphQL’s usage of the
__id
field name was now not spec-compliant. Therefore, PostGraphQL had to change the name__id
tonodeId
to continue being spec-compliant. If you were not using the--classic-ids
argument, this will be a breaking change for you. Users how have the--classic-ids
argument will not experience a breaking change. We believenodeId
is safe from naming collisions because we already reserve theNode
interface name. For a longer explanation of this change see #327. - Because the range of Postgres big integers is larger than the range of JavaScript numbers and GraphQL
Int
s big integers now have their own custom type calledBigInt
which will return a string in the GraphQL JSON output. We knew this may be a problem for a while, but we did not want to make a breaking change unless we had a very good reason. The__id
change made for a good reason. For more information see #302 and #328.
ES5 and AWS Lambda
With this release PostGraphQL is no longer published as ES6 to the npm registry. Before we were building PostGraphQL to ES6 with TypeScript to take advantage of the latest work in browser engines, so the package published to npm had native classes and object destructuring. Now that people are looking to use PostGraphQL in new environments like AWS Lambda and Meteor which use Node.js v4 we build the project to target ES5. Some standard library features like Map
and Promise
may still need to be polyfilled in ES5 environments, but there will be no syntax errors.
This release also allows you to pass a PgCatalog
object instead of a schema name. This was implemented by @rentrop in #306 and it helps if you want to prebuild your catalog so PostGraphQL doesn’t introspect your schema at startup. This is especially useful for deploying to AWS Lambda. Hopefully we’ll be adding documentation for deploying to PostGraphQL as more community members have positive experiences deploying there.
Disabling Default Mutations
By default PostGraphQL gives you basic create, update, and delete mutations to offer complete CRUD functionality. However, sometimes it may be useful to disable these default mutations and only use custom Postgres procedures to mutate your data.
If you only ever use custom procedures you may not run into as many naming conflicts and you can restrict mutations that can be made by the client.
Of course individual default mutations will still be disabled if no user can use them given the Postgres grant system.
Watching Your Database in Development
This release adds watch functionality to PostGraphQL 🎉
When developing PostGraphQL, it’s nice to have a fast feedback cycle. Being able to open PostGraphQL in one window and a Postgres query input in the other while PostGraphQL automatically updates is a great way to develop rapidly.
To use just pass in --watch
and/or watchPg: true
(depending on if you are using the CLI or the middleware). PostGraphQL will add an event trigger to your database (can only be done if you start PostGraphQL as a superuser), and whenever it gets a notification from that trigger PostGraphQL will automatically rebuild the schema. See a demonstration below:
PostGraphQL 2.0.0
With this release, we are very excited to announce the release of PostGraphQL 2 🎉
Get it now and start playing around by running (make sure you have a database running on postgres://localhost:5432
):
npm install -g postgraphql
postgraphql
PostGraphQL 2 fixes a number of long standing bugs, makes some breaking changes to reflect emerging GraphQL best practices, and sets a foundation which can be used to do truly amazing things in the future (most popularly MySQL support). To understand more of the vision behind PostGraphQL 2, read “#87 My vision for the future of PostGraphQL.”
A number of breaking changes were made in PostGraphQL 2. We hate making breaking changes, especially given that GraphQL itself is designed to be change-tolerant, but we felt these were (in most cases) necessary small fixes that would be best for PostGraphQL’s feature. While this PostGraphQL 2 release does add a lot of things, remember that its real purpose is to create a strong base on which to build a data interfacing platform. Therefore, it felt like breaking changes made sense. If you disagree with any breaking changes, let me know! We would be more than happy to add a flag to provide backwards compatibility where possible. We are hoping most breaking changes are small enough to not be a big deal, and perhaps even be desired changes. Most are inspired by dialog with the community.
New Stuff
- Friendly console UI. Now when you run PostGraphQL it has colors and a much more useful request logger. See a preview image in this tweet.
- Easy to use CLI. PostGraphQL can now be run without a single option! Just run
postgraphql
and we will automatically connect to your local database running atpostgres://localhost:5432
and thepublic
schema. So easy you have to try 😉 - Authentication. For a while PostGraphQL supported authorization so users could only see their data, but not authentication which meant you would need to build a small service to issue JSON Web Tokens. In PostGraphQL 2.0.0, this is no longer required. I’ll be writing up an authentication tutorial before the final release.
- Better Postgres types support, including compound types. PostGraphQL now uses ISO 8601 for dates and times (#107), custom handling of interval types, better support for Postgres ranges (#90), correct handling for all array types, and support for dynamic JSON with the
--dynamic-json
flag (#102). Compound type support means now you can create nested objects in your schemas, input or output. - No
rowId
fields by default. By default, PostGraphQL no longer renamesid
columns torowId
. This was a controversial decision made in PostGraphQL 1 to support Relay 1, as Relay 1 requires theid
field to be a special global id. However, it would appear that the GraphQL team is moving towards a standard global field name in__id
. This new field name makes a lot of sense for PostGraphQL so now all global ids are named__id
by default. However, this does not mean PostGraphQL no longer supports Relay 1! You could use the Relay 1 fork that supports__id
, or you could pass the option--classic-ids
to PostGraphQL which will use the original behavior. If you prefer the classic behavior, all power to you! - Related tables included in mutations. If you are using Relay 1, it may be helpful to have access to related rows from mutations at the payload level (#110, #114, #115). In PostGraphQL 2, such rows are included in the mutation payload for create, update, delete, and procedure mutations.
- Mutations using any unique identifier. With PostGraphQL 2 you can execute update and delete mutations using the global
Node
identifier. The row’s primary key, or a unique constraint (#126). - Cursor pagination by offset. The “correct” way to implement cursor pagination in GraphQL does not involve using SQL limits and offsets. Rather PostGraphQL must control the columns and the ordering. This makes using custom orderings incredibly difficult. Whether you had a view that was already ordered or a connection procedure that defined an order. Now that offset cursor pagination is implemented, we can support natural ordering as well as the “correct” method. Offset ordering has a few gotchas, but they aren’t bad enough to warrant not having this feature.
- Better field names. It has been annoying to many that the top level method of selecting rows has been named
{tableName}Nodes
, as inpersonNodes
orpostNodes
. This was originally because I was against bringing in a pluralization package, mainly because it may have been awkward for non-English speakers. However, as PostGraphQL aims to be more and more extensible, it isn’t hard to change/add pluralization rules. So in PostGraphQL 2, names are not pluralized and read likeallPeople
orallPosts
. This feels like much more natural and may always be configured. - Introspection of multiple schemas. In PostGraphQL 1, you could only introspect a single schema. In 2 you can introspect as many as you would like.
Other Breaking Changes
- No more
--development
flag. Instead all of the features in--development
have been broken out into their own flags. The reason this was done is because sometimes a GraphiQL interface in production makes since. GraphiQL is now also enabled by default, use--disable-graphiql
to disable it. - GraphQL and GraphiQL live on different routes. In PostGraphQL 1 if you went to the
/graphql
route with a browser, you would see GraphiQL. This turns out to not be a best practice as it tightly couples GraphiQL to the GraphQL endpoint. If we wanted to add features to GraphiQL like a headers editor, or a SQL terminal it would be much more difficult if the routes were not separated. Whenever you start PostGraphQL you will be told the exact URL GraphiQL is served on so you won’t be confused. - “Insert” mutations renamed to “Create.” This is to better reflect the industry standard CRUD acronym which stands for: create, read, update delete. “Insert” was initially chosen to feel more like SQL.
- No more “new” prefix in update mutation (#125). The “new” prefix in PostGraphQL 1 has gotten some understandable complaints as it has made updating rows without first renaming the fields impossible. The types for update mutations have been refactored so that now there is one
patch
object whose fields correspond to the object’s fields. - Removed the
descending
argument in connection fields, instead descending information is contained in theorderBy
enum. So instead of configuringorderBy: NAME, descending: true
, you would instead just write:orderBy: NAME_DESC
ororderBy: NAME_ASC
. - The root level
viewer
field has been renamed toquery
in PostGraphQL 2. The root levelviewer
field is a hack for Relay 1 to workaround some of Relay 1’s limitations when it comes to top level fields (such limitations should be gone in Relay 2). However, theviewer
field could also have some semantic meaning such as the literal “viewer,“ or “current user” of the schema. By naming this root fieldviewer
, PostGraphQL 1 disallowed users to add their own implementation forviewer
. In PostGraphQL 2, the field still exists, but it has been renamed toquery
. It can be used in the exact same way, just now with a better name 😉 - Connection conditions moved from top level arguments to a
condition
object. This change declutters your connection argument list, avoids naming collisions with connection arguments, and allows us to make exciting new enhancements to conditions in the future.
What Comes Next?
So what’s the plan after PostGraphQL 2.0.0 is released? We’ll continue with the rough timeline as proposed in #87, but here it is again with a few extra things.
- Documentation/marketing website. We really need this…
- Performance. Experiment with different ways of executing queries to make PostGraphQL as fast as possible.
- Extensibility. This is a big one. Being able to extend PostGraphQL in Node.js is important to the future of the project.
- CMS?
Please try out PostGraphQL 2 and tell us what you think! It’s as easy as:
npm install -g postgraphql
postgraphql
Add Support For Anonymous Roles
When building an authentication system on top of PostGraphQL, you’ll need to add an anonymous role for all requests that don’t assert their own role in a JWT. Before, the anonymous role was the same as the role you would use to authenticate with the database, now that default can be overridden with the --anonymous-role
command line option! Just do the following:
postgraphql postgres://auth_user@localhost:5432/mydb --anonymous-role anonymous_role
For more information about roles in PostgreSQL and their “role” in PostGraphQL read the documentation article titled “The Anonymous Role”.
Bugfixes
PostGraphQL has also had a number of patch releases since the last minor release.
Add CORS Headers
Before PostGraphQL didn’t have appropriate CORS headers making it difficult to use in the browser or without a reverse proxy. With this release CORS headers were added. To see the exact CORS used see the custom middleware here.
Unique column constraint fields and hidden mutations for non-updatable views
This release adds two new helpful features. The first being unique column constraint fields, and the second being the hiding of mutations for non-updatable views.
Unique column constraint fields adds a feature a lot of people have been wanting. Selection by the raw rowId
field. In the forum example, for instance, you can now use this new fields:
{
userByRowId(rowId: 1) {
id
rowId
givenName
familyName
}
}
Instead of needing to use the obfuscated global ID. But this method also extends to tables with a unique compound constraint. So for example if table foo
had columns bar
and buz
which had a unique constraint, you could query a single row of such a table like such:
{
fooByBarAndBuz(bar: 1, buz: 2) {
...
}
}
In addition, this release is able to detect which views are updatable and which are not and exclude/include insert, update, and delete mutations accordingly. This means views which may not be mutated will not be falsely represented in your schema now. This should have been the functionality all along, therefore it is considered a bug fix and not a breaking change.
Commits
Better Relay mutation payloads
This release adds better PostGraphQL support for Relay mutations. In the past, PostGraphQL didn’t always include all of the fields Relay would want in its mutations payloads, this release adds fields to the mutation payload that benefit Relay and non-Relay users alike.
The new payload types from the person table in the forum example look like so:
type InsertPersonPayload {
person: Person
personEdge(orderBy: PersonOrdering): PersonEdge
clientMutationId: String
viewer: Viewer!
}
type UpdatePersonPayload {
person: Person
clientMutationId: String
viewer: Viewer!
}
type DeletePersonPayload {
person: Person
deletedPersonId: ID
clientMutationId: String
viewer: Viewer!
}
express-graphql
Update
Another exciting feature of this release is the upgrade of a bunch of dependencies, most notably express-graphql
! This brings a new version of GraphiQL which fixes a couple of bugs and now also hides GraphiQL from search engines.
With this update you can now also use PostGraphQL as Connect middleware and not just Express middleware.