Skip to main content

Welcome to Grats

What if building a GraphQL server were as simple as just writing functions?

When you write your GraphQL server in TypeScript, your fields and resovlers are already annotated with type information. Grats leverages your existing type annotations to automatically extract an executable GraphQL schema from your generic TypeScript resolver code.

By making your TypeScript implementation the source of truth, you never have to worry about valiating that your implementiaton matches your schema. Your implementation is your schema!

How it works

Grats works as a built step which statically analyzes your TypeScript code and extracts a .graphql schema file. This file can be shared with other tools, but also used directly by Grats' slim runtime wrapper around graphql-js to build a GraphQL endpoint.

To tell Grats which parts of your code to expose in the schema, simply annotate them with docblock tags like /** @gqlField */. Grats will scan your code for these tags and use them to automatically build your schema.

note

In some cases Grats may prompt you to use more explicit type annotations to ensure that it can "see" all the relevent type information.

Examples

Grats is flexible enough to work with both class-based and functional approaches to authoring GraphQL types and resolvers.

/** @gqlType */
export default class Query {
/** @gqlField */
me(): User {
return new User();
}
/**
* @gqlField
* @deprecated Please use `me` instead. */
viewer(): User {
return new User();
}
}

/**
* A user in our kick-ass system!
* @gqlType */
class User {
/** @gqlField */
name: string = "Alice";

/** @gqlField */
greeting(args: { salutation: string }): string {
return `${args.salutation}, ${this.name}`;
}
}

Output

Both of the above examples define the following GraphQL schema:

type Query {
me: User
viewer: User @deprecated(reason: "Please use `me` instead.")
}

"""
A user in our kick-ass system!
"""
type User {
name: String
greeting(salutation: String!): String
}