first commit
This commit is contained in:
299
README.md
Normal file
299
README.md
Normal file
@@ -0,0 +1,299 @@
|
||||
# Axum + Tokio API Baslangici
|
||||
|
||||
Bu proje Rust ile yazilmis minimal bir Axum API iskeletidir.
|
||||
JWT access/refresh token ile temel account akisi da dahildir.
|
||||
|
||||
Detayli teknik dokumantasyon icin bkz. `docs/IMPLEMENTATION.md`.
|
||||
Admin panel baslangic dokumani icin bkz. `docs/ADMIN_PANEL_PLAN.md`.
|
||||
|
||||
## Ozellik Ozeti
|
||||
|
||||
- JWT access/refresh tabanli account sistemi
|
||||
- Swagger / OpenAPI dokumani
|
||||
- Multipart image upload
|
||||
- Query tabanli image process endpointi
|
||||
- Image listeleme ve variant stream endpointleri
|
||||
- SeaORM entity + migration yapisi
|
||||
- Local filesystem storage (`uploads/originals`, `uploads/variants`)
|
||||
- Ayrik admin panel iskeleti (`admin-panel/`)
|
||||
- Dinamik CORS (DB tabanli whitelist/blacklist + Redis cache/rate limit)
|
||||
|
||||
Not: CORS migration'lari calisirken `cors_origins` tablosuna bilinen frontend portlari
|
||||
(`localhost/127.0.0.1` icin `5173`, `4173`, `3001`) whitelist olarak seed edilir;
|
||||
ornek blacklist girdileri de eklenir.
|
||||
|
||||
## Proje Yapisi
|
||||
|
||||
- `src/main.rs` -> sadece uygulama bootstrap ve server baslatma
|
||||
- `src/app/mod.rs` -> genel route'lar (`/`, `/health`, `/db/ping`) ve router birlestirme
|
||||
- `src/auth/mod.rs` -> account endpointleri ve JWT/password islemleri
|
||||
- `src/images/` -> image controller/service/repository/dto/model/processor katmanlari
|
||||
- `src/entities/` -> SeaORM entity tanimlari
|
||||
- `src/migration/` -> auth ve image tablolarinin migration dosyalari
|
||||
- `src/state/mod.rs` -> `AppState`, auth state ve env tabanli init
|
||||
- `src/error/mod.rs` -> global JSON hata modeli ve `ApiError`
|
||||
- `src/telemetry/mod.rs` -> `tracing` kurulumu
|
||||
- `src/tests/mod.rs` -> endpoint testleri
|
||||
- `admin-panel/` -> React + TypeScript admin panel MVP
|
||||
|
||||
## Akis Ozetleri
|
||||
|
||||
### Auth
|
||||
|
||||
1. `register/login` ile token cifti uretilir
|
||||
2. `refresh` ile token rotasyonu yapilir
|
||||
3. `me` endpointi aktif kullaniciyi doner
|
||||
|
||||
### Image Upload
|
||||
|
||||
1. Bearer token dogrulanir
|
||||
2. Orijinal dosya `uploads/originals` altina yazilir
|
||||
3. Istenen format/dimension ile variant uretilir
|
||||
4. Variant dosya `uploads/variants` altina yazilir
|
||||
5. DB aktifse metadata `images` ve `image_variants` tablolarina kaydedilir
|
||||
6. `GET /api/v1/images` ile kayitlar listelenir
|
||||
7. `GET /api/v1/images/{id}/variant` ile son variant stream edilir
|
||||
|
||||
## Endpointler
|
||||
|
||||
- `GET /` -> Basit bilgilendirme mesaji
|
||||
- `GET /health` -> JSON health yaniti
|
||||
- `GET /db/ping` -> DB baglantisini `SELECT 1` ile test eder
|
||||
- `POST /api/v1/auth/register` -> Hesap olusturur ve token ciftini doner
|
||||
- `POST /api/v1/auth/login` -> Giris yapar ve token ciftini doner
|
||||
- `POST /api/v1/auth/refresh` -> Refresh token ile token rotasyonu yapar
|
||||
- `POST /api/v1/auth/logout` -> Verilen refresh token oturumunu sonlandirir
|
||||
- `GET /api/v1/auth/me` -> Access token ile aktif kullaniciyi doner
|
||||
- `GET /api/v1/images/process` -> Query ile image isleme parametrelerini dogrular (token gerekir)
|
||||
- `POST /api/v1/images/process` -> Multipart form-data ile image yukler ve parametreleri uygular
|
||||
- `GET /api/v1/images` -> Kayitli image metadata listesini doner (DB gerekir)
|
||||
- `GET /api/v1/images/{id}/variant` -> Image'in son variant dosyasi binary stream eder (DB gerekir)
|
||||
- `GET /api-docs/openapi.json` -> OpenAPI JSON dokumani
|
||||
- `GET /swagger-ui` -> Swagger UI
|
||||
|
||||
Ornek `/health` yaniti:
|
||||
|
||||
```json
|
||||
{"status":"ok"}
|
||||
```
|
||||
|
||||
Ornek hata formati:
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "NOT_FOUND",
|
||||
"message": "Istenen endpoint bulunamadi"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Calistirma
|
||||
|
||||
Ortam degiskenleri icin once ornek dosyayi kopyalayip degerleri doldurun:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Ardindan kendi gizli degerlerinizi `.env` dosyasina girin.
|
||||
|
||||
```bash
|
||||
cargo run
|
||||
```
|
||||
|
||||
Varsayilan adres:
|
||||
|
||||
- `http://0.0.0.0:3000`
|
||||
|
||||
## Docker ile Calistirma
|
||||
|
||||
Proje icin `Dockerfile`, `.dockerignore` ve `docker-compose.yml` dosyalari eklendi.
|
||||
Compose bu kurulumda sadece API'yi (ve opsiyonel admin paneli) ayaga kaldirir.
|
||||
PostgreSQL ve Redis disarida zaten calisiyor olmalidir.
|
||||
|
||||
1) Ornek Docker env dosyasini olusturun:
|
||||
|
||||
```bash
|
||||
cp .env.docker.example .env.docker
|
||||
```
|
||||
|
||||
2) Servisleri build edip baslatin:
|
||||
|
||||
```bash
|
||||
docker compose --env-file .env.docker up --build -d
|
||||
```
|
||||
|
||||
Frontend (admin panel) da acmak icin profile ile calistirin:
|
||||
|
||||
```bash
|
||||
docker compose --env-file .env.docker --profile frontend up --build -d
|
||||
```
|
||||
|
||||
3) Loglari izleyin:
|
||||
|
||||
```bash
|
||||
docker compose logs -f api
|
||||
```
|
||||
|
||||
4) Servisleri durdurun:
|
||||
|
||||
```bash
|
||||
docker compose down
|
||||
```
|
||||
|
||||
Sadece frontend profilini kapatmak isterseniz:
|
||||
|
||||
```bash
|
||||
docker compose stop admin-panel
|
||||
```
|
||||
|
||||
Kalici volume'ler:
|
||||
|
||||
- `uploads_data` -> `uploads/originals` ve `uploads/variants`
|
||||
|
||||
Docker icinde endpointler:
|
||||
|
||||
- API: `http://127.0.0.1:3000`
|
||||
- Admin panel (frontend profili acikken): `http://127.0.0.1:5173`
|
||||
- Swagger: `http://127.0.0.1:3000/swagger-ui`
|
||||
- OpenAPI JSON: `http://127.0.0.1:3000/api-docs/openapi.json`
|
||||
|
||||
Not: Reverse proxy yok; frontend tarayicidan API'ye dogrudan `VITE_API_BASE_URL`
|
||||
degeri ile erisir (varsayilan: `http://127.0.0.1:3000`).
|
||||
|
||||
Not: API container dis servislerle varsayilan olarak `host.docker.internal` uzerinden
|
||||
haberlesir. Gerekirse `.env.docker` icinde `DATABASE_URL` ve `REDIS_URL` degerlerini
|
||||
kendi ortamina gore guncelle.
|
||||
|
||||
Farkli port icin:
|
||||
|
||||
```bash
|
||||
PORT=8080 cargo run
|
||||
```
|
||||
|
||||
DB baglantisi ile calistirmak icin:
|
||||
|
||||
```bash
|
||||
DATABASE_URL="postgres://kullanici:sifre@localhost:5432/veritabani" cargo run
|
||||
```
|
||||
|
||||
Redis ile calistirmak icin:
|
||||
|
||||
```bash
|
||||
REDIS_URL="redis://127.0.0.1:6379" cargo run
|
||||
```
|
||||
|
||||
Request log seviyesini degistirmek icin:
|
||||
|
||||
```bash
|
||||
RUST_LOG=debug,tower_http=info cargo run
|
||||
```
|
||||
|
||||
JWT ayarlari (opsiyonel):
|
||||
|
||||
```bash
|
||||
JWT_SECRET="cok-gizli-anahtar"
|
||||
JWT_ISSUER="web-api"
|
||||
ADMIN_EMAILS="admin@example.com"
|
||||
ACCESS_TOKEN_TTL_SECS=900
|
||||
REFRESH_TOKEN_TTL_SECS=604800
|
||||
```
|
||||
|
||||
Swagger UI ac/kapa:
|
||||
|
||||
```bash
|
||||
ENABLE_SWAGGER_UI=true
|
||||
IMAGE_ACCESS_TOKEN=image-dev-token
|
||||
IMAGE_UPLOAD_DIR=uploads/originals
|
||||
IMAGE_VARIANT_DIR=uploads/variants
|
||||
CORS_DEFAULT_ALLOW=false
|
||||
CORS_ALLOW_LOCALHOST=true
|
||||
CORS_RATE_LIMIT_PER_MINUTE=120
|
||||
CORS_CACHE_TTL_SECS=300
|
||||
```
|
||||
|
||||
## Auth Ornekleri
|
||||
|
||||
Register:
|
||||
|
||||
```bash
|
||||
curl -s -X POST http://127.0.0.1:3000/api/v1/auth/register \
|
||||
-H 'content-type: application/json' \
|
||||
-d '{"email":"demo@example.com","password":"Sup3rSifre!"}'
|
||||
```
|
||||
|
||||
Login:
|
||||
|
||||
```bash
|
||||
curl -s -X POST http://127.0.0.1:3000/api/v1/auth/login \
|
||||
-H 'content-type: application/json' \
|
||||
-d '{"email":"demo@example.com","password":"Sup3rSifre!"}'
|
||||
```
|
||||
|
||||
Refresh:
|
||||
|
||||
```bash
|
||||
curl -s -X POST http://127.0.0.1:3000/api/v1/auth/refresh \
|
||||
-H 'content-type: application/json' \
|
||||
-d '{"refresh_token":"<REFRESH_TOKEN>"}'
|
||||
```
|
||||
|
||||
Me:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:3000/api/v1/auth/me \
|
||||
-H 'authorization: Bearer <ACCESS_TOKEN>'
|
||||
```
|
||||
|
||||
Image process:
|
||||
|
||||
```bash
|
||||
curl -s "http://127.0.0.1:3000/api/v1/images/process?w=800&format=webp&quality=80&crop=cover" \
|
||||
-H 'authorization: Bearer image-dev-token'
|
||||
```
|
||||
|
||||
Image upload (multipart):
|
||||
|
||||
```bash
|
||||
curl -s -X POST http://127.0.0.1:3000/api/v1/images/process \
|
||||
-H 'authorization: Bearer image-dev-token' \
|
||||
-F "file=@/tmp/demo.jpg" \
|
||||
-F "width=800" \
|
||||
-F "format=webp" \
|
||||
-F "quality=80" \
|
||||
-F "crop=cover"
|
||||
```
|
||||
|
||||
Image list:
|
||||
|
||||
```bash
|
||||
curl -s "http://127.0.0.1:3000/api/v1/images?page=1&limit=10&q=demo&format=webp" \
|
||||
-H 'authorization: Bearer <ACCESS_TOKEN>'
|
||||
```
|
||||
|
||||
Image variant stream:
|
||||
|
||||
```bash
|
||||
curl -L "http://127.0.0.1:3000/api/v1/images/<IMAGE_ID>/variant" \
|
||||
-H 'authorization: Bearer <ACCESS_TOKEN>' \
|
||||
-o variant-output.avif
|
||||
```
|
||||
|
||||
Not: Upload edilen orijinal dosya varsayilan olarak `uploads/originals`, islenmis format cikti dosyasi `uploads/variants` altina kaydedilir.
|
||||
DB baglantisi aktif ve token JWT access ise metadata `images` ve `image_variants` tablolarina yazilir.
|
||||
|
||||
## Test
|
||||
|
||||
```bash
|
||||
cargo test
|
||||
```
|
||||
|
||||
## Admin Panel Calistirma
|
||||
|
||||
```bash
|
||||
cd /home/beyhan/Projeler/Rust/Web/admin-panel
|
||||
cp .env.example .env
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
Reference in New Issue
Block a user