Typed resolver and authorizer arguments

Tom HouléTom Houlé
Typed resolver and authorizer arguments

End-to-end type safety is an essential part of a good developer experience. Types are not there only to prevent mistakes: they're like documentation the machine understands, so that your editor can help you write code faster in the first place, and they give you the confidence that you can change code, because they're going to remind you of everything that needs to change.

We want to achieve hassle-free, end-to-end type safety for developers building GraphQL APIs at Grafbase. This week, we released one more building block toward that vision: Resolvers and Custom Authorizer arguments and return types in the Grafbase SDK.

Today, a Grafbase custom resolver's signature looks like this:

export default async function (parent, args, context, info) { const { value } = await kv.get(`answers/${parent.id}`) return `⚙️ Result of ${info.fieldName}: ${value}` }

You can read the docs for more details. Notice that you are left on your own to add types to the resolver.

As of the latest release, you will get some help from @grafbase/sdk. Now the same resolver can look like this:

import { Context, Info } from '@grafbase/sdk' export default async function (parent, _args, { kv }: Context, info: Info) { const { value } = await kv.get(`answers/${parent.id}`) return `⚙️ Result of ${info.fieldName}: ${value}` }

The context and info arguments are fully typed, with doc strings and all relevant properties. The context has full typings for Grafbase KV and Grafbase AI.

The parent and args arguments, as well as the return type of the resolver are more dynamic, because they depend on your GraphQL schema. We are working on making them type safe. If you are interested in the design, want to submit ideas or be included early for feedback on our prototype, please talk to us on Discord or any other channel.

Just like resolvers, authorizer functions now have exported types in @grafbase/sdk. They can look like this:

import { AuthorizerContext, VerifiedIdentity } from '@grafbase/sdk' export default async function ({ request, }: AuthorizerContext): Promise<VerifiedIdentity> { // your logic here }

The arguments and return type are independent of your GraphQL schema: this is as type safe as it gets.

You'll find an example with typed resolvers and an authorizer in the examples/ directory of the Grafbase repo.