hasura / hasura/graphql-engine
[SPEC] Building a great Codegen platform for Hasura
- Dominant language
- TypeScript
- Stars
- 32.1k
- Forks
- 3k
- PR merge metrics
- PR metrics pending
Description
# Overview
I wanted to open an issue to get feedback and start a community discussion around how to build an optimal base platform for doing codegen in Hasura.
While setting out to build some codegen plugins of my own, I noticed that the official examples use native JS array methods for working with the GraphQL AST, which leads to things like this:
```js
const operationName = operationDoc.definitions[0].selectionSet.selections.filter(
s => s.name.value.indexOf('__') !== 0
)[0].name.value;
```
Unfortunately, for as much ***general*** tooling as there in the general ecosystem, online you will not find a lot of information about working with the low level bits in `graphql/language` and `graphql/utilities` (I assume because few people want to go mucking about with AST transforms).
The `graphql` library provides a `visit` method, which recursively walks the AST and allows you to pattern-match on node kinds during traversal. With this, you have a lot more power and expressibility/flexibility in ways you can work.
One major factor I wanted to address is **_codegen for language-specific type definitions (e.g. GraphQL type -> Go struct/Kotlin type)_**. The way this is done for Typescript currently is with `graphql-code-generator`. **The problem with this approach is that it only supports a number of plugins/languages, and outside of that you are SOL.** It would be optimum to write a base parser/generator for Codegen so that there is more flexibility here.
**To this end, I spent the past several days diving into the GraphQL source, and have come up with a rough draft using `visit` which you can see here (press RUN):**
https://repl.it/@GavinRay97/OurBlankCygwin
# Details
Given a schema of the following:
```gql
type Mutation {
InsertUserAction(user_info: UserInfo): TokenOutput
}
input UserInfo {
username: String!
password: [String]
}
type TokenOutput {
accessToken: String!
}
```
It produces:

The core of it is very tiny (~30 lines) and only has a [dependency on a library which is a convenience wrapper around `graphql`](https://github.com/vadistic/graphql-extra), so no real dependencies outside of `graphql` itself:

# Conclusion
Now the goal is to provide some class/module which can take a schema string, parse out the typemap, and allow you to do something like:
```js
const hasuraCodegen = new HasuraCoden(schema)
hasuraCodegen.types.forEach(type => {
console.log(type.toGoType())
console.log(type.toJavaType())
console.log(type.toTypescriptType())
})
```
Any ideas/suggestions or help are much appreciated.
Contributor guide
Research direction
Start with the linked repl.it draft, then read the GraphQL AST `visit` API and the existing `graphql-code-generator` approach described in the issue. There are no repository files or tests named; the broad goal is a schema parser/generator supporting language-specific type output, but the concrete scope and completion criteria need to be decided first.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- graphql, typescript
- Domain
- api, developer-experience, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100