GraphQL: How to Make a Relay Connection Type with Nexus by Prisma

I really like using the format of Relay Connection Types as they create uniform output on GetAll<name> queries. It’s very easy on the front end to only have to check for edges and nodes, and makes for very reusable code.

The question was, how does one create Relay connections with Nexus by Prisma? Well it actually isn’t that hard to create the types, what took some thought was how to resolve the data retrieval into the types. I’m going to first place all types below.

export const PageInfo = objectType({
  name: "PageInfo",
  definition(t) {
    t.string("startCursor", { nullable: true });
    t.boolean("hasPreviousPage");
    t.string("endCursor", { nullable: true });
    t.boolean("hasNextPage");
  }
});

const userConnection = objectType({
  name: "userConnection",
  definition(t) {
    t.int("total_count");
    t.list.field("edges", { type: userEdge });
    t.field("pageInfo", { type: PageInfo });
  }
});
export const userEdge = objectType({
  name: "userEdge",
  definition(t) {
    t.string("cursor");
    t.field("node", { type: "user" });
  }
});

const User = objectType({
  name: "user",
  definition(t) {
    t.id("id");
    t.string("name");
    t.field("signedUp", { type: "dateTime" });
  }
});

Now that’s not too bad, but how do you get data into the page info, and total count? I’m going to do a real generic example of a resolver for the agove, as there are many way to retrieve the data.

const Query = objectType({
  name: "Query",
  definition(t) {
    t.field("users", {
      type: "userConnection",
      nullable: true,
      args: {
        where: arg({
          type: "UserInputType",
          required: true
        })
      },
      resolve: async (
        root,
        { where }: { where: userArgs },
        ctx: Context,
        info
      ) => {
        const { nextToken, previousToken, users } = await ctx.getUsers({
          where
        });

        // many ORMs and APIs have ways to get tokens
        const pageInfo = {
          hasPreviousPage: !!previousToken,
          startCursor: previousToken ? previousToken : null,
          hasNextPage: !!nextToken,
          endCursor: nextToken ? nextToken : null
        };

        let edges = [];
        if (users && users[0]) {
          edges = users.map(user => ({
            node: { ...user },
            cursor: user.id // this is up to your implementation
          }));
        }

        const total_count = users ? users.length : 0;

        return { pageInfo, edges, total_count };
      }
    });
  }
});

I hope this helps those trying to implement a Relay Connection Type with Nexus. Let me know if you have any questions.

Posted in

Andrew Obrigewitsch

Andrew is a Senior Software Engineer based out of Sacramento California, he works at are large software company that handles massive data sets. He builds both backend and frontend solutions to handle said large data sets. He is passionate about new technologies which make developing faster, easier and achieve more uniform and predication results.

Reader Interactions

Leave a Reply

Your email address will not be published. Required fields are marked *