Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting parent, context and pageInfo types for relay plugin #1305

Open
garfieldnate opened this issue Sep 17, 2024 · 3 comments
Open

Setting parent, context and pageInfo types for relay plugin #1305

garfieldnate opened this issue Sep 17, 2024 · 3 comments

Comments

@garfieldnate
Copy link

I'm investigating doing a migration to pothos for a fairly complex existing codebase. We use a custom PageInfo type for relay connections as well as custom Parent and Context types for resolver arguments. Here are our types:

import type { PageInfo } from "graphql-relay";
import { enums } from "globals";
import type { Knex } from "knex";

interface PageInfoWithCount extends PageInfo {
  totalCount?: number | null;
}

export interface ConnectionWithCount<T> extends Connection<T> {
  pageInfo: PageInfoWithCount;
}

interface GraphQLContext {
  myCustomField: string;
  dbConnection: Knex;
  // etc.
}

export interface ParentType {
  __nodeType__: string;
  __dbName__: DBNameType;
  [key: string]: any;
  id: Buffer | number;
}

The relay plugin documentation page lists a large number of options, but doesn't show any examples of using them. I see the following possibly relevant options:

  • pageInfoTypeOptions
  • pageInfoFieldOptions
  • defaultConnectionTypeOptions
  • defaultConnectionFieldOptions
  • I don't see any options for the parent or context types.

Here's some follow-up code that tries to define a resolver using the above types:

import SchemaBuilder, { Resolver } from "@pothos/core";
import RelayPlugin from "@pothos/plugin-relay";

const builder = new SchemaBuilder({
  plugins: [RelayPlugin],
  relay: {
    idFieldName: "ID",
    // ??? not sure what else
  }
});
builder.queryType({
  fields: (t) => ({
    ID: t.globalID({
      // does not type-check
      resolve: (parent: ParentType, args, context: GraphQLContext, resolveInfo) => "foo",
    });
  })
});

The resolver does not type-check, failing with this error:

  Types of parameters 'parent' and 'parent' are incompatible.
    Type '{}' is missing the following properties from type 'ParentType': __nodeType__, __dbName__, id

I apologize if this is a very basic question! Any documentation pointers or tips here would be much appreciated.

@hayes
Copy link
Owner

hayes commented Sep 18, 2024

There is a lot to unpack in this question, and touches a lot of different components.

In general, in Pothos you will almost never define types for your resolver manually. They should always be typed for you based on types provided elsewhere.

This is probably very different than your existing set up, but leads to much better type safety, and an easier developer experience once you get things set up, and understand the patterns being used.

Some of what you asked about isn't well documented, and currently requires some workarounds (mostly extending the pageInfo type to have a totalCount type)

Rather than trying to explain each piece individually, I tried to create a quick interactive demo that adds most of the pieces you asked about:

https://stackblitz.com/edit/typescript-wrj4wo?file=index.ts

@garfieldnate
Copy link
Author

Wow, thank you for such a thorough and fast response!

It looks like Root and Connection in SchemaBuilder's types are not documented, and extending pageInfo is not directly supported, though certainly possible (thank you so much for figuring all of that out for me!). Not sure if these require follow-up tickets.

This gives me plenty to work with for a while. Thanks again!

@hayes
Copy link
Owner

hayes commented Sep 20, 2024

Context is documented here: https://pothos-graphql.dev/docs/guide/context

Root is kind of obscure, it should probably be added to the API docs, but I've never actually seen it used in a real GraphQL API, and I am not entirely sure that it's supported in all the popular graphql server implementations.

Extending existing types is probably something that could be covered in the docs.

I did remember there was a less hacky solution (but also undocumented) to extend pageInfo:

builder.objectField(builder.pageInfoRef(), 'totalCount', ...)

This could probably be documented, and I think won't pick up the extended types from the builder, so would probably require a type cast in the resolver (which probably could also be fixed pretty easily)

PRs for docs are always appreciated if you see something that's missing!

@hayes hayes closed this as completed Sep 20, 2024
@hayes hayes reopened this Sep 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants