Exercise 3: A Tags Endpoint With Counts — Possible Solution ============================================================= app.get("/tags", async (req, res) => { const unusedOnly = req.query.unused === "true"; const tags = await prisma.tag.findMany({ where: unusedOnly ? { posts: { none: {} } } : undefined, select: { name: true, _count: { select: { posts: { where: { published: true } } } }, }, orderBy: { name: "asc" }, }); res.json(tags.map((t) => ({ name: t.name, publishedPosts: t._count.posts }))); }); $ curl localhost:3000/tags [{"name":"api","publishedPosts":0},{"name":"orm","publishedPosts":4}, {"name":"prisma","publishedPosts":6}] $ curl "localhost:3000/tags?unused=true" [{"name":"api","publishedPosts":0}] Which technique, and why: - The count uses relation _count with a where filter. We're listing tag records anyway and want a number next to each one, which is exactly what relation _count is for. groupBy wouldn't fit well here: many-to- many links live in a hidden join table that groupBy can't group on. - "Unused" uses the none relation filter from Prisma Fundamentals, Chapter 9. It's a condition on which tags to return, not a number, so it belongs in where. Note the difference: a tag used only by drafts shows publishedPosts: 0 but does NOT appear in ?unused=true, because it still has posts. WHY THIS WORKS AS AN ANSWER ------------------------------ One query answers each request, the count and the filter each use the tool that matches the question being asked, and the final note shows that "zero published posts" and "no posts at all" are genuinely different conditions — the kind of edge case that causes real bugs.