๐๐ป SNS Server๋ฅผ ๋ง๋ค์ด ๋ด
๋๋ค.
Let’s build an SNS server.
๐๐ป ์น์ฌ์ดํธ ํ๋ฉด ์ด์ ์ CRUD API๋ถ๋ถ์ ๋จผ์ ๊ตฌํํด ๋ด
๋๋ค.
We will implement the CRUD API first, before working on the website interface.
๐ ์ ์ฒด ํ๋ก์ ํธ ๊ตฌ์กฐ / Project Structure
myapp11/ (Root Directory)
โโโ ๐ app/ # Next.js App Router
โ โโโ ๐ api/
โ โ โโโ ๐ posts/
โ โ โโโ ๐ route.ts # CRUD API
โ โโโ ๐ layout.tsx
โ โโโ ๐ page.tsx # Main Home
โ โโโ ๐ globals.css
โโโ ๐ lib/
โ โโโ ๐ db.ts # SQLite dbconnection(data.sqlite)
โโโ ๐ data.sqlite # Local SQLite Database
โโโ ๐ Caddyfile # Caddy file
๐ Nextjs ํ๋ก์ ํธ ์์ / Starting a Next.js project(myapp11)
npx create-next-app@latest
๐ SQLite์ค์น / Installing SQLite
cd ~/myapp11
npm install better-sqlite3
npm install -D @types/better-sqlite3
๐ API์ฝ๋ ์์ฑ
Writing API code
โ๏ธ myapp11/app/api/posts/route.ts
// ~/myapp11/app/api/posts/route.ts
import db from '@/lib/db';
import { randomUUID } from 'crypto';
export async function GET() {
// R - ์ฝ๊ธฐ / Read
const posts = db.prepare('SELECT * FROM posts ORDER BY created_at DESC').all();
return Response.json(posts);
}
export async function POST(req: Request) {
// C - ์์ฑ / Create
const { content } = await req.json();
if (!content) return Response.json({ error: '๋ด์ฉ ์์ / Content is required' }, { status: 400 });
const id = randomUUID();
db.prepare('INSERT INTO posts (id, content) VALUES (?, ?)').run(id, content);
const post = db.prepare('SELECT * FROM posts WHERE id = ?').get(id);
return Response.json(post);
}
export async function PUT(req: Request) {
// U - ์์ / Update
const { id, content } = await req.json();
if (!id || !content) {
return Response.json({ error: 'id์ content ํ์ / id and content are required' }, { status: 400 });
}
const result = db.prepare('UPDATE posts SET content = ? WHERE id = ?').run(content, id);
if (result.changes === 0) {
return Response.json({ error: 'ํด๋น ๊ธ ์์ / Post not found' }, { status: 404 });
}
const post = db.prepare('SELECT * FROM posts WHERE id = ?').get(id);
return Response.json(post);
}
export async function DELETE(req: Request) {
// D - ์ญ์ / Delete
const { searchParams } = new URL(req.url);
const id = searchParams.get('id');
if (!id) return Response.json({ error: 'id ํ์ / You need id' }, { status: 400 });
db.prepare('DELETE FROM posts WHERE id = ?').run(id);
return Response.json({ ok: true });
}
โ๏ธ myapp11/db/db.ts
// ~/myapp11/lib/db.ts
import Database from 'better-sqlite3';
import path from 'path';
import fs from 'fs';
const dir = path.join(process.cwd());
const dbPath = path.join(dir, 'data.sqlite');
const db = new Database(dbPath);
// ํ
์ด๋ธ ์์ฑ / Create table if it doesn't exist
db.exec(`
CREATE TABLE IF NOT EXISTS posts (
id TEXT PRIMARY KEY,
content TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
`);
export default db;
๐ Nextjs ์๋ฒ์คํ / Running the Next.js server
npm run dev
๐ ๋ค๋ฅธ ํฐ๋ฏธ๋์์ ๊ธ์ ์ฅ ๋ฐ ๋ชฉ๋ก ๋ณด๊ธฐ
Save posts and view lists from another terminal
โ๏ธ ํฐ๋ฏธ๋์์ ์คํํฉ๋๋ค.()
Run it in the terminal.
# ๊ธ ์ฐ๊ธฐ / Write a Post
curl -X POST http://localhost:3000/api/posts -H "Content-Type: application/json" -d '{"content":"์ฒซ ๊ธ! sqlite์ ์ ์ฅ๋จ"}'
# ๊ธ ๋ชฉ๋ก ๋ณด๊ธฐ / View list of posts
curl http://localhost:3000/api/posts
# ๊ธ ์์ ํ๊ธฐ / Edit Post
curl -X PUT http://localhost:3000/api/posts -H "Content-Type: application/json" -d '{"id":"a1b2c3d4-...","content":"์์ ๋ ๋ด์ฉ/Revised content!"}'
# ๊ธ ์ญ์ / Delete post
curl -X DELETE "http://localhost:3000/api/posts?id=a1b2c3d4-..."
1)๊ธ์ฐ๊ธฐ๋ฅผ ๋ธ๋ผ์ฐ์ ์์ ํ๋ ค๋ฉด page.tsx์ ๊ธ ์ ์กํ๋ ์ฝ๋๋ฅผ ๋ณ๋๋ก ๋ง๋ค์ด์ผํฉ๋๋ค.
To write posts directly in the browser, you need to create separate code in page.tsx to submit the content.
โ๏ธ ๋ธ๋ผ์ฐ์ ์์ ๊ธ ๋ชฉ๋ก ๋ณด๊ธฐ
View the list of posts in the browser

์ํ๋ณต์ 8์ฅ 32์ / John 8:32
“๊ทธ๋ฆฌ๊ณ ๋ํฌ๋ ์ง๋ฆฌ๋ฅผ ์๊ฒ ๋ ๊ฒ์ด๋ฉฐ, ์ง๋ฆฌ๊ฐ ๋ํฌ๋ฅผ ์์ ๋กญ๊ฒ ํ ๊ฒ์ด๋ค.”
“Then you will know the truth ,and the truth will set you free”