Graphql-engine: customise generated type names in graphql schema

Created on 5 Nov 2018  ·  23Comments  ·  Source: hasura/graphql-engine

Hi. It will be cool to let a developer select which style of schema's root resolver and type names to use. Or let him override it in a console (separately for an object and arrays).
In my case, I already have a frontend on ApolloStack (about 60000 lines of code) + backend on JoinMonster, and it's too hard to replace joinMonster to Hasura, because I need to transform schema, like this:

export default async function getSchema() {
    const link = makeHttpAndWsLink(HASURA_GRAPHQL_ENGINE_URL, HASURA_ACCESS_KEY && { 'x-hasura-access-key': HASURA_ACCESS_KEY })

    const schema = makeRemoteExecutableSchema({
        schema: await introspectSchema(link),
        link
    })

    return transformSchema(schema, [
        new RenameTypes(type => pluralize.singular(capitalize(camelCase(type)))),
        new RenameRootFields((operation, name) => {
            let newName = name

            if (name.includes('_by_pk')) {
                newName = pluralize.singular(newName.replace('_by_pk', ''))
            }

            return camelCase(newName)
        })
    ])
}

I want to:

  • Type names must be in camelcase style
  • Type names must begin with a capital letter
  • Type names must be in the singular (even if the table name is in the plural) because it describes one object
  • Root resolvers names must be in camelcase style
  • Root resolvers names which returning arrays must be in the plural
  • Root resolvers names which returning an object must be in the singular (_by_pk, for example)

Example:
Before:

user_parties: [user_parties!]!
user_parties_by_pk: user_parties

After:

userParties: [UserParty!]!
userParty: UserParty
console server enhancement mockup-required 🖊️ high

Most helpful comment

@coco98, @0x777 is this still planned to be supported?

Also, we should allow aliasing of the postgres schema names so that people can change the prefixing behaviour. For example, being able to disable schema name prefixing altogether.

The custom_root_fields and custom_column_names customizations work great added by #2509, but it would be great to have the same kind of customization for the type names/prefixes as well.

Is there an issue or PR where this is being implemented?

Thanks!

All 23 comments

I don't think camelCase is actually useful.
In my case, i use user_parties as translation key for i18n.

@Maxpain177 What you are proposing is complete customisability for the schema generated by Hasura from your Postgres tables, right? Like camel case vs snake case, singular vs plural etc.

I have added an ideas label so that we can discuss further.

@Maxpain177 What you are proposing is complete customisability for the schema generated by Hasura from your Postgres tables, right? Like camel case vs snake case, singular vs plural etc.

I have added an ideas label so that we can discuss further.

Yes exactly

The server can add a field_names option to the track_table API to customise fields at the top level.

For example, for an article table

{
    "select": "Articles",
    "select_by_pk": "Article",
    "select_aggregate": "ArticleAggregate",
    "insert" : "AddArticles",
    "update" : "UpdateArticles",
    "delete" : "DeleteArticles"
}

I'm not sure about how to allow customisation of the column names. For relationships, it is already under the user control. However for every array relationship, we also generate a _aggregate field which we should allow to be customised. That can be part of the create_array_relationship API.

The console can then do the hard part of automatically adding the correct field names to the track_table request based on the user's choice, snake case or camel case etc.

Thoughts @rikinsk @praveenweb @coco98 ?

@0x777, @shahidhk, @rikinsk, @praveenweb, @coco98
I think we also should allow being customized fields in tables.

@Maxpain177 That might complicate things a bit but I see your point.

yes, I would like to customise the schema as well.

Since data coming from graphql flow into code, it is better to have semantic names for better maintainability. For example, if graphql return list of users, I would like to have data property name to be users instead user.

yes, I would like to customise the schema as well.

Since data coming from graphql flow into code, it is better to have semantic names for better maintainability. For example, if graphql return list of users, I would like to have data property name to be users instead user.

While we wait for implementing this feauture by Hasura Team, we can use graphql aliases.

I got excited when I checked the features of Hasura, however when I set up Hasura using Heroku I really did not like it just because of naming conventions used by Hasura.

I started creating table and column names, soon while entering column names I realized that my column name contains error, it was because I used "firstName" while it expected "first_name", but I thought let it be, its just name of columns in DB, we would not be typing these in angular frontend as I thought there would be something in Hasura to convert these to camel case in API.

Going forward I wrote a query in GraphiQl but disappointed to see it has all field names as "first_name" and not firstName, more to it the functions names "insert_user". I just don't understand why? Why this cannot be as simple as "createUser". Still not a big problem for developing apps with Hasura.

