Graphql-engine: Custom GraphQL types for tables not conforming to GraphQL naming spec

Created on 31 Jan 2020  ·  4Comments  ·  Source: hasura/graphql-engine

Version: 1.1.0-beta.2

I have a table from an underlying, existing database that is a legacy table with spaces in the name. Let's call it "User Accounts". This name does not conform to the GraphQL naming standard and thus cannot be exposed over the API.

In an attempt to solve this issue - I went to Modify -> Custom GraphQL Root Fields and , under the Query and Subscription section made the Select "UserAccounts" and hit save. The message said it was successful but I am not seeing "UserAccounts" anywhere under my available Schemas on the GraphIQL page.

The docs say this is available as of version v1.0.0-beta.8 and higher but I am using 1.1.0-beta.2 and it doesn't appear to be working.

console server intermediate high

Most helpful comment

When we track a table, the table name becomes the root for every field name and type name that is generated, for example <table_name>_by_pk, <table_name>_aggregate, <table_name>_bool_exp etc.

1. Table Identifier

Let's introduce a new optional top level field under configuration called identifier which takes a replacement for <table_name> in the field and type names that are generated, i.e, when an identifier is given, the generated field and type names will be <identifier>_by_pk, <identifier>_aggregate, <identifier>_bool_exp etc. When the identifier is absent, it will default to the table's name.

This will help these two use cases:

  1. Exposing a table whose name is not a valid GraphQL identifier.

    {
      "type": "track_table",
      "version": 2,
      "args": {
        "table": "user profile",
        "configuration": {
           "identifier": "user_profile"
        }
      }
    }
    
  2. To retain the same API when a table's name changes.

    {
      "type": "track_table",
      "version": 2,
      "args": {
        "table": "new_table",
        "configuration": {
           "identifier": "old_table"
        }
      }
    }
    

2. Custom Type Names

We currently do not allow customising the names of generated types. Let's add a new option, custom_type_names under configuration through which every type name that is generated for a table is customized.

{
   "type": "track_table",
   "version": 2,
   "args": {
     "table": "author",
     "configuration": {
        "custom_root_fields": {
           "select": "Authors",
           "select_by_pk": "Author",
           "select_aggregate": "AuthorAggregate",
           "insert": "AddAuthors",
           "insert_one":"AddAuthor",
           "update": "UpdateAuthors",
           "update_by_pk": "UpdateAuthor",
           "delete": "DeleteAuthors",
           "delete_by_pk": "DeleteAuthor"
        },
        "custom_type_names" : {
          "selection": "Author",
          "selection_aggregate": "AuthorAggregate",
          "boolean_expression": "AuthorBooleanExpression"
          ...
        }
     }
   }
}

3. Introduce set_table_configuration

Deprecate the set_table_custom_fields and introduce a new query type called set_table_configuration which takes and sets the entire configuration.

{
   "type": "set_table_configuration",
   "args": {
     "table": "user profile",
     "configuration": {
       "identifier": "user_profile"
     }
   }
}

All 4 comments

The API that you use is for fields but the type (of the table) needs to be changed as well. Changing the title of this issue to reflect the same.

When a new table type is given, then all the corresponding fields should change to the new name like insert_new_name automatically unless a field name is also provided.

See the new spec in comment below by 0x777

Old Spec (previously in #4821) :

For postgres, we already have a set_table_custom_fields API which allows you to rename top-level fields and column names: https://hasura.io/docs/1.0/graphql/manual/api-reference/schema-metadata-api/table-view.html#set-table-custom-fields

This can include custom_table_type key which will change the name of the type of table. E.g.

{
   "type": "set_table_custom_fields",   # see note at the bottom about changing the type of this metadata query
   "version": 2,
   "args": {
     "table": "author",
     "custom_root_fields": {
        "select": "Authors",
        "select_by_pk": "Author",
        "select_aggregate": "AuthorAggregate",
     },
     "custom_column_names": {
        "id": "authorId"
     },
     “custom_table_type”: “myauthor”
   }
}

This should be possible via track_table version 2 API also:

{
   "type": "track_table",
   "version": 2,
   "args": {
     "table": "author",
     "configuration": {
        "custom_root_fields": {
           "select": "Authors",
           "select_by_pk": "Author",
           "select_aggregate": "AuthorAggregate",
           "insert": "AddAuthors",
           "insert_one":"AddAuthor",
           "update": "UpdateAuthors",
           "update_by_pk": "UpdateAuthor",
           "delete": "DeleteAuthors",
           "delete_by_pk": "DeleteAuthor"
        },
        "custom_column_names": {
           "id": "authorId"
        },
        "custom_table_type" : "myauthor"
     }
   }
}
  1. When a new table type is given, then all the corresponding fields should change to the new name like insert_new_name automatically unless a field name is also provided.

  2. We may want to deprecate type: set_table_custom_fields and create the more general (and consistent with track_table api) type: set_table_configuration going forward.

When we track a table, the table name becomes the root for every field name and type name that is generated, for example <table_name>_by_pk, <table_name>_aggregate, <table_name>_bool_exp etc.

1. Table Identifier

Let's introduce a new optional top level field under configuration called identifier which takes a replacement for <table_name> in the field and type names that are generated, i.e, when an identifier is given, the generated field and type names will be <identifier>_by_pk, <identifier>_aggregate, <identifier>_bool_exp etc. When the identifier is absent, it will default to the table's name.

This will help these two use cases:

  1. Exposing a table whose name is not a valid GraphQL identifier.

    {
      "type": "track_table",
      "version": 2,
      "args": {
        "table": "user profile",
        "configuration": {
           "identifier": "user_profile"
        }
      }
    }
    
  2. To retain the same API when a table's name changes.

    {
      "type": "track_table",
      "version": 2,
      "args": {
        "table": "new_table",
        "configuration": {
           "identifier": "old_table"
        }
      }
    }
    

2. Custom Type Names

We currently do not allow customising the names of generated types. Let's add a new option, custom_type_names under configuration through which every type name that is generated for a table is customized.

{
   "type": "track_table",
   "version": 2,
   "args": {
     "table": "author",
     "configuration": {
        "custom_root_fields": {
           "select": "Authors",
           "select_by_pk": "Author",
           "select_aggregate": "AuthorAggregate",
           "insert": "AddAuthors",
           "insert_one":"AddAuthor",
           "update": "UpdateAuthors",
           "update_by_pk": "UpdateAuthor",
           "delete": "DeleteAuthors",
           "delete_by_pk": "DeleteAuthor"
        },
        "custom_type_names" : {
          "selection": "Author",
          "selection_aggregate": "AuthorAggregate",
          "boolean_expression": "AuthorBooleanExpression"
          ...
        }
     }
   }
}

3. Introduce set_table_configuration

Deprecate the set_table_custom_fields and introduce a new query type called set_table_configuration which takes and sets the entire configuration.

{
   "type": "set_table_configuration",
   "args": {
     "table": "user profile",
     "configuration": {
       "identifier": "user_profile"
     }
   }
}
Was this page helpful?
0 / 5 - 0 ratings