Under varje inlÀgg i anteckningsboken finns nu fyra knappar: gilla, ogilla, Àlska och applÄdera. Klicka och rÀknaren gÄr upp. Klicka igen och den gÄr ner. Gilla och ogilla utesluter varandra, som man kan vÀnta sig.
Knapparna Àr det minst intressanta. Det intressanta Àr vad som inte behövdes för att bygga dem: ingen server, ingen databas att drifta, inget nytt konto att hÄlla reda pÄ. Backend Àr en fil, och databasen kom frÄn en meny.
Varför inte lÀgga rÀknarna i Sanity?
Första tanken var förstĂ„s att spara rĂ€knarna dĂ€r inlĂ€ggen redan ligger. Det finns tvĂ„ skĂ€l att lĂ„ta bli. Det första: webblĂ€saren lĂ€ser Sanity anonymt i dag, och skrivning krĂ€ver en token. En token i en bundle Ă€r en token alla har, och dĂ„ kan vem som helst Ă€ndra vad som helst â inte bara bumpa en siffra. Det andra Ă€r subtilare: en rĂ€knare som ligger pĂ„ inlĂ€gget krockar med utkast. Har nĂ„gon ett utkast öppet i Studio medan lĂ€sarna klickar, skriver publiceringen över rĂ€knaren med utkastets gamla vĂ€rde.
RÀknare Àr inte innehÄll. De ska bo nÄgon annanstans.
En Redis frÄn menyn
Vercel Marketplace har Upstash Redis som integration. Man vĂ€ljer den, vĂ€ljer region (vi tog EU) och kopplar den till projektet. Det Ă€r hela provisioneringen. Miljövariablerna â KV_REST_API_URL och KV_REST_API_TOKEN â dyker upp i projektet av sig sjĂ€lva, i alla miljöer.
GratisnivĂ„n rĂ€cker till 500 000 kommandon i mĂ„naden. En reaktion kostar fyra: rĂ€kna upp, uppdatera topplistan, lĂ€sa tillbaka och ett för spĂ€rren mot missbruk. Varje sidvisning av ett inlĂ€gg kostar ett. Med 20 000 sidvisningar och 10 000 reaktioner i mĂ„naden landar vi pĂ„ 60 000 â drygt en tiondel av gratisnivĂ„n. Om den hĂ€r bloggen nĂ„gonsin fĂ„r det problemet skriver vi gĂ€rna ett inlĂ€gg om det.
Klienten pratar REST, inte ett öppet socket. Det Àr poÀngen i serverless: en funktion som startar kallt ska inte sitta och hÄlla anslutningar, och Upstash Àr byggt för precis det.
Hela backenden Àr en fil
Filen ligger i katalogen api/ bredvid frontendkoden. Vercel ser katalogen och gör en funktion av varje fil i den. SÄ hÀr ser kÀrnan ut, med valideringen bortklippt:
api/react.js
import { Redis } from '@upstash/redis';
import { Ratelimit } from '@upstash/ratelimit';
const redis = new Redis({ url: process.env.KV_REST_API_URL, token: process.env.KV_REST_API_TOKEN });
const limiter = new Ratelimit({ redis, limiter: Ratelimit.slidingWindow(20, '10 m') });
export async function POST(request) {
const { slug, kind, delta = 1 } = await request.json();
const ip = request.headers.get('x-forwarded-for') ?? 'unknown';
if (!(await limiter.limit(ip)).success) {
return Response.json({ error: 'slow down' }, { status: 429 });
}
const key = `reactions:${slug}`;
await redis.hincrby(key, kind, delta); // atomĂ€rt â inga tappade klickTre saker gör den vĂ€rd att visa. HINCRBY Ă€r atomĂ€rt: tvĂ„ personer som klickar samtidigt ger tvĂ„, inte ett. Det sorterade settet reactions:top hĂ„ller totalen per inlĂ€gg, sĂ„ att sorteringen âPopulĂ€rastâ pĂ„ bloggen kan börja betyda nĂ„got pĂ„ riktigt â fram till nu har den sorterat pĂ„ lĂ€stid, för det var den enda siffran som fanns. Och @upstash/ratelimit ger ett glidande fönster pĂ„ 20 reaktioner per IP-adress och tio minuter, pĂ„ en rad. Mer Ă€n en Ă€rlig lĂ€sare nĂ„gonsin behöver, för lite för att ett skript ska kunna göra ett inlĂ€gg populĂ€rt pĂ„ en eftermiddag.
Saknas miljövariablerna svarar funktionen 503, och sidan döljer knapparna. Det gjorde att koden gick att deploya innan databasen fanns â och att sidan överlever om integrationen nĂ„gon gĂ„ng tas bort.
Vad som inte sparas
RĂ€knarna Ă€r anonyma summor. NĂ€r du klickar skickas inlĂ€ggets adress, reaktionstypen och â som i alla HTTP-anrop â din IP-adress. IP-adressen anvĂ€nds enbart i spĂ€rren mot missbruk och lever i tio minuter dĂ€r; den sparas aldrig tillsammans med rĂ€knaren. Vad du sjĂ€lv har reagerat pĂ„ ligger i din egen webblĂ€sare, i localStorage, sĂ„ att knappen visas som vald och gĂ„r att ta tillbaka. Vi vet inte vem som klickat. Allt det stĂ„r i cookies-policyn och integritetspolicyn, som uppdaterades samma dag som knapparna kom.
GÄr det att lura?
Ja. Den som vill kan rensa sin webblĂ€sare eller byta IP-adress och klicka igen. SpĂ€rren gör det trĂ„kigt, inte omöjligt. SĂ„ Ă€r det med alla rĂ€knare utan inloggning, och alternativet â att krĂ€va ett konto för att fĂ„ applĂ„dera â Ă€r en sĂ€mre blogg. Vi tar hellre en siffra som kan vara lite fel Ă€n en funktion ingen anvĂ€nder.
VÄrt korta svar
RĂ€knare Ă€r inte innehĂ„ll â lĂ€gg dem inte i CMS:et. En Redis frĂ„n Vercel Marketplace, en funktion pĂ„ en fil och HINCRBY rĂ€cker: gratis upp till 500 000 kommandon i mĂ„naden, atomĂ€rt, utan en server att drifta. Spara summor, inte mĂ€nniskor.
Knapparna finns hÀr nedanför. De Àr kopplade.
