next-ai-news
next-ai-news copied to clipboard
Add a GraphQL API using Fuse
Summary
This sets up a GraphQL API for next-ai-news
using Fuse.
Instead of having database queries in the server components directly, this introduces a central data layer that can be used across server- and client components to resolve data.
This, of course, adds additional complexity & code by introducing an extra layer in the architecture. Whether that additional layer is worth the overhead really depends on the goals of this project; I cannot make that tradeoff decision.
Implementation notes
- The data layer is defined in the
types/
folder, mostly in thetypes/Story.ts
node - The API's schema (see the generated
schema.graphql
) matches the underlying database schema- …except for adding a
User
node and exposing a stories submitter centrally asStory.submitter
, whether it's AI generated or from an authenticated user (i.e.story.submitted_by ?? story.username
only exists once in the API layer and is opaque to the client)
- …except for adding a
- In server components, data is resolved in-process without a network hop
-
execute
runs GraphQL resolution in-process so the data gets resolved from the server rendering process immediately
-
- The API is accessible for client components via an API route at
/api/fuse
- Components define their data requirements the same way whether they are eventually resolved in-process (with
execute
) or via the API route (withuseQuery
) - Currently, there are no client components that request data, so we could remove the API route entirely if wanted.
- Components define their data requirements the same way whether they are eventually resolved in-process (with
- Everything is type-safe from the Drizzle db queries to the client components and I kept the client code as similar as possible with minimal changes
- I changed the individual story URLs from
story.id.replace(/^story_/, "")
to Fuse's opaque unique IDs for simpler client logic and better client caching.- I can implement the URLs to stay consistent if necessary.
- Fuse's Next.js plugin doesn't work with Turbopack due to a difference in Turbopack's module resolution compared to webpack/vite, so removed
--turbo
fromnext dev
for now
Local development
Everything about local development stays the same as before: next dev
. The only additional step is that when first opening this code in VSCode, you need to CMD+Shift+P, "TypeScript: Select TypeScript Version…" and select "Use Workspace Version" to enable GraphQLSP and get type auto-completion for GraphQL queries on the client:
One of the deep dependencies throws a strange webpack parsing error. This error does not impact any functionality however I haven't found a way to silence it either. We can dig further into this.
Todo
- [x] Move homepage to fetch data via the GraphQL layer
- [x] Implement pagination on the homepage
- [x] Move individual story page to fetch data via the GraphQL layer
- [ ] Implement mutations for actions