Skip to main content
Version: Next (2.x)

First module

A module bundles a slice of your GraphQL schema (.gql), its generated types (typedef.ts), and its resolvers (*.ts) into a single folder. This page walks through building a small user module end-to-end.

Creating a module

1. Define the schema

Create your first schema file at src/modules/user/user.gql:

type User {
id: ID!
name: String!
}

type Query {
user(id: ID): User
}
tip

You can split your schema into multiple files (types, inputs, queries) as your module grows.

2. Generate the types

yarn build

This produces src/modules/user/typedef.ts with the types for everything declared in user.gql.

tip

Use --watch (or the start script wired up in Configuration) to regenerate on file change.

3. Implement the resolvers

src/modules/user/resolvers.ts:

import { UserModule } from "./typedef.ts";

const { Query, User } = UserModule;

export const userResolver = User.$fields({
id: User.id.key("id"),
name: User.name.key("name"),
});

export const queryResolver = Query.$fields({
user: Query.user.resolve(({ args }) => {
return {
id: args.id,
name: "John Doe",
};
}),
});
tip

key("name") is shorthand for .resolve(({ source }) => source.name). The default source for a type matches the GraphQL type itself; override it via Custom Types when your data layer's shape differs.

4. Export the module

src/modules/user/index.ts:

import { queryResolver, userResolver } from "./resolvers.ts";
import { UserModule } from "./typedef.ts";

export default UserModule.$schema({
User: userResolver,
Query: queryResolver,
});

Project structure

The module now lives in its own folder:

src/modules/user/
├── user.gql # schema
├── resolvers.ts # query/mutation implementations
├── typedef.ts # generated types (don't edit)
└── index.ts # module export

Next

Extend the module with a second one to see how Baeta stitches modules together.