Skip to content

Instantly share code, notes, and snippets.

@hayes
Created April 6, 2022 05:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hayes/f11aa5ea0095cc26abe9ee80ba72046a to your computer and use it in GitHub Desktop.
Save hayes/f11aa5ea0095cc26abe9ee80ba72046a to your computer and use it in GitHub Desktop.
Pothos schema first concept

Simple SDL

type Query {
  posts(page: Int): [Post!]!
}

type Post {
  author: User
  title: String
}

type User {
  name: String
  posts: [Post!]!
}

Basic schema first usage

// import some metadata/types generated from schema
import { generateSchemaInfo } from 'schema.graphql';

// Create a builder as usual
const builder = new SchemaBuilder({
    plugins: [...],
});

// Generate a new schema helper
const schema = builder.fromSchema(
    generateSchemaInfo,
    // refs provide a way to define TS types for you gql types
    // they can provide a place to add various plugin options
    refs: {
        User: builder.objectRef<{ name: string, id: string }>('User')
        // if no ref is provided for a type, a default type will be derived from shape of the schema
    }
);


// Simple API can be used as a basic resolver map
schema.Query({
    fields: {
        // Just a resolver
        posts:  (_, { page }) => Posts.getPostsPage(page ?? 0),
        // Or with options
        posts: {
            description: 'load some posts',
            resolve: (_, { page }) => Posts.getPostsPage(page ?? 0),
        }
    },
});

schema.User({
    // Fields can also be used more like a normal pothos field definitions
    // This enables interoperability with some more complicated plugins
    fields: t => ({
        // t would have a custom method for each field defined in the schema
        posts: t.posts({
            resolve: (user) => Posts.getPostsByAuthor(user.id)
        }),
        // name resolver is needed because the ref has a name prop that matches the expected type for the name field

    }),
});

Example with the prisma plugin

import { generateSchemaInfo } from 'schema.graphql';

const builder = new SchemaBuilder({
    plugins: [PrismaPlugin],
});

const schema = builder.fromSchema(
    generateSchemaInfo,
    refs: {
        User: builder.prismaObjectRef('User', {
            // prisma plugin specific options can be added here
        }),
        Post: builder.prismaObjectRef('Post', {}),
    }
);

schema.Query({
    fields: t => ({
        posts: t.posts.prismaQuery(query => prisma.posts.findMany(query)),
    }),
});

schema.User({
    fields: t => ({
        posts: t.posts.relation('posts'),
        name: ({ firstName, lastName }) => `${firstName} ${lastName}`,
    }),
});

schema.Post({
    fields: t => ({
        author: t.author.relation('author'),
    }),
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment