nhost / hasura-backend-plus

🔑Auth and 📦Storage for Hasura. The quickest way to get Auth and Storage working for your next app based on Hasura.
https://nhost.github.io/hasura-backend-plus/
MIT License
1.17k stars 188 forks source link

Support for generating types from Hasura #344

Open ziahamza opened 4 years ago

ziahamza commented 4 years ago

Right now the types are manually crafted to work with the GraphQL API from Hasura. It would make it more ideal if they could be generated from Hasura directly. That way, it makes sure that existing code works fine as the schema updates over time

There are a number of tutorials to achieve this here: https://hasura.io/learn/graphql/typescript-react-apollo/codegen/

Plus, integrating the latest version of GraphQL Codegen allows us to transparently support types without polluting each query with the correct types. See: https://the-guild.dev/blog/typed-document-node

plmercereau commented 4 years ago

I see that you like to keep code clean @ziahamza 😊

I like the idea, it will help our code to be better organised. But as the HBP model should not change quite often, I will not be able spare the little time I have in contributing to HBP on this one - maybe more critical issues. You may want to contribute on this one?

@elitan, what do you think about this suggestion?

elitan commented 4 years ago

Again. I'm not sure if this is the right priorities for a project like HBP

To add more dependencies and complexity so solve a problem that don't exist.

I'm not convinced.

elitan commented 4 years ago

I'll revise my answer. I think this could be really good tbh. I'm not a big fan of Typescript because it's just too much work setting up the types from all the responses from GraphQL.

If we could automate this it would be great.

oleksify commented 4 years ago

I used to do this automatically with https://graphql-code-generator.com/. It can even generate ready to use React hooks for you (Apollo or Urql) and many other useful stuff.

elitan commented 4 years ago

How can we get started with this? Anyone who could do like a small example here or in a PR?

I would be happy to help from there.

alexkharech commented 4 years ago

How can we get started with this? Anyone who could do like a small example here or in a PR?

I would be happy to help from there.

@elitan

.env

HASURA_ENDPOINT=http://example.com/v1/graphql
HASURA_GRAPHQL_ADMIN_SECRET=secret

/package.json

"scripts": {
    "generate-sdk": "node -r ./node_modules/dotenv/config ./node_modules/.bin/graphql-codegen"
},
"dependencies": {
    "graphql-request": "1.8.2",
},
"devDependencies": {
    "@graphql-codegen/cli": "^1.18.0",
    "@graphql-codegen/introspection": "^1.18.0",
    "@graphql-codegen/typescript": "^1.17.11",
    "@graphql-codegen/typescript-graphql-request": "^2.0.2",
    "@graphql-codegen/typescript-operations": "^1.17.8",

create graphql files in /src/graphql/**

#ex: /src/graphql/fragments.graphql
fragment User on users {
  __typename
  id
  display_name
  avatar_url
}

fragment Account on auth_accounts {
  __typename
  id
  user_id
}

# ex: /src/graphql/mutations/update_user.graphql
mutation updateUser($userId: uuid!, $set: users_set_input!) {
  user: update_users_by_pk(pk_columns: { id: $userId }, _set: $set) {
    ...User
    account {
      ...Account
    }
  }
}

/codegen.yml

schema:
 - ${HASURA_ENDPOINT}:
      headers:
        x-hasura-admin-secret: ${HASURA_GRAPHQL_ADMIN_SECRET}
documents: ./src/graphql/**/*.graphql
generates:
  ./src/shared/sdk.ts: #output file
    plugins:
      - typescript
      - typescript-operations
      - typescript-graphql-request
    config:
      scalars:
        uuid: string
        date: Date
        timestamptz: Date
        jsonb: '{ [key: string]: any } | null'
        numeric: number
        bigint: number

and run for code generation yarn generate-sdk with ./src/graphql/** watcher yarn generate-sdk --watch

/src/shared/sdk-client.ts

import { GraphQLClient } from 'graphql-request'
import { getSdk } from './sdk'

const client = new GraphQLClient(process.env.HASURA_ENDPOINT || '', {
  headers: {
    'x-hasura-admin-secret': process.env.HASURA_GRAPHQL_ADMIN_SECRET || ''
  }
})

const sdk = getSdk(client)
export default sdk

image

elitan commented 3 years ago

This is a good suggestion but nothing we'll put effort into fixing for HBP.

If someone wants to do it PRs are welcomed. But I'll close this one for now.

elitan commented 3 years ago

I'll reopen this because if someone wants to do it we'd be open to accepting a PR because it's a refactor.

joshua1 commented 2 years ago

I have been using this https://github.com/remorses/genql with nhost v1, not tried on V2 yet, and on Hasura on digital Ocean. I also use Hasura-Camelize https://github.com/bkniffler/hasura-camelize (this first , to alias my entities, then genQL to generate client and type using run-s )