Skip to content

Instantly share code, notes, and snippets.

@Quramy
Last active April 11, 2024 15:34
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Quramy/7b9036f236b2ac2fdac0a2d0f4f49172 to your computer and use it in GitHub Desktop.
Save Quramy/7b9036f236b2ac2fdac0a2d0f4f49172 to your computer and use it in GitHub Desktop.
Analogy RSC and GraphQL resolver
import { cache } from "react";
import DataLoader from "dataloader";
// backend service clients
import { getPopularPosts, getUserById, getUsers } from "@/services";
const memoizedGetUserById = cache(getUserById);
const getUserLoader = () =>
new DataLoader((id: readonly string[]) =>
getUsers(id).then((users) => id.map((id) => users.find((u) => u.id === id)))
);
const memoizedGetUserLoader = cache(getUserLoader);
export async function User({ userId }: { userId: string }) {
// const result = await memoizedGetUserById(userId); This may cause N + 1 problem
const result = await memoizedGetUserLoader().load(userId);
if (!result) return null;
const { name, email } = result;
return (
<div>
<p>{name}</p>
<p>{email}</p>
</div>
);
}
export default async function Posts() {
const posts = await getPopularPosts();
return (
<ol>
{posts.map((post) => (
<li key={post.id}>
<h3>{post.title}</h3>
<User userId={post.authorId} />
</li>
))}
</ol>
);
}
import { createSchema, createYoga } from "graphql-yoga";
// backend service clients
import { getPopularPosts, getUserById, getUsers } from "@/services";
const typeDefs = gql`
type Post {
id: ID!
title: String!
author: User
}
type User {
id: ID!
name: String!
email: String!
}
type Query {
popularPosts: [Post!]!
}
`;
const context = () => ({
userLoader: new DataLoader((id: readonly string[]) =>
getUsers(id).then((users) => id.map((id) => users.find((u) => u.id === id)))
),
});
export const resolvers = {
User: {},
Post: {
author: async ({ authorId }, { userLoader }) => {
// return await getUserById(authorId); // This may cause N + 1 problem
return await userLoader.load(authorId);
},
},
Query: {
popularPosts: async () => {
return await getPopularPosts();
},
},
};
const schema = createSchema({ typeDefs, resolvers });
export const yoga = createYoga({ schema, context });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment