Skip to content

v1.0.0-beta.8

Pre-release
Pre-release
Compare
Choose a tag to compare
@hasura-bot hasura-bot released this 22 Oct 08:30
· 8319 commits to master since this release

Changelog

Note: This release fixes the bugs with beta.7 and this is a combined changelog since beta.6.

Upgrading & downgrading

  • You can upgrade to beta.8 from any version.

  • Downgrading: You may need to manually run SQL scripts if your downgrade path involves a catalog change. Please see this for catalog history.

Read more about upgrading and downgrading.

Table of contents 🗂

  • Customize names of root fields and column fields

  • Computed fields

  • Create permissions with conditions spanning tables

  • Performance optimisations

    • Compress HTTP responses
    • Optmization for all subscriptions
  • Annotate GraphQL schema for better documentation

  • Update conditionally when using upsert

  • Better support for Postgres connection string parameters

  • Docs

  • Others


Customize the names of root fields and column fields 🏷

This change allows customizing the names of root fields and the column fields in Hasura's GraphQL schema.

E.g. the default root field names generated for a table named author are:

Queries/Subscriptions:

  • author
  • author_by_pk
  • author_aggregate

Mutations:

  • insert_author
  • delete_author
  • update_author

The above and the names of the column fields can now be customized.

How to customize

Console
(to be available shortly)

  • Customizing root fields names: Head to the Modify tab of the table whose generated root fields you want to change:

  • Customizing column field names: Head to the Modify tab of the table whose column fields you want to alias and edit the column for an option to provide a custom name:

Metadata API

The v2 track_table allows you to specify all the customizations while tracking a table. Here's an example request:

POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
   "type": "track_table",
   "version": 2,
   "args": {
     "table": "authors",
     "configuration": {
        "custom_root_fields": {
           "select": "authors",
           "select_by_pk": "author",
           "select_aggregate": "authorStats",
           "insert": "createAuthors",
           "update": "updateAuthors",
           "delete": "removeAuthors"
        },
        "custom_column_names": {
           "id": "authorId"
        }
     }
   }
}

For tables that have already been tracked, you can use the set_table_custom_fields metadata API:

POST /v1/query HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
   "type": "set_table_custom_fields",
   "version": 2,
   "args": {
     "table": {
        "name": "site_employees",
        "schema": "rocc"
		},
     "custom_root_fields": {
           "select": "authors",
           "select_by_pk": "author",
           "select_aggregate": "authorStats",
           "insert": "createAuthors",
           "update": "updateAuthors",
           "delete": "removeAuthors"
     },
        "custom_column_names": {
           "id": "authorId"
        }
   }
}

⚠️ Warnings ⚠️

  • The original Postgres table and column names are used in metadata definitions for relationships, permissions etc.
  • Please ensure that your client apps are in sync with this change as once you begin using custom names, requests with the original field names will result in an error.
  • Known limitations: an error is thrown if the custom name and the original name of a column are the same. This is being fixed in #3154.

Computed fields

Computed fields are virtual values or objects that are dynamically computed and can be queried along with a table's columns. Computed fields are computed when requested for via SQL functions using other columns of the table and other custom inputs if needed. See pull request description.

Adding a computed field

Computed fields are added to a table via SQL functions. Any SQL function which accepts table row type as one of the input arguments, returns base types (integer, Text, etc.) or SETOF <table-name> and not VOLATILE can be added as computed field.

Example:-

