๋ชจ๋ฐ์ผ ๊ฒ์ ๋ง๋ค๊ธฐ #1
๊ธฐํ ยท ๊ธฐ์ ์คํ ์ ์ ยท Expo + FastAPI + PostgreSQL ์ธํ
1 ์ ๋ชจ๋ฐ์ผ ๋ฒ์ ์ ์๋ก ๋ง๋ค์๋
์น๋ฒ์ Neon Runner๋ฅผ ๋ฐฐํฌํ๊ณ ๋์ ์น๊ตฌ๊ฐ ํธ๋ํฐ์ผ๋ก ์ด์ด๋ดค๋๋ ํ๋ฉด์ด ์๋ฆฌ๊ณ ํค๋ณด๋๊ฐ ์์ด์ ์กฐ์์ด ์ ๋๋ค. ์ฒ์๋ถํฐ ๋ชจ๋ฐ์ผ์ ๊ณ ๋ คํ์ง ์๊ณ ๋ง๋ค์์ผ๋ ๋น์ฐํ ๊ฒฐ๊ณผ์๋ค.
๊ทธ๋ฅ ์น๋ฒ์ ์ ์์ ํ๋ ๊ฒ๋ณด๋ค ์ฒ์๋ถํฐ ๋ชจ๋ฐ์ผ์ ๊ธฐ์ค์ผ๋ก ๋ค์ ๋ง๋๋ ๊ฒ ๋ซ๊ฒ ๋ค๊ณ ํ๋จํ๋ค. ์ด์ฐจํผ ์๋ก ๋ง๋ค ๊ฑฐ๋ฉด ๊ธฐ๋ฅ๋ ๋ ์ถ๊ฐํ๊ณ DB๋ ์ ๋๋ก ์ฐ๊ณ ์ถ์๋ค.
๋ชจ๋ฐ์ผ ๋ฒ์ ์ ์์ ํ ๋ณ๋ ํ๋ก์ ํธ๋ก ๋ง๋ค์๋ค. ์น๋ฒ์ (
neon-runner)์ ๊ทธ๋๋ก ๋๊ณ , ๋ชจ๋ฐ์ผ ๋ฒ์ ์ neon-runner-mobile๋ก ๋ฐ๋ก ๊ด๋ฆฌํ๋ค.
2 ๊ธฐ์ ์คํ ์ ์ ์ด์
3 ์น๋ฒ์ ๊ณผ ๋ฌ๋ผ์ง ์
| ํญ๋ชฉ | ์น๋ฒ์ | ๋ชจ๋ฐ์ผ๋ฒ์ |
|---|---|---|
| ํ๋ ์์ํฌ | React + Vite | React Native + Expo |
| ๋ ๋๋ง | Canvas API | React Native ์ปดํฌ๋ํธ |
| ์กฐ์ | ํค๋ณด๋ (SPACE, โ) | ํฐ์น (์ผ์ชฝ ํญ, ์ค๋ฅธ์ชฝ ํญ) |
| ๋ฐ์ดํฐ ์ ์ฅ | JSON ํ์ผ | PostgreSQL DB |
| ์ธ์ฆ | ๋๋ค์๋ง ์ ๋ ฅ | ํ์๊ฐ์ / ๋ก๊ทธ์ธ (JWT) |
| ์์ดํ | ์์ | ์ด๋ / ์ฌ๋ก์ฐ / ๋ฌด์ / ์ ์2๋ฐฐ |
| ์คํ ์ด์ง | ์์ | 4๊ฐ ํ ๋ง (30์ด๋ง๋ค ๋ณ๊ฒฝ) |
| ์ฝค๋ณด | ์์ | ์ฐ์ ํํผ ์ ์ ์ ๋ฐฐ์จ ์ฆ๊ฐ |
4 ๊ฒ์ ๊ธฐํ โ ์ถ๊ฐ๋ ๊ธฐ๋ฅ๋ค
ํํ ์ ํ๊ฒ์์ด๋ ์ฐจ๋ณํํ๋ ค๊ณ ์ฌ๋ฌ ์์๋ฅผ ์ถ๊ฐํ๋ค.
๐ ์คํ ์ด์ง ์์คํ
30์ด๋ง๋ค ๋ฐฐ๊ฒฝ ํ ๋ง๊ฐ ๋ฐ๋๋ค. ์ฌ์ด๋ฒ๋์ โ ์ฐ์ฃผ โ ์ฉ์์ง๋ โ ์ฌํด ์์๋ก. ์ฅ์ ๋ฌผ ์์ด๋ ๋ถ์๊ธฐ๋ ์คํ ์ด์ง๋ง๋ค ๋ฌ๋ผ์ ธ์ ์ง๋ฆฌ์ง ์๋๋ค.
โก ์์ดํ ์์คํ
๊ฒ์ ์ค์ ์์ดํ ์ด ๋งต์ ๋ฑ์ฅํ๊ณ , ๋จน์ผ๋ฉด ์ธ๋ฒคํ ๋ฆฌ์ ๋ณด๊ด๋๋ค. ์ํ ๋ ๊บผ๋ด ์ธ ์ ์๋ค.
| ์์ดํ | ํจ๊ณผ | ์ง์์๊ฐ |
|---|---|---|
| ๐ก๏ธ ์ด๋ | ํ ๋ฒ ๋ง์๋ ์ ์ฃฝ์ | 1ํ |
| ๐ ์ฌ๋ก์ฐ | ๊ฒ์ ์๋ ๋๋ ค์ง | 3์ด |
| ๐ ๋ฌด์ | ๋ชจ๋ ์ฅ์ ๋ฌผ ํต๊ณผ | 2์ด |
| ๐ ์ ์ 2๋ฐฐ | ํ๋ ์ ์ 2๋ฐฐ | 5์ด |
๐ฏ ์ฝค๋ณด ์์คํ
์ฅ์ ๋ฌผ์ ์ฐ์์ผ๋ก ํผํ ์๋ก ์ฝค๋ณด๊ฐ ์์ด๊ณ ์ ์ ๋ฐฐ์จ์ด ์ฌ๋ผ๊ฐ๋ค. ๋ง์ผ๋ฉด ์ฝค๋ณด ์ด๊ธฐํ.
๐ ์์ดํ ์ธ๋ฒคํ ๋ฆฌ
100์ ์ด์ ํ๋ํ๋ฉด ๊ฒ์์ค๋ฒ ํ ๋๋ค ์์ดํ 1๊ฐ ์ง๊ธ. ์ต๋ 3๊ฐ ๋ณด๊ด ๊ฐ๋ฅ. ๋ค์ ๊ฒ์์์ ์ํ ๋ ์ฌ์ฉ.
5 ํ๋ก์ ํธ ๊ตฌ์กฐ & Expo ์ธํ
โโโ frontend\ โ React Native (Expo)
โ โโโ App.js โ ๊ฒ์ ๋ฉ์ธ
โ โโโ app.json
โ โโโ package.json
โโโ backend\ โ Python FastAPI
โโโ venv\
โโโ main.py โ API ์๋ฒ
โโโ .env โ DB ์ฃผ์, ๋น๋ฐํค
โโโ .gitignore
Expo ํ๋ก์ ํธ ์์ฑ ๋ช ๋ น์ด:
# Expo ์ค์น npm install -g expo-cli # ๋น ํ๋ก์ ํธ ์์ฑ npx create-expo-app frontend --template blank # ๊ฐ๋ฐ ์๋ฒ ์คํ cd frontend npx expo start
React Native ์ฑ์ ๋ง๋ค ๋ Xcode, Android Studio ๊ฐ์ ๋ฌด๊ฑฐ์ด ๋๊ตฌ ์ค์น ์์ด ๋ฐ๋ก ์์ํ ์ ์๊ฒ ํด์ฃผ๋ ๋๊ตฌ๋ค. ํฐ์ Expo Go ์ฑ ์ค์นํ๊ณ QR์ฝ๋ ์ค์บํ๋ฉด ์ค๊ธฐ๊ธฐ์์ ๋ฐ๋ก ํ ์คํธ ๊ฐ๋ฅํ๋ค. ์ฝ๋ ์์ ํ๋ฉด ์ค์๊ฐ์ผ๋ก ํฐ์ ๋ฐ์๋๋ค.
HTML ํ๊ทธ ๋์ React Native ์ ์ฉ ์ปดํฌ๋ํธ๋ฅผ ์ด๋ค.
<div> โ <View><p> โ <Text>CSS โ
StyleSheet.create()ํด๋ฆญ โ
onPressJavaScript/React ๋ฌธ๋ฒ์ ์์ ํ ๋์ผํ๋ค.
6 FastAPI + PostgreSQL ๋ฐฑ์๋ ์ธํ
์น๋ฒ์ ๊ณผ ๋ค๋ฅด๊ฒ ์ด๋ฒ์ PostgreSQL DB๋ฅผ ์ฐ๊ธฐ ๋๋ฌธ์ ํ์ํ ํจํค์ง๊ฐ ๋ ๋ง๋ค.
# ๊ฐ์ํ๊ฒฝ ์์ฑ ๋ฐ ํ์ฑํ cd D:\Lee_project\neon-runner-mobile\backend python -m venv venv venv\Scripts\activate # ํ์ํ ํจํค์ง ์ค์น pip install fastapi uvicorn sqlalchemy psycopg2-binary python-jose passlib python-multipart python-dotenv
์ค์นํ ํจํค์ง๋ค ์ญํ :
| ํจํค์ง | ์ญํ |
|---|---|
| fastapi | API ์๋ฒ ํ๋ ์์ํฌ |
| uvicorn | ์๋ฒ ์คํ |
| sqlalchemy | Python์ผ๋ก DB ์ฟผ๋ฆฌ ์์ฑ (ORM) |
| psycopg2-binary | PostgreSQL ๋๋ผ์ด๋ฒ |
| python-jose | JWT ํ ํฐ ์์ฑ/๊ฒ์ฆ |
| passlib | ๋น๋ฐ๋ฒํธ ์ํธํ (bcrypt) |
| python-multipart | ๋ก๊ทธ์ธ ํผ ๋ฐ์ดํฐ ์ฒ๋ฆฌ |
| python-dotenv | .env ํ์ผ์์ ํ๊ฒฝ๋ณ์ ์ฝ๊ธฐ |
Object Relational Mapping. SQL ์ฟผ๋ฆฌ๋ฅผ ์ง์ ์ฐ๋ ๋์ Python ์ฝ๋๋ก DB๋ฅผ ์กฐ์ํ ์ ์๊ฒ ํด์ฃผ๋ ๋๊ตฌ๋ค.
SELECT * FROM users ๋์ db.query(User).all() ๊ฐ์ด ์ธ ์ ์๋ค. SQLAlchemy๊ฐ ๋ํ์ ์ธ Python ORM์ด๋ค.
JSON Web Token. ๋ก๊ทธ์ธํ๋ฉด ์๋ฒ๊ฐ ํ ํฐ์ ๋ฐ๊ธํด์ค๋ค. ์ดํ ์์ฒญํ ๋ ์ด ํ ํฐ์ ๊ฐ์ด ๋ณด๋ด๋ฉด ์๋ฒ๊ฐ ๋๊ฐ ๋ณด๋ธ ์์ฒญ์ธ์ง ์ ์ ์๋ค. ์ธ์ ์ฒ๋ผ ์๋ฒ์ ์ ์ฅํ ํ์ ์์ด ํ ํฐ ์์ฒด์ ์ ๋ณด๊ฐ ๋ด๊ฒจ์์ด์ ๊ฐ๋ณ๋ค.
7 Supabase DB ์ฐ๊ฒฐ
PostgreSQL ์๋ฒ๋ฅผ ์ง์ ์ค์นํ๋ ๊ฑด ๋ณต์กํ๋ค. Supabase๋ฅผ ์ฐ๋ฉด ๋ฌด๋ฃ๋ก ํด๋ผ์ฐ๋ PostgreSQL DB๋ฅผ ๋ง๋ค ์ ์๋ค.
supabase.com์์ ํ๋ก์ ํธ ๋ง๋ค๊ณ โ Connect โ Direct ํญ์์ ์ฐ๊ฒฐ ๋ฌธ์์ด์ ๋ฐ์๋ค. ๋น๋ฐ๋ฒํธ์ ํน์๋ฌธ์๊ฐ ์์ผ๋ฉด URL ์ธ์ฝ๋ฉ์ด ํ์ํ๋ค. @๋ %40, !๋ %21๋ก ๋ฐ๊ฟ์ผ ํ๋ค.
DATABASE_URL=postgresql://postgres.ํ๋ก์ ํธID:๋น๋ฐ๋ฒํธ@aws-1-ap-northeast-1.pooler.supabase.com:5432/postgres SECRET_KEY=neon-runner-secret-key-2026
venv/ .env __pycache__/ *.pyc
DB ์ฃผ์์ ๋น๋ฐํค๊ฐ ๋ค์ด์๊ธฐ ๋๋ฌธ์ด๋ค. .gitignore์ ๋ฐ๋์ ์ถ๊ฐํด์ผ ํ๋ค. ์ค์๋ก ์ฌ๋ ธ๋ค๋ฉด ๋ฐ๋ก Supabase์์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํด์ผ ํ๋ค.
8 API ๊ตฌ์กฐ ์์ฑ
์น๋ฒ์ ์ API๊ฐ 2๊ฐ(์ ์ ์ ์ฅ, ๋ฆฌ๋๋ณด๋)๋ฟ์ด์๋๋ฐ ์ด๋ฒ์ ํจ์ฌ ๋ง์์ก๋ค.
| ๋ฉ์๋ | ๊ฒฝ๋ก | ์ญํ | ์ธ์ฆ |
|---|---|---|---|
| POST | /register | ํ์๊ฐ์ | ๋ถํ์ |
| POST | /login | ๋ก๊ทธ์ธ โ JWT ๋ฐ๊ธ | ๋ถํ์ |
| GET | /me | ๋ด ์ ๋ณด ์กฐํ | ํ์ ๐ |
| POST | /score | ์ ์ ์ ์ฅ + ์์ดํ ์ง๊ธ | ํ์ ๐ |
| GET | /leaderboard | ์์ 20๊ฐ ์ ์ ์กฐํ | ๋ถํ์ |
| GET | /items | ๋ด ์์ดํ ์กฐํ | ํ์ ๐ |
| POST | /items/use | ์์ดํ ์ฌ์ฉ | ํ์ ๐ |
DB ํ ์ด๋ธ ๊ตฌ์กฐ๋ ์ด๋ ๊ฒ ์ค๊ณํ๋ค.
# users ํ ์ด๋ธ class User(Base): id = Column(Integer, primary_key=True) username = Column(String, unique=True) hashed_password = Column(String) # bcrypt ์ํธํ skin = Column(String, default="default") total_score = Column(Integer, default=0) # scores ํ ์ด๋ธ class Score(Base): id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey("users.id")) username = Column(String) score = Column(Integer) time = Column(Float) stage = Column(Integer) # items ํ ์ด๋ธ class Item(Base): id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey("users.id")) item_type = Column(String) # shield / slow / invincible / double_score quantity = Column(Integer, default=1)
Python ํด๋์ค๋ก ์ ์ํ ํ ์ด๋ธ์ ์ค์ DB์ ์๋์ผ๋ก ์์ฑํด์ค๋ค. ์๋ฒ๊ฐ ์ฒ์ ์ผ์ง ๋ ํ ๋ฒ ์คํ๋๊ณ , ํ ์ด๋ธ์ด ์ด๋ฏธ ์์ผ๋ฉด ๊ฑด๋๋ด๋ค. SQL๋ก ์ง์
CREATE TABLE์ ์ธ ํ์๊ฐ ์๋ค.
- ์๋ฃ ํ๋ก์ ํธ ๊ธฐํ ๋ฐ ๊ธฐ์ ์คํ ์ ์
- ์๋ฃ Expo React Native ํ๋ก์ ํธ ์์ฑ
- ์๋ฃ Python FastAPI + PostgreSQL ํจํค์ง ์ค์น
- ์๋ฃ Supabase DB ์์ฑ ๋ฐ ์ฐ๊ฒฐ
- ์๋ฃ .env + .gitignore ์ค์
- ์๋ฃ API 7๊ฐ + DB ํ ์ด๋ธ 3๊ฐ ์์ฑ
- ์๋ฃ FastAPI /docs ์์ API ๋์ ํ์ธ
- ๋ค์ํธ ๊ฒ์ ํ๋ฉด UI ๋ง๋ค๊ธฐ (React Native)
- ๋ค์ํธ ํ์๊ฐ์ /๋ก๊ทธ์ธ ํ๋ฉด
์น๋ฒ์ ๋ง๋ค ๋๋ณด๋ค ์ค์ ํ ๊ฒ ํจ์ฌ ๋ง์๋ค.
๊ทผ๋ฐ DB๋ JWT ์ธ์ฆ๊น์ง ๋ถ์ด๊ณ ๋๋๊น ์ง์ง ์๋น์ค์ฒ๋ผ ๋๊ปด์ง๋ค.
'Python' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| React + FastAPI๋ก ์น ๊ฒ์ ๋ง๋ค๊ธฐ #4 - Render + Vercel ๋ฐฐํฌ (0) | 2026.04.24 |
|---|---|
| React + FastAPI๋ก ์น ๊ฒ์ ๋ง๋ค๊ธฐ #3 - ์์ฑ (0) | 2026.04.23 |
| React + Python FastAPI๋ก์น ๊ฒ์ ๋ง๋ค๊ธฐ #2 (0) | 2026.04.23 |
| React + Python FastAPI๋ก์น ๊ฒ์ ๋ง๋ค๊ธฐ #1 (1) | 2026.04.22 |
| ๐ค๏ธ๋ ์จ ๋ฐ์ดํฐ(2) - ์ ์ฅํ๊ณ API ์๋ฒ๊น์ง ๋ง๋ค๊ธฐ (0) | 2026.03.25 |