⚡ Bolt: Resolve sequential DB query waterfalls in entity GET routes#128
⚡ Bolt: Resolve sequential DB query waterfalls in entity GET routes#128aicoder2009 wants to merge 1 commit into
Conversation
Refactored `GET` API routes for entity relationships (project lists, list citations, and single citation) to use `Promise.all`. This allows the parent validation query (e.g., `getProject` or `getList`) and the child data query (e.g., `getProjectLists` or `getListCitations`) to run concurrently rather than sequentially, reducing latency. Also added a journal entry in `.jules/bolt.md` documenting this performance pattern. Co-authored-by: aicoder2009 <127642633+aicoder2009@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
There was a problem hiding this comment.
Pull request overview
This PR refactors three Next.js API GET routes to reduce latency by avoiding sequential “waterfall” DB access, using Promise.all to fetch parent entities (for validation/authorization) concurrently with their related child data.
Changes:
/api/projects/[id]/lists: fetch project + project lists concurrently./api/lists/[id]/citations: fetch list + list citations concurrently./api/lists/[id]/citations/[citationId]: fetch list + citation concurrently.- Adds a
.jules/bolt.mdlearning entry documenting the optimization pattern.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/app/api/projects/[id]/lists/route.ts | Concurrently loads project and its lists to reduce query waterfall latency. |
| src/app/api/lists/[id]/citations/route.ts | Concurrently loads list and its citations (introduces an auth-scoping concern). |
| src/app/api/lists/[id]/citations/[citationId]/route.ts | Concurrently loads list and a single citation (introduces an auth-scoping concern). |
| .jules/bolt.md | Documents the concurrency pattern; needs tighter guidance around auth-scoped child queries. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Verify the list exists and belongs to the user | ||
| const list = await getList(userId, listId); | ||
| // Fetch list details and list citations concurrently by utilizing the userId | ||
| const [list, citations] = await Promise.all([ | ||
| getList(userId, listId), | ||
| getListCitations(listId), | ||
| ]); |
| // Verify the list exists and belongs to the user | ||
| const list = await getList(userId, listId); | ||
| // Fetch list details and citation concurrently by utilizing the userId | ||
| const [list, citation] = await Promise.all([ | ||
| getList(userId, listId), | ||
| getCitation(listId, citationId), | ||
| ]); |
|
|
||
| ## 2024-05-23 - Concurrent Parent/Child Data Fetching in API Routes | ||
| **Learning:** In backend API routes (e.g. GET requests for entities), sequentially awaiting a parent validation query (like `getProject(userId, projectId)`) and then its child data query (`getProjectLists(userId, projectId)`) creates a database query waterfall that adds unnecessary latency. | ||
| **Action:** When the child query does not strictly depend on the result of the parent query (for example, when both rely on existing parameters like `userId` and `projectId`/`listId`), execute both queries concurrently using `Promise.all` and then perform the necessary validation checks (e.g. `if (!project) return 404`). |
💡 What: Refactored three GET API endpoints (
/api/projects/[id]/lists,/api/lists/[id]/citations, and/api/lists/[id]/citations/[citationId]) to usePromise.allfor concurrently fetching the parent entity (for authorization/validation) and the required child data.🎯 Why: Previously, these endpoints fetched the parent entity,
awaited the response, and then fetched the child entities using the same path parameters. This created a sequential database query waterfall that artificially delayed the API response time.📊 Impact: Expected to reduce the Time to First Byte (TTFB) on these API routes by approximately the time it takes to execute one database query (~50% latency reduction for the data-fetching portion of the request).
🔬 Measurement: This optimization can be verified by observing the network latency on the frontend when loading project or list detail pages, or by profiling the individual API routes before and after the change.
Also added a learning entry to
.jules/bolt.mddetailing this optimization pattern.PR created automatically by Jules for task 8277444277158071437 started by @aicoder2009