Let's say we have a table, author, that has two text columns, first_name and last_name, and we want to enrich the table with a virtual field that combines these columns into a new one, full_name. We can do this by adding a computed field:

  1. Define a SQL function called author_full_name:

     CREATE FUNCTION author_full_name(author_row author)
     RETURNS TEXT AS $$
       SELECT author_row.first_name || ' ' || author_row.last_name
     $$ LANGUAGE sql STABLE;
  2. Add a computed field, full_name to the author table with the SQL function above using the following API.

    POST /v1/query HTTP/1.1
    Content-Type: application/json
    X-Hasura-Role: admin
    
    {
        "type":"add_computed_field",
        "args":{
            "table":{
                "name":"author",
                "schema":"public"
            },
            "name":"full_name",
            "definition":{
                "function":{
                    "name":"author_full_name",
                    "schema":"public"
                },
                "table_argument":"author_row"
            }
        }
    }
  3. Query the data from author table along with its computed fields.

    query {
          author {
            id
            first_name
            last_name
            full_name
          }
        }

    Response:

    {
      "data": {
        "author": [
          {
            "id": 1,
            "first_name": "Chris",
            "last_name": "Raichael",
            "full_name": "Chris Raichael"
          }
        ]
      }
    }

Please see docs to learn more about computed fields and their metadata API.


Create permissions with conditions spanning tables 🔐

This change allows you to use data in unrelated tables to build a permission rule using the new _exists keyword. Let's use an example to see how this works:

Say you have the following two tables:

  • users

    Columns Type
    id Integer
    is_admin Boolean
  • accounts

    Columns Type
    id Integer
    account_info Text

and you want to restrict access to the accounts table to only those users who are "admins" i.e. the value of the is_admin column is true for the given user_id (which is sent in the X-Hasura-User-Id session variable).

To compose a permission rule for this use-case, you can check if there's a row in the users table where id = X-Hasura-User-Id and is_admin = true:

Like all the other operators, you can use logical operators (_and, _or and _not) to further restrict access to a subset of the rows.


Performance optimisations

Compress HTTP responses 🗜️

HTTP responses from Hasura are now compressed (using gzip) by default whenever supported by the requesting client. In anecdotal tests, we've noticed approximately 10X compression in response payloads with negligible overhead for handling compression in the server and in client apps.

This should be especially useful to handle introspection queries on large datasets. We haven't yet benchmarked these changes in scenarios where network latency is a significant factor in overall latency, and any reports from the community on this front will be much appreciated!

Optmization for all subscriptions 🎚

The previous iteration of this change only optimised subscriptions that did not use non-scalar variables. This has now been fixed, and requests with non-scalar variable values, such as the following, are now multiplexed if they generate the same SQL:

subscription latest_tracks($condition: tracks_bool_exp!) {
  tracks(where: $tracks_bool_exp) {
    id
    title
  }
}

Annotate GraphQL schema for better documentation 🖍

You can now annotate your GraphQL schema for better readability by adding comments to your Postgres schema elements i.e. tables, views, columns and functions. These comments will be displayed in the Docs window of GraphiQL:

Note: Currently, you can add comments for tables, views and column names using the console, but for functions you'll need to run a SQL query that does the same (support for this will be added to the console shortly).


Update conditionally when using upsert (where clause in on_conflict input object)

When using upsert, you can now conditionally update only a subset of rows using the new optional where clause in the on_conflict input object. Here's an example mutation:

mutation {
  insert_item(
    objects: {itemId:"1234", creationEpochSeconds: 1567026834},
    on_conflict: {
    	constraint: item_pkey,
        update_columns: [itemId, creationEpochSeconds]
        where: {creationEpochSeconds: {_lt: 1567026834 }}
    }) {
    affected_rows
  }
}

Better support for Postgres connection string parameters 🔌

Native support for the database connection string is now available and you can leverage the optional parameters in the string with Hasura. Examples of parameters you can now use:

  • application_name
  • ssl
  • connection_timeout
  • IPv6 (host address for the GraphQL engine -> Postgres connection)

Please see this for details on parameters.


Docs 📖


Others

  • This release also includes bug-fixes and other minor changes.

  • A big shoutout to:

    • @lorenzo for extending the graceful shutdown behaviour to WebSocket connections
    • @abn for disables auto-update checks when the cli is used in the entrypoint script for the cli-migrations container