docs/docs/resources/upgrade-hasura-v2.mdx
import GraphiQLIDE from '@site/src/components/GraphiQLIDE';
This page talks about the conceptual changes introduces in Hasura v2 and things to keep in mind while updating from Hasura v1 to v2.
Do reach out to us if you run into any issues while using Hasura v2 or have any questions regarding any changes introduced.
The following are the most significant conceptual changes introduced in Hasura v2:
:::info Note
A detailed changelog with all the new features introduced in Hasura v2 is available on the releases page.
:::
Semantics of explicit "null" values in "where" filters have changed
According to the discussion in
this GitHub issue, an explicit null
value in a comparison input object will be treated as an error rather than resulting in the expression being evaluated
to True.
For example: The mutation delete_users(where: {id: {_eq: $userId}}) { name } will yield an error if $userId is
null instead of deleting all users.
The older behavior can be preserved by setting the HASURA_GRAPHQL_V1_BOOLEAN_NULL_COLLAPSE env var to true.
Semantics of "null" join values in Remote Schema relationships have changed
In a Remote Schema relationship query, the Remote Schema will be queried when all of the joining arguments are not
null values. When there are null value(s), the Remote Schema won't be queried and the response of the remote
relationship field will be null. Earlier, the Remote Schema was queried with the null value arguments and the
response depended upon how the Remote Schema handled the null arguments but as per user feedback, this behavior was
clearly not expected.
Order of keys in objects passed as "order_by" operator inputs is not preserved
The order_by operator accepts an array of objects as input to allow ordering by multiple fields in a given order,
i.e. [{field1: sortOrder}, {field2: sortOrder}] but it is also accepts a single object with multiple keys as an
input, i.e. {field1: sortOrder, field2: sortOrder}. In earlier versions, Hasura's query parsing logic used to
maintain the order of keys in the input object and hence the appropriate order by clauses with the fields in the
right order were generated.
As the GraphQL spec specifies that input object keys are
unordered, Hasura v2.0's new and stricter query parsing logic doesn't maintain the order of keys in the input object,
removing the previous guarantee that the generated order by clauses specify the fields in the given order.
For example: The query fetch_users(order_by: {age: desc, name: asc}) {id name age} which is intended to fetch users
ordered by their age and then by their name is now not guaranteed to return results first ordered by age and then by
their name as the order_by input is passed as an object. To achieve the expected behavior, the query
fetch_users(order_by: [{age: desc}, {name: asc}]) {id name age} should be used, which uses an array to define the
order of fields to generate the appropriate order by clause.
This has an effect on query operators that depend on order_by, most notably distinct_on. The distinct_on
operator relies on the order of order_by, and therefore is also impacted by this change.
To avoid confusion and potentially-unwanted behavior, you should use an array value for all order_by clauses.
Type name for computed fields' input argument has changed
The name of the computed field input argument has changed from <function_name>_args to
<computed_field_name>_<table_name>_args. This change enables adding a root-level tracked function as a computed
field which previously would have thrown an input type conflict error.
Hasura APIs generated by older Hasura versions cannot be added as Remote Schemas to Hasura v2
With v2.0, some of the auto-generated schema types have been extended. For example, String_comparison_exp has an
additional regex input object field. This means if you have a Hasura API with an older Hasura version added as a
Remote Schema then it will have a type conflict. You should update all Hasura Remote Schemas to avoid such type
conflicts.
CLI Migrations are executed sequentially, instead of one large transaction
While applying multiple Migrations, in earlier Hasura CLI versions all migration files were run under one transaction block. i.e. if any migration threw an error, all the previously successfully executed Migrations would be rolled back. With Hasura CLI v2.0, each migration file is run in its own transaction block but all the Migrations are not executed under one. i.e. if any migration throws an error, applying further Migrations will be stopped but the other successfully executed Migrations up till that point will not be rolled back.
Passing extra GQL params will now throw validation error
According to the discussion in this GitHub issue, passing unused, required GQL params will now throw a validation error.
Per the GraphQL spec, any variable - if defined by an operation as required - should be referenced/used in the operation.
In the example below, the role_type variable is defined but not referenced or used in operation. Thus, executing
this query will result in a validation error.
<GraphiQLIDE
query={query fetch_users($role_type: String!) { users { displayName id role } }}
variables={{ "role_type": "user" }}
response={{ "errors": [ { "extensions": { "code": "validation-failed", "path": "$" }, "message": "unexpected variables in variableValues: role_type" } ] }}
/>
Deprecation of database specific env vars
In v2.0, the values of the following env vars are used to define the connection parameters of the default database
while updating an existing instance or while starting a fresh instance. During Metadata initialization, their values
are moved to the Metadata of the default database as defined here.
HASURA_GRAPHQL_PG_CONNECTIONSHASURA_GRAPHQL_PG_TIMEOUTHASURA_GRAPHQL_NO_OF_RETRIESHASURA_GRAPHQL_PG_POOL_TIMEOUTHASURA_GRAPHQL_USE_PREPARED_STATEMENTSHASURA_GRAPHQL_TX_ISOLATIONHASURA_GRAPHQL_READ_REPLICA_URLSHASURA_GRAPHQL_CONNECTIONS_PER_READ_REPLICAPost the initial setup/update once the Metadata is initialized, these env vars can be considered as Deprecated. i.e. Changing or setting values of these env vars will have no impact as the values in the Hasura Metadata are now used to define the connection parameters.
To accommodate changes for storing information for multiple databases, the Hasura Metadata and the Hasura CLI project
versions have been bumped from v2 to v3. The v2 versions of the Metadata and CLI project can continue to be used
with Hasura v2 instances. Hasura v2 will assume the v2 Metadata and Migrations belong to a database connected with
the name default.
A new mandatory env var HASURA_GRAPHQL_METADATA_DATABASE_URL is now introduced and is mandatory for storing Hasura
Metadata.
Custom env vars can now be used to connect databases dynamically at runtime.
With support for multiple databases, older database specific env vars have been deprecated. See details
:::info Existing Metadata
HASURA_GRAPHQL_METADATA_DATABASE_URL must be the connection string for where your metadata existed previously.
:::
All existing Metadata and Migrations from a Hasura v1 instance are assumed to belong to a database named default in
Hasura v2.
Hence in Hasura v2, a database with name "default" needs to be added to apply Metadata and Migrations from a Hasura v1 instance.
Post adding a database named default, the Hasura v2 instance should behave equivalently to the Hasura v1 instance and
all previous workflows will continue working as they were.
Refer to connecting databases to add a database to Hasura v2.
Hasura v2 is backwards compatible with Hasura v1. Hence simply updating the Hasura docker image version number and restarting your Hasura instance should work seamlessly.
:::info Note
In case you happen to have a large number of past cron and Event Trigger logs in your database, this might slow down the update to v2 and might even cause unexpected errors in certain scenarios.
It is highly recommended to clean up past cron and Event Trigger logs data from the database before attempting the update if you have a lot of historical data.
You can take a dump of this data before cleaning up if you wish to keep the log history. This data can be restored back into the DB if required post the update.
:::
With support for multiple databases, database connection related config is now stored in Hasura Metadata and the older database specific env vars have been deprecated. See details.
Post update to Hasura v2 these env vars can be removed as they will now be ignored.
This config can now be modified by updating the Hasura Metadata for the connected database(s) via the Console/CLI/APIs.
Update your Hasura CLI project to config v3 using the steps mentioned in
this guide to take full advantages of the features
introduced in Hasura v2.
Post upgrading to config v3, the database connection parameters would have been moved to the metadata. Hence it is
important to ensure that the same env vars are used for storing database connection strings across all environments and
the Metadata being applied also uses the appropriate env vars.
:::info Note
If you do not need multiple database support or any of new features introduced in Hasura v2, like REST endpoints,
inherited roles etc., then you can continue to use config v2 project directory and workflows.
Though we would recommend to upgrade to config v3 anyway as it includes some useful directory structure changes.
:::
The following commands need to be executed in the specified order to apply Metadata and Migrations in CI/CD workflows
config v2:
hasura migrate apply - (apply migrations to the database named "default")hasura metadata apply - (apply metadata to the database named "default")config v3:
hasura metadata apply - (connect Hasura to the databases configured in the metadata)hasura migrate apply --all-databases - (apply the migrations to the connected databases)hasura metadata reload - (make Hasura aware of any newly created database objects in the previous step)In case there are some issues with your Hasura instance post updating to Hasura v2, you can downgrade back to Hasura v1 by reverting the Hasura docker image version and using the downgrade command to revert the Hasura Metadata catalogue changes:
docker run -e HASURA_METADATA_DATABASE_URL=$POSTGRES_URL hasura/graphql-engine:v2.0.0 graphql-engine downgrade --to-v1.3.3
:::info Note
You can downgrade a Hasura v2 instance to Hasura v1 only if there is only one database connected to it.
:::