Skip to main content

Custom Queries

As a product gets more complicated, adding custom queries to the schema becomes essential. This shows how to do so.

Viewer​

The Viewer, which was introduced earlier is never automatically exposed in the GraphQL schema because there's no uniformity in what can be exposed across different products. So if/when this needs to be exposed, it has to be done manually.

Here's an example which exposes Viewer :

src/graphql/resolvers/viewer.ts
@gqlObjectType({ name: "Viewer" })
export class ViewerType {
constructor(private viewer: Viewer) {}

@gqlField({
class: 'ViewerType',
type: GraphQLID,
nullable: true,
async: true,
})
async viewerID() {
const user = await this.user();
if (!user) {
return null;
}
return encodeGQLID(user);
}

@gqlField({
class: 'ViewerType',
type: User,
nullable: true,
async: true,
})
async user(): Promise<User | null> {
const v = this.viewer.viewerID;
if (!v) {
return null;
}
return User.loadX(this.viewer, v);
}
}

export default class ViewerResolver {
@gqlQuery({
class: 'ViewerResolver',
name: "viewer",
type: 'ViewerType',
args: [
gqlContextType(),
],
})
viewer(context: RequestContext): ViewerType {
return new ViewerType(context.getViewer());
}
}

This updates the GraphQL schema as follows:

src/graphql/generated/schema.gql
type Viewer {
viewerID: ID
user: User
}

type Query {
viewer: Viewer!
}

Here's what's happening here:

  • This adds a new object Viewer to the GraphQLSchema represented by the class ViewerType.
  • Viewer object has 2 fields:
    • nullable viewerID of type ID
    • nullable user of type User
  • New field viewer added to Query Type.

This uses the following concepts to implement this:

gqlQuery​

This adds a new field to the GraphQL Query type. See example usage above.

Accepts the following options which overlap with gqlField:

  • class for the name of the class the function is defined in.
  • name for the name of the GraphQL field
  • description of the field
  • type: type returned by the field