You're not required to follow this exact workflow, but we've found it gives a good developer experience.
We start from the API and then create the frontend. The reason for this is that Bison will generate types for your GraphQL operations which you will leverage in your components on the frontend.
To generate a new GraphQL module we can run the command yarn g:graphql MODULE_NAME, replacing MODULE_NAME with the name of your module. In our example, we'll be using the concept of an Organization.
yarn g:graphql organizationThis should output something like:
yarn run v1.22.10
$ hygen graphql new --name organization
Loaded templates: _templates
added: graphql/organization.ts
inject: graphql/schema.ts
✨ Done in 0.34s.Using our "organization" module example from the last step, we need to update schema.prisma with our data model:
// prisma/schema.prisma
model Organization {
id String @id @default(cuid())
name String
userId String
user User @relation(fields: [userId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}In our example a User has many Organizations, so we need to update our User model as well to reflect this relationship:
// prisma/schema.prisma
model User {
id String @id @default(cuid())
email String @unique
password String
roles Role[]
profile Profile?
organizations Organization[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}Note that we have defined organizations as Organization[].
This is currently a two step process, 1) generate the migration and 2) execute the migration
Generate the migration
yarn g:migrationExecute the migration
yarn db:migrateWrite a type, query, input, or mutation using Nexus
yarn g:test:request-
Add tests cases and update schema code accordingly. The GraphQL playground (localhost:3000/api/graphql) can be helpful to form the proper queries to use in tests.
-
types.tsandapi.graphqlshould update automatically as you change files. Sometimes it's helpful to open these as a sanity check before moving on to the frontend code.
- Generate a new page using
yarn g:page - Generate a new component using
yarn g:component - If you need to fetch data in your component, use a cell. Generate one using
yarn g:cell - To generate a typed GraphQL query, simply add it to the component or page:
export const SIGNUP_MUTATION = gql`
mutation signup($data: SignupInput!) {
signup(data: $data) {
token
user {
id
}
}
}
`;- Use the newly generated hooks from Codegen instead of the typical
useQueryoruseMutationhook. For the example above, that would beuseSignupMutation. You'll now have a fully typed response to work with!
import { User, useMeQuery } from './types';
// adding this will auto-generate a custom hook in ./types.
export const ME_QUERY = gql`
query me {
me {
id
email
}
}
`;
// an example of taking a user as an argument with optional attributes
function noIdea(user: Partial<User>) {
console.log(user.email);
}
function fakeCell() {
// use the generated hook
const { data, loading, error } = useMeQuery();
if (loading) return <Loading />;
// data.user will be fully typed
return <Success user={data.user}>
}