Note
Four APIs as follow:
POST /api/v1/data/shorten:- with body
{longUrl: longURLString} - return: shortURL
- with body
GET /api/v1/shortUrl:- return status 302
- return longUrl for redirect
GET /shortUrl: redirect toGET /api/v1/shortUrlGET /: UI
-
POST /api/v1/data/shorten:- when longURL comes in, check if usl
not exists indatabase- if not exists in => use snowflake ID to generate Index and insert => return shortURL
- if might exist => search longURL
- if exist url => return shortURl
- not exist => insert
- when longURL comes in, check if usl
-
GET /api/v1/shortUrl:- Plan 1: use bloom filter to check wether url exist in database first
- Plan 2: use catch
- Plan 3: do nothing
Each api should:
- check http method
- check status
- check input
Middleware should:
- log input
- recovery
cd ./cmd/migrate
go build -o migrate.out
./migrate.out -path="../../migrations"graph TD
User((使用者)) --> LB[Load Balancer]
LB --> Server[Web Servers]
subgraph "Write Path(產生短網址)"
Server --> Blacklist{1. 黑名單檢查<br/>Redis/Local Cache}
Blacklist -- 命中黑名單 --> Refuse[回傳 403 Forbidden]
Blacklist -- 安全 --> KeyGen[2. 產生短網址 Key]
KeyGen --> WriteDB[(3. 寫入 Database)]
WriteDB --> UpdateBF[4. 更新 Bloom Filter]
UpdateBF --> UpdateCache[5. 寫入 Cache]
end
subgraph "Read Path (還原網址)"
Server --> BF_Check{A. Bloom Filter<br/>檢查是否存在?}
BF_Check -- 絕對不存在 --> 404[直接回傳 404]
BF_Check -- 可能存在 --> CacheCheck{B. Cache 查詢<br/>Redis}
CacheCheck -- Hit --> Redirect[回傳 302/301 導向]
CacheCheck -- Miss --> DB_Query[(C. Database 查詢)]
DB_Query -- 存在 --> SyncCache[更新 Cache]
SyncCache --> Redirect
DB_Query -- 不存在 --> 404_Real[回傳 404]
end
%% 零件定義
subgraph "資料層"
Redis[(Redis<br/>Cache + BloomFilter)]
DB[(PostgreSQL/MySQL)]
end
%% 連接資料層
UpdateCache -.-> Redis
CacheCheck -.-> Redis
WriteDB -.-> DB
DB_Query -.-> DB
UpdateBF -.-> Redis
- enter
make up-debugin consule - use vscode dbug and launch
Connect to Docker Debug