Next, I see this user: [], Now this is really problematic as it would create confusion for developers. I think this is important, we should be writing users to get multiple users and single user by writing user not user_by_pk.

One more thing instead of "returning" can't we use something like "nodes" or just "items"

@JeetChaudhari Thanks for your input. This issue will address your concerns. However, if this is possible for you, in the time being, naming your tables the way you would like your schema variables will address the concerns you mentioned.

Eg: Name your table users, and your columns 'firstName'. :)

I've created a sample console with a sample users table here:
https://api-days.herokuapp.com/console/api-explorer?query_file=https://gist.githubusercontent.com/coco98/7d2e8992af7d2ce0224619d8b8ff21ce/raw/f632c01838c9399b5782650d10c17a20f4831b33/camecase.graphql

@coco98 I was thinking about same, Thank you for showing me how to do it. Currently, I would do my project as you explained but I hope in the near future Hasura team changes the names to "user_by_pk" => "user" or "accountByAccountId" => "account".

@JeetChaudhari Sure :)

Also, uou can rename relationships very easily. The default names are just generated for convenience and ensure that there are no overlapping relationship names for the same table.
You can delete the relationship and then name it to whatever you want :)

@coco98 Thank You for the info, I wasn't knowing that relationships can be renamed.

@coco98 I did exactly the way you mentioned. Here is the link for Heroku hosted app https://hasura-naming-convension.herokuapp.com/console/api-explorer.

Now there are two cases.

  1. If we select table name as singular (user) we get queries as user: [] and user_by_pk: {}. In this case, user query returning multiple users is confusing.

  2. If we select table name plural (users) we get queries as users: [] and users_by_pk: {}. In this case, users_by_pk query returning single user is confusing.

The point is changing table names does not solve the confusion completely. I strongly believe the suggestions made by @Maxpain177 should be implemented while Hasura is still at alpha stage.

FYI though you may know it already, Postgraphile allows the naming and other customizations via plugins https://www.graphile.org/postgraphile/make-add-inflectors-plugin/

This could be also helpful for Hasura I guess.

@ivawzh I know, I switched to postgraphile due to following facts after trying Hasura.

  1. The main reason is postgraphile can be used in multiple ways including CLI, library, and schema only which means I can easily integrate it with NestJs framework with Apollo server to implement my business logic there and my team can manage everything in a single server application.
  2. Postgraphile supports plugins so we can create plugins according to our need.
  3. The naming conventions used by Hasura in my personal opinion is a pain and confusing for my team. More to it, there is no way we can change those apart from the relation names. Postgraphile has a plugin which does this efficiently.
  4. Postgraphile has been developed in JS which means my team can work on its core features as they are familiar with the stack used.
  5. Postgraphile does not have build in support for subscriptions but, I am working on currently developing one plugin for that (almost ready, within one or two days it would be on GitHub), which would not provide live queries (maybe in future) but would provide features provided by Prisma subscriptions with less filter options(maybe in future there would be more).

Once Hasura solves most of these issues and becomes stable I would give it another try.

@JeetChaudhari The main reasons to use Hasura to me:

  • Haskell instead of Javascript, means better performance and stability.
  • Built-in RBAC means i don't have to manually code my authorization logic.
  • Naming convention ? insert_users is fine, what's wrong ?
  • Hasura has built-in subscription for all query mean all of my query now is live.
  • Hasura has built-in event triggers means i can easily scale my application per my need as app grows.
  • Hasura has built-in remote schema stitching means i don't have to manually merge remote schemas on my side, and the performance is 10x better.
  • Future release will include custom postgres function as query and mutation !
  • Hasura has built-in Console UI, means i don't have to use local PGAdmin to manage my data.

I tried Postgraphile before and it's no way better than Hasura.

@revskill10 @JeetChaudhari Thanks for your comments and notes.
We'll take especially the naming stuff into account. I think aliasing made easy via the console will work well :)

@karibertils FYI

Also, we should allow aliasing of the postgres schema names so that people can change the prefixing behaviour. For example, being able to disable schema name prefixing altogether.

@coco98, @0x777 is this still planned to be supported?

Also, we should allow aliasing of the postgres schema names so that people can change the prefixing behaviour. For example, being able to disable schema name prefixing altogether.

The custom_root_fields and custom_column_names customizations work great added by #2509, but it would be great to have the same kind of customization for the type names/prefixes as well.

Is there an issue or PR where this is being implemented?

Thanks!

it would be great to have the same kind of customization for the type names/prefixes as well

Being tracked here: https://github.com/hasura/graphql-engine/issues/3811

Was this page helpful?
0 / 5 - 0 ratings