Skip to content

Commit

Permalink
Document static method fields
Browse files Browse the repository at this point in the history
  • Loading branch information
captbaritone committed Mar 26, 2024
1 parent 1d1c41c commit 957a70f
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 17 deletions.
17 changes: 8 additions & 9 deletions examples/production-app/models/Viewer.ts
Expand Up @@ -7,7 +7,7 @@ import { User } from "./User";
/**
* The currently authenticated viewer.
* @gqlType */
class Viewer {
export class Viewer {
/**
* The currently authenticated user.
* @gqlField */
Expand All @@ -30,13 +30,12 @@ class Viewer {
yield new Post(row);
}
}
}

// --- Root Fields ---
// --- Root Fields ---

/**
* The currently authenticated viewer.
* @gqlField */
export function viewer(_: Query): Viewer {
return new Viewer();
/**
* The currently authenticated viewer.
* @gqlField */
static viewer(_: Query): Viewer {
return new Viewer();
}
}
4 changes: 2 additions & 2 deletions examples/production-app/schema.ts
Expand Up @@ -13,7 +13,7 @@ import { nodes as queryNodesResolver } from "./graphql/Node";
import { posts as queryPostsResolver } from "./models/PostConnection";
import { nodes as userConnectionNodesResolver } from "./models/UserConnection";
import { users as queryUsersResolver } from "./models/UserConnection";
import { viewer as queryViewerResolver } from "./models/Viewer";
import { Viewer as queryViewerResolver } from "./models/Viewer";
import { createLike as mutationCreateLikeResolver } from "./models/Like";
import { createPost as mutationCreatePostResolver } from "./models/Post";
import { createUser as mutationCreateUserResolver } from "./models/User";
Expand Down Expand Up @@ -436,7 +436,7 @@ export function getSchema(): GraphQLSchema {
name: "viewer",
type: ViewerType,
resolve(source) {
return queryViewerResolver(source);
return queryViewerResolver.viewer(source);
}
}
};
Expand Down
7 changes: 3 additions & 4 deletions website/docs/03-resolvers/index.mdx
Expand Up @@ -17,10 +17,7 @@ When defining your resolvers as methods on a class, the initial `obj` argument
is omitted in favor of `this`.
:::

When using the functional style, Grats inspects
the type annotation of the first argument to determine which which type this
field is being defined on. In other word, the definition of the type applied to
the `obj` argument must be annotated with `/** @gqlType */`. Grats will report a helpful error if you forget to do this.
When using the functional or static method style, Grats inspects the type annotation of the first argument to determine which which type this field is being defined on. In other word, the definition of the type applied to the `obj` argument must be annotated with `/** @gqlType */`. Grats will report a helpful error if you forget to do this.

### `args`

Expand All @@ -37,6 +34,8 @@ A value which is provided to every resolver and holds important contextual infor
- Context about the currently logged in user
- Per-request caches, such as [DataLoaders](https://github.com/graphql/dataloader)

Grats will ensure that all resolvers in your project use reference the same type for the `context` argument.

### `info`

A value which holds field-specific information relevant to the current query as well as the schema details, also refer to type [GraphQLResolveInfo](https://graphql.org/graphql-js/type/#graphqlobjecttype) for more details.
Expand Down
12 changes: 10 additions & 2 deletions website/docs/04-docblock-tags/02-fields.mdx
Expand Up @@ -3,6 +3,7 @@ import PropertyAndMethodFields from "!!raw-loader!./snippets/02-property-and-met
import ParameterPropertyFields from "!!raw-loader!./snippets/02-parameter-property-fields.out";
import FunctionExtendQuery from "!!raw-loader!./snippets/02-function-extending-query.out";
import FunctionExtendMutation from "!!raw-loader!./snippets/02-function-extending-mutation.out";
import StaticMethodExtendQuery from "!!raw-loader!./snippets/02-static-method-extending-query.out";

# Fields

Expand All @@ -13,7 +14,8 @@ You can define GraphQL fields by placing a `@gqlField` directly before a:
- Property declaration
- Property signature
- Parameter property
- Function declaration (with named export)
- Function declaration
- Static method

## Class-based fields

Expand All @@ -25,12 +27,18 @@ Fields can also be defined using TypeScript's [parameter properties](https://www

<GratsCode out={ParameterPropertyFields} mode="ts" />

If you want to group root fields `Query` `Mutation` that return or modify a specific type, you can define them as part of that type's class using static methods:

<GratsCode out={StaticMethodExtendQuery} mode="both" />

Grats will use the type of the first argument of the static method to determine which type is being extended. Even if you don't need access to any values on the parent object, you must type your first argument using the parent type so that Grats knows which type your field is on.

For more information about field resolves, see [Resolver Signature](../03-resolvers/index.mdx).

## Functional style fields

If you prefer to avoid classes, types can be defined using type literals. However, this approach does not allow you to define derived/resolver fields. To solve this, Grats
also allows you to **define derived fields using named exported functions**. Function resolvers:
also allows you to **define derived fields using named, exported functions**. Function resolvers:

- Accept an instance of the parent type as the first argument
- Have a return type that matches the field type
Expand Down
@@ -0,0 +1,17 @@
/** @gqlType */
type Query = unknown;

/** @gqlType */
export class User {
constructor(
/** @gqlField */
public name: string,
) {}

// highlight-start
/** @gqlField */
static getUser(_: Query): User {
return new User("Elizabeth");
}
// highlight-end
}
@@ -0,0 +1,60 @@
/** @gqlType */
type Query = unknown;

/** @gqlType */
export class User {
constructor(
/** @gqlField */
public name: string,
) {}

// highlight-start
/** @gqlField */
static getUser(_: Query): User {
return new User("Elizabeth");
}
// highlight-end
}

=== SNIP ===
type Query {
getUser: User
}

type User {
name: String
}
=== SNIP ===
import { User as queryGetUserResolver } from "./02-static-method-extending-query.grats";
import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql";
export function getSchema(): GraphQLSchema {
const UserType: GraphQLObjectType = new GraphQLObjectType({
name: "User",
fields() {
return {
name: {
name: "name",
type: GraphQLString
}
};
}
});
const QueryType: GraphQLObjectType = new GraphQLObjectType({
name: "Query",
fields() {
return {
getUser: {
name: "getUser",
type: UserType,
resolve(source) {
return queryGetUserResolver.getUser(source);
}
}
};
}
});
return new GraphQLSchema({
query: QueryType,
types: [QueryType, UserType]
});
}

0 comments on commit 957a70f

Please sign in to comment.