Skip to content

Commit b98e950

Browse files
authored
feat: add cache invalidation example app (#6731)
* feat: add cache invalidation example app * fix: add README.md * Update accelerate/accelerate-hacker-news/package.json
1 parent 28b4d9a commit b98e950

File tree

24 files changed

+580
-0
lines changed

24 files changed

+580
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
DIRECT_URL=
2+
DATABASE_URL=
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": ["next/core-web-vitals", "next/typescript"]
3+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
.yarn/install-state.gz
8+
9+
# testing
10+
/coverage
11+
12+
# next.js
13+
/.next/
14+
/out/
15+
16+
# production
17+
/build
18+
19+
# misc
20+
.DS_Store
21+
*.pem
22+
23+
# debug
24+
npm-debug.log*
25+
yarn-debug.log*
26+
yarn-error.log*
27+
28+
# local env files
29+
.env*.local
30+
31+
# vercel
32+
.vercel
33+
34+
# typescript
35+
*.tsbuildinfo
36+
next-env.d.ts
37+
38+
prisma/migrations
39+
package-lock.json
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Prisma Accelerate Hacker News Clone
2+
3+
This project showcases how to use Prisma ORM with Prisma Accelerate, leveraging caching and on-demand cache invalidation, in a Next.js application to build a minimal Hacker News clone.
4+
5+
This app retrieves and caches the [top 20 latest posts](/app/page.tsx#L8) with a long Time-to-Live ([TTL](https://www.prisma.io/docs/accelerate/caching#time-to-live-ttl)). The cache is invalidated on-demand whenever a post is [upvoted](/app/actions/addVotes.ts) or a [new post is added](/app/submit/actions/addPost.ts).
6+
7+
![GIF of interaction](demo.gif)
8+
9+
## Prerequisites
10+
11+
To successfully run the project, you will need the following:
12+
13+
- The **connection string** of a PostgreSQL database
14+
- Your **Accelerate connection string** (containing your **Accelerate API key**) which you can get by enabling Accelerate in a project in your [Prisma Data Platform](https://pris.ly/pdp) account (learn more in the [docs](https://www.prisma.io/docs/platform/concepts/environments#api-keys))
15+
16+
## Getting started
17+
18+
### 1. Clone the repository
19+
20+
Clone the repository, navigate into it and install dependencies:
21+
22+
```
23+
git clone git@github.com:prisma/prisma-examples.git --depth=1
24+
cd prisma-examples/accelerate/accelerate-hacker-news
25+
npm install
26+
```
27+
28+
### 2. Configure environment variables
29+
30+
Create a `.env` in the root of the project directory:
31+
32+
```bash
33+
cp .env.example .env
34+
```
35+
36+
Now, open the `.env` file and set the `DATABASE_URL` and `DIRECT_URL` environment variables with the values of your connection string and your Accelerate connection string:
37+
38+
```bash
39+
# .env
40+
41+
# Accelerate connection string (used for queries by Prisma Client)
42+
DATABASE_URL="__YOUR_ACCELERATE_CONNECTION_STRING__"
43+
44+
# Database connection string (used for migrations by Prisma Migrate)
45+
DIRECT_URL="__YOUR_DATABASE_CONNECTION_STRING__"
46+
```
47+
48+
Note that `__YOUR_DATABASE_CONNECTION_STRING__` and `__YOUR_ACCELERATE_CONNECTION_STRING__` are placeholder values that you need to replace with the values of your database and Accelerate connection strings. Notice that the Accelerate connection string has the following structure: `prisma://accelerate.prisma-data.net/?api_key=__YOUR_ACCELERATE_API_KEY__`.
49+
50+
### 3. Run a migration to create the `Post` table
51+
52+
The Prisma schema file contains a single `Post` model. You can map this model to the database and create the corresponding `Post` table using the following command:
53+
54+
```
55+
npx prisma migrate dev --name init
56+
```
57+
58+
### 4. Generate Prisma Client for Accelerate
59+
60+
When using Accelerate, Prisma Client doesn't need a query engine. That's why you should generate it as follows:
61+
62+
```
63+
npx prisma generate --no-engine
64+
```
65+
66+
### 5. Start the app
67+
68+
You can run the app with the following command:
69+
70+
```
71+
npm run dev
72+
```
73+
74+
You should now be able to:
75+
76+
- See the most recent post at http://localhost:3000 and upvote it by clicking the ▲ button.
77+
- Submit a new post by navigating to http://localhost:3000/submit.
78+
79+
When you make changes, it might take a few seconds to invalidate the cache and display the latest changes.
80+
81+
## Resources
82+
83+
- [Accelerate Speed Test](https://accelerate-speed-test.vercel.app/)
84+
- [Accelerate documentation](https://www.prisma.io/docs/accelerate)
85+
- [Prisma Discord](https://pris.ly/discord)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use server'
2+
3+
import prisma from '@/lib/db'
4+
5+
export async function addVotes(id: number) {
6+
// console.log({
7+
// updating: id,
8+
// })
9+
10+
await prisma.post.update({
11+
where: {
12+
id: id,
13+
},
14+
data: {
15+
vote: {
16+
increment: 1,
17+
},
18+
},
19+
})
20+
21+
await prisma.$accelerate.invalidate({
22+
tags: ['posts'],
23+
})
24+
25+
return id
26+
}
25.3 KB
Binary file not shown.
66.3 KB
Binary file not shown.
64.7 KB
Binary file not shown.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
4+
5+
:root {
6+
--background: #ffffff;
7+
--foreground: #171717;
8+
}
9+
10+
@media (prefers-color-scheme: dark) {
11+
:root {
12+
--background: #0a0a0a;
13+
--foreground: #ededed;
14+
}
15+
}
16+
17+
body {
18+
color: var(--foreground);
19+
background: var(--background);
20+
font-family: Arial, Helvetica, sans-serif;
21+
}
22+
23+
@layer utilities {
24+
.text-balance {
25+
text-wrap: balance;
26+
}
27+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import type { Metadata } from 'next'
2+
import localFont from 'next/font/local'
3+
import './globals.css'
4+
5+
const geistSans = localFont({
6+
src: './fonts/GeistVF.woff',
7+
variable: '--font-geist-sans',
8+
weight: '100 900',
9+
})
10+
const geistMono = localFont({
11+
src: './fonts/GeistMonoVF.woff',
12+
variable: '--font-geist-mono',
13+
weight: '100 900',
14+
})
15+
16+
export const metadata: Metadata = {
17+
title: 'Accelerate Hacker News Clone',
18+
description: 'A minimal hackernews clone using Prisma Accelerate',
19+
}
20+
21+
export default function RootLayout({
22+
children,
23+
}: Readonly<{
24+
children: React.ReactNode
25+
}>) {
26+
return (
27+
<html lang="en">
28+
<body
29+
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
30+
>
31+
<div className="pl-8 pr-8 md:pl-12 md:pr-12 bg-slate-100 h-screen overflow-scroll">
32+
<div className="h-full flex flex-col">{children}</div>
33+
</div>
34+
</body>
35+
</html>
36+
)
37+
}

0 commit comments

Comments
 (0)