Last active
April 11, 2024 15:34
-
-
Save Quramy/7b9036f236b2ac2fdac0a2d0f4f49172 to your computer and use it in GitHub Desktop.
Analogy RSC and GraphQL resolver
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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