improve deno example#8400
Conversation
WalkthroughThis PR migrates the Deno Deploy example from custom database connection patterns to a standardized PrismaPg adapter setup, replaces the Quotes data model with a Task model, introduces a REST API for task CRUD operations, and updates supporting configurations and documentation accordingly. Changes
Sequence DiagramsequenceDiagram
participant Client as HTTP Client
participant Server as Deno Server<br/>(main.ts)
participant Prisma as PrismaClient
participant PG as PostgreSQL<br/>Database
Note over Server: Initialize PrismaPg Adapter<br/>& PrismaClient on startup
Client->>Server: GET /tasks
Server->>Prisma: findMany(orderBy: createdAt)
Prisma->>PG: Query tasks
PG-->>Prisma: Task records
Prisma-->>Server: Task[]
Server-->>Client: 200 + JSON tasks
Client->>Server: POST /tasks<br/>{title, description}
Server->>Prisma: create({data})
Prisma->>PG: Insert task
PG-->>Prisma: New task record
Prisma-->>Server: Task
Server-->>Client: 201 + JSON created task
Client->>Server: GET /tasks/:id
Server->>Prisma: findUnique(id)
Prisma->>PG: Query by id
alt Task exists
PG-->>Prisma: Task record
Prisma-->>Server: Task
Server-->>Client: 200 + JSON task
else Task not found
PG-->>Prisma: null
Prisma-->>Server: null
Server-->>Client: 404 + error
end
Client->>Server: PATCH /tasks/:id<br/>{completed, ...}
Server->>Prisma: update(id, {data})
Prisma->>PG: Update task
PG-->>Prisma: Updated task
Prisma-->>Server: Task
Server-->>Client: 200 + JSON updated task
Client->>Server: DELETE /tasks/:id
Server->>Prisma: delete(id)
Prisma->>PG: Delete task
PG-->>Prisma: Deleted task
Prisma-->>Server: Task
Server-->>Client: 200 + success
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Pre-merge checks❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (6)
generator-prisma-client/deno-deploy/.gitignore (1)
1-4: Consider committingdeno.lockfor reproducible builds.Ignoring
deno.lockmay lead to inconsistent dependency resolution across environments. For production deployments, committing the lock file ensures reproducible builds. However, if this is intentional for an example project to always use latest compatible versions, this is acceptable.generator-prisma-client/deno-deploy/prisma/seed.ts (1)
53-65: Addprisma.$disconnect()to properly close the database connection.The Prisma client connection is never explicitly closed. While the process exits afterward, it's best practice to disconnect properly to ensure all pending queries are flushed and connections are released cleanly.
🔎 Proposed fix
const tasks = await prisma.task.findMany(); console.log(`Created ${tasks.length} tasks`); + + await prisma.$disconnect(); }; main() .then(() => { console.log("Process completed"); Deno.exit(0); }) .catch((e) => { console.error(e); + prisma.$disconnect(); Deno.exit(1); });Note: For the catch block, you'd need to either move
prismato module scope or restructure to ensure cleanup. A cleaner approach:-main() - .then(() => { - console.log("Process completed"); - Deno.exit(0); - }) - .catch((e) => { - console.error(e); - Deno.exit(1); - }); +main() + .catch((e) => { + console.error(e); + Deno.exit(1); + });And handle disconnect inside
main()with afinallyblock.generator-prisma-client/deno-deploy/src/main.ts (3)
32-42: Consider validating required fields on task creation.The
titlefield is required in the schema but there's no validation before callingprisma.task.create. Missingtitlewill result in a Prisma error surfaced as a generic 500.🔎 Proposed fix
// POST /tasks - Create a new task if (method === "POST" && path === "/tasks") { const body = await request.json(); + if (!body.title || typeof body.title !== "string") { + return json({ error: "title is required" }, 400); + } const task = await prisma.task.create({ data: { title: body.title, description: body.description, }, }); return json(task, 201); }
55-63: PATCH endpoint accepts arbitrary fields without validation.Passing
bodydirectly toprisma.task.updateallows clients to set any field. Consider explicitly picking allowed fields to prevent unintended modifications (e.g.,createdAt).🔎 Proposed fix
// PATCH /tasks/:id - Update a task if (method === "PATCH") { const body = await request.json(); + const { title, description, completed } = body; const task = await prisma.task.update({ where: { id }, - data: body, + data: { + ...(title !== undefined && { title }), + ...(description !== undefined && { description }), + ...(completed !== undefined && { completed }), + }, }); return json(task); }
65-69: DELETE returns 500 if task doesn't exist.
prisma.task.deletethrowsP2025(Record not found) if the task doesn't exist, which gets caught and returns a generic 500. Consider checking existence first or handling the specific error.🔎 Proposed fix
// DELETE /tasks/:id - Delete a task if (method === "DELETE") { - await prisma.task.delete({ where: { id } }); - return json({ message: "Task deleted" }); + const task = await prisma.task.findUnique({ where: { id } }); + if (!task) return json({ error: "Task not found" }, 404); + await prisma.task.delete({ where: { id } }); + return json({ message: "Task deleted" }); }Alternatively, use
deleteManywhich doesn't throw on missing records:const { count } = await prisma.task.deleteMany({ where: { id } }); if (count === 0) return json({ error: "Task not found" }, 404); return json({ message: "Task deleted" });generator-prisma-client/deno-deploy/README.md (1)
27-30: Clarify the two install commands.The two separate
deno installcommands might confuse users. Consider adding a brief note explaining why both are needed, or consolidate if possible.```bash -deno install -deno install --allow-scripts +# Install dependencies +deno install --allow-scriptsOr if both are truly needed: ```diff ```bash +# Initial install deno install +# Run postinstall scripts (needed for Prisma) deno install --allow-scripts</blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used**: Path: .coderabbit.yaml **Review profile**: CHILL **Plan**: Pro <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 8cd7783ea968d20aeb258ef1330541d05ddc349e and c954078a895d8383d90949be319ad1ba2c9b6a5a. </details> <details> <summary>📒 Files selected for processing (11)</summary> * `generator-prisma-client/deno-deploy/.env.example` * `generator-prisma-client/deno-deploy/.gitignore` * `generator-prisma-client/deno-deploy/README.md` * `generator-prisma-client/deno-deploy/deno.json` * `generator-prisma-client/deno-deploy/deno.jsonc` * `generator-prisma-client/deno-deploy/prisma.config.ts` * `generator-prisma-client/deno-deploy/prisma/schema.prisma` * `generator-prisma-client/deno-deploy/prisma/seed.ts` * `generator-prisma-client/deno-deploy/src/db.ts` * `generator-prisma-client/deno-deploy/src/main.ts` * `generator-prisma-client/deno-deploy/src/prisma-enums.ts` </details> <details> <summary>💤 Files with no reviewable changes (3)</summary> * generator-prisma-client/deno-deploy/src/db.ts * generator-prisma-client/deno-deploy/src/prisma-enums.ts * generator-prisma-client/deno-deploy/deno.jsonc </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>🧬 Code graph analysis (2)</summary> <details> <summary>generator-prisma-client/deno-deploy/prisma/seed.ts (1)</summary><blockquote> <details> <summary>orm/prisma-mocking-javascript/client.js (1)</summary> * `adapter` (4-4) </details> </blockquote></details> <details> <summary>generator-prisma-client/deno-deploy/src/main.ts (2)</summary><blockquote> <details> <summary>orm/prisma-mocking-javascript/client.js (1)</summary> * `adapter` (4-4) </details> <details> <summary>.github/scripts/get-packages.js (1)</summary> * `path` (2-2) </details> </blockquote></details> </details><details> <summary>🪛 dotenv-linter (4.0.0)</summary> <details> <summary>generator-prisma-client/deno-deploy/.env.example</summary> [warning] 1-1: [QuoteCharacter] The value has quote characters (', ") (QuoteCharacter) </details> </details> </details> <details> <summary>⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)</summary> * GitHub Check: test (orm/clerk-nextjs) * GitHub Check: test (orm/betterauth-astro) * GitHub Check: test (orm/authjs-nextjs) * GitHub Check: test (orm/ai-sdk-nextjs) * GitHub Check: test (orm/betterauth-nextjs) * GitHub Check: test (orm/cloudflare-workers) * GitHub Check: test (orm/astro) * GitHub Check: test (orm/grpc) * GitHub Check: test (orm/clerk-astro) * GitHub Check: test (orm/hapi-graphql) * GitHub Check: test (orm/nest-graphql) * GitHub Check: test (orm/nest-graphql-sdl-first) * GitHub Check: test (orm/nest) * GitHub Check: test (orm/sveltekit) * GitHub Check: test (orm/nextjs-trpc) * GitHub Check: test (orm/nuxt) * GitHub Check: test (orm/solid-start) </details> <details> <summary>🔇 Additional comments (7)</summary><blockquote> <details> <summary>generator-prisma-client/deno-deploy/.env.example (1)</summary><blockquote> `1-1`: **LGTM!** The connection string format is correct for PostgreSQL. The dotenv-linter warning about quotes is a false positive for example files—quotes are appropriate here to demonstrate the expected format. </blockquote></details> <details> <summary>generator-prisma-client/deno-deploy/deno.json (2)</summary><blockquote> `12-18`: **LGTM!** The task definitions are well-structured with appropriate flags for Deno. Using `--env=.env` for environment variable loading and `--watch` for development is idiomatic. --- `7-11`: The Prisma 7.x versions specified are valid and available. Prisma 7.0.0 was released on November 19, 2025, with the latest stable version being 7.1.0 (December 3, 2025). The `^7.0.0` constraints for `@prisma/adapter-pg`, `@prisma/client`, and `prisma` are all published and available on npm. </blockquote></details> <details> <summary>generator-prisma-client/deno-deploy/prisma.config.ts (1)</summary><blockquote> `1-12`: **LGTM!** The configuration correctly uses `defineConfig` with appropriate paths. Note that `process.env["DATABASE_URL"]` may be `undefined`, but Prisma handles this gracefully by throwing a clear error during client operations. </blockquote></details> <details> <summary>generator-prisma-client/deno-deploy/src/main.ts (1)</summary><blockquote> `94-95`: **LGTM!** Using `Deno.serve` with an explicit port is appropriate for local development and Deno Deploy compatibility. </blockquote></details> <details> <summary>generator-prisma-client/deno-deploy/prisma/schema.prisma (1)</summary><blockquote> `1-18`: **LGTM!** The schema is well-structured with appropriate field types and defaults. The `Task` model correctly uses `@updatedAt` for automatic timestamp updates, and the output path aligns with the import paths in `seed.ts` and `main.ts`. </blockquote></details> <details> <summary>generator-prisma-client/deno-deploy/README.md (1)</summary><blockquote> `85-119`: **LGTM!** The API endpoints table accurately reflects the implementation, and the deployment instructions are clear and comprehensive with both UI-based and CLI options. </blockquote></details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
| // Initialize Prisma Client with the Postgres adapter | ||
| const connectionString = Deno.env.get("DATABASE_URL")!; | ||
| const adapter = new PrismaPg({ connectionString }); | ||
| const prisma = new PrismaClient({ adapter }); |
There was a problem hiding this comment.
Add validation for missing DATABASE_URL instead of using non-null assertion.
The non-null assertion (!) on line 5 will cause an unclear runtime error if DATABASE_URL is not set. Unlike in seed.ts, there's no validation here.
🔎 Proposed fix
// Initialize Prisma Client with the Postgres adapter
-const connectionString = Deno.env.get("DATABASE_URL")!;
+const connectionString = Deno.env.get("DATABASE_URL");
+if (!connectionString) {
+ throw new Error("DATABASE_URL environment variable is not set");
+}
const adapter = new PrismaPg({ connectionString });
const prisma = new PrismaClient({ adapter });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Initialize Prisma Client with the Postgres adapter | |
| const connectionString = Deno.env.get("DATABASE_URL")!; | |
| const adapter = new PrismaPg({ connectionString }); | |
| const prisma = new PrismaClient({ adapter }); | |
| // Initialize Prisma Client with the Postgres adapter | |
| const connectionString = Deno.env.get("DATABASE_URL"); | |
| if (!connectionString) { | |
| throw new Error("DATABASE_URL environment variable is not set"); | |
| } | |
| const adapter = new PrismaPg({ connectionString }); | |
| const prisma = new PrismaClient({ adapter }); |
🤖 Prompt for AI Agents
In generator-prisma-client/deno-deploy/src/main.ts around lines 4 to 7, remove
the non-null assertion on Deno.env.get("DATABASE_URL") and add an explicit
validation: read the env var into a const, check if it's undefined or empty, and
if so throw a clear Error (or log and Deno.exit(1)) with a descriptive message
about the missing DATABASE_URL; only then construct the PrismaPg adapter with
the validated connection string and pass it into PrismaClient.
Summary by CodeRabbit
Release Notes
Documentation
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.