Cloudflare SQL to API 開源工具,寫 SQL 就能發布 REST API

Cloudflare SQL to API 是開源的自架工具,寫好 SQL 查詢就能發布成 REST API 端點,跑在自己的 Cloudflare Workers 與 D1 上。它省下的後端樣板是真的,但管理後台沒有伺服器端驗證、預設還帶著公開的寫入端點,自架前要先補鎖。

用 AI 摘要這篇文章:

後端最重複的工作之一,是為了讓前端拿得到資料庫裡的東西,先寫一整層讀寫介面。Cloudflare SQL to API 這個開源專案給的答覆很直接:SQL 查詢本身就是介面定義,你寫好一段查詢,它就變成一個可以呼叫的 REST 端點,而且跑在你自己的 Cloudflare 帳號裡。我把整包原始碼抓下來逐檔讀完,也把 GitHub 上的問題清單翻過一輪,先講結論:它的核心機制是真的,授權是寬鬆的 MIT,額度面用免費方案就夠,當成內部工具或原型驗證的資料服務層很划算;但 README 那句「內建 SQL 注入防護」只兌現了一半,防護畫在參數綁定那條線上,線以外的整個管理後台沒有上鎖。要自架可以,鎖要自己補。

一張路由表加一個執行器,就是它的全部

拆開看,這個專案的概念薄到一頁就講完。資料庫裡有一張 api_routes 表,每一列就是一支 API:名稱、路徑、HTTP 方法、SQL 查詢、參數定義,以及是否公開。執行器收到請求時,拿路徑和方法去這張表做字串完全比對,找得到就執行那條 SQL,找不到回 404。沒有框架魔法,也沒有程式碼產生,你的 SQL 原封不動躺在資料庫裡等著被叫用。

參數的接法是冒號開頭的占位符。SQL 裡寫 WHERE id = :userId,參數定義表加上 userId、型別、是否必填,呼叫端把值放在查詢字串或請求內容裡送來,執行器把 :userId 換成問號,再交給資料庫的綁定機制附值,回應則是一個固定的 JSON 外框:成功與否、資料列陣列,以及總筆數和執行時間。以它內建的示範資料為例,有一條現成的單筆查詢路由,呼叫 GET /api/public/user?userId=1,回應就是該編號用戶的資料列,前後端之間不再需要一層手寫的轉接程式碼。整個定義流程在網頁介面上完成:SQL 欄位用的是 Monaco 編輯器,就是 VS Code 同款的核心,關鍵字有高亮、有行號,填完表單按建立,端點就存在了。

Cloudflare SQL to API 的建立 API 頁面,SQL 欄位使用 Monaco 編輯器,畫面中有 API 名稱、描述、路徑、HTTP 方法與預先填入 SELECT 查詢的 SQL 編輯區Pin
官方截圖:建立 API 頁面。SQL 欄位是 Monaco 編輯器,填完表單按建立,端點就存在(圖片來源:123xiao/Cloudflare-SQL-to-API repository)

API 管理頁把所有端點列成一張表,方法、路徑、是否公開一目了然,每列都有測試和日誌按鈕,可以不離開介面就打一輪請求看結果。它還有一份內建的使用文件頁,把 SQL 怎麼寫、參數怎麼定義、有哪些語法限制都寫在站內,不用回 GitHub 找 README。

Cloudflare SQL to API 的 API 管理頁面,表格列出每支 API 的名稱、路徑、HTTP 方法、操作類型與是否公開,右側有詳情、編輯、測試、日誌、刪除按鈕Pin
官方截圖:API 管理頁。每支端點的方法、路徑與公開狀態一目了然(圖片來源:123xiao/Cloudflare-SQL-to-API repository)

除了手寫 SQL,它還有一個表格設計器:在介面上把欄位名稱、型別、長度填一填,存檔後系統幫你產生整組增刪查改端點,列表那支還自帶分頁參數。官方文件寫明支援 SELECT、INSERT、UPDATE、DELETE,換句話說,寫入和刪除型的 API 都是它的正規公民,這個工具的定位從一開始就不只於查詢。這對原型開發的意義很實際:早上開一張新表,中午就能讓前端對著端點接畫面,資料模型怎麼改,SQL 重貼一次就好,介面不用動。

注入防護是真的,但它畫的位置比你想的窄

現在講值得每個自架者停下來看的部分。README 說「內建 SQL 注入防護」,這句話在程式碼裡的兌現方式是:呼叫端帶來的所有值都走綁定,不會被拼接進 SQL 文字。就這條線而言,防護是真的而且做得乾淨,占位符換成問號、值交給 D1 的預備陳述綁定,呼叫者沒有任何機會把 SQL 語法塞進你的查詢裡。

問題在於那條線的另外一邊。管理端那些介面背後的 API,包括列出所有路由、建立、更新、刪除、表管理、呼叫日誌,在伺服器端沒有做任何身分檢查;建立路由的處理器開頭還留著一行作者自己的註解,意思是這裡應該加上管理員認證,還沒做。整個後端裡,碰過 session 的只有登入、登出與工作階段驗證這幾個端點,其餘管理端點誰都能呼叫。你以為有登入頁就安全嗎?登入頁確實存在,前端路由的中介層會把沒登入的瀏覽器導去登入頁,但那只攔得住用瀏覽器走頁面的人,直接對管理 API 的位址發請求,不需要任何憑證。

還有兩個細節讓這道門開得更開。路由表裡有個 require_auth 欄位,預設是開的,看名字是「這支 API 需不需要認證」的開關,但執行器從頭到尾只讀 is_public,require_auth 沒有任何執行路徑會去檢查,等於裝飾品。登入頁的人機驗證靠 Cloudflare Turnstile,金鑰沒設的話,程式碼拿官方測試金鑰當預設值,而那組金鑰的設計用途就是永遠回傳通過。工作階段本身存在記憶體裡、識別碼用 Math.random 產生,註解卻寫著加密安全,登入成功的回應內容還會附上工作階段識別碼,程式碼註解自己也承認這在生產環境應該拿掉。

把這些加起來,這個工具的安全模型其實假設你的管理介面位址沒有人知道,或者你會自己在前面加一層防護。README 的安全注意事項裡確實寫了「建議在生產環境中加入適當的認證機制」,也寫了「公開 API 無需認證,請謹慎使用」,都算誠實,只是輕描淡寫到很容易漏讀。

照預設部署完,你的站台就帶著一組任何人都能寫入的端點

初始遷移檔不只是建表,它還塞了示範資料:users 和 products 兩張表、十條現成的 API。其中新增產品、更新產品、刪除產品三支寫入端點,全部標成公開。也就是說,照著文件部署完的那一刻,任何知道位址的人都可以對你的資料庫寫入和刪除,動的雖然是示範表,但那條通道是活的。想乾淨上線,先把這十條路由清掉或關掉,再談別的。

SQL 的防呆也值得看一眼再上線。它擋 DROP 和 ALTER 的方式,是把整條 SQL 轉成小寫之後找子字串,所以欄位名稱裡只要含有 drop 或 alter 這幾個字母,例如 dropped_at,整條查詢會被誤判成刪表而被拒絕;反過來,DELETE 不在黑名單上,官方文件也明講支援。這是防呆,真正的邊界還是那句話:你寫進路由表的 SQL,就是這支 API 的全部能力。

另外兩個行為會影響你怎麼用它。每次呼叫,執行器都會把來源 IP、完整請求內容、Cloudflare 回報的國家與城市寫進日誌表,管理介面的日誌頁可以按 API、狀態碼、IP、時間範圍篩選,上方還有總呼叫次數、平均回應時間、成功率的統計卡片。這對除錯很好用;換個角度想,你等於替每一個呼叫者記下了 IP,在有用戶來自多地區或有個資考量的場景,這是一份跟著來的義務。

Cloudflare SQL to API 的呼叫日誌頁面,上方有依 API、狀態碼、IP 位址、時間範圍的篩選器與統計卡片,表格列出每筆呼叫的來源 IP、狀態碼、執行時間與請求內容Pin
官方截圖:呼叫日誌頁。每一筆呼叫的來源 IP 與請求內容都被記錄下來(圖片來源:123xiao/Cloudflare-SQL-to-API repository)

出錯時的行為也順道記一筆:SQL 出錯的話,回給呼叫端的是資料庫的原始錯誤訊息,表名、欄位名都看得到。內部工具無所謂,對外開放就是把自己的結構攤給對方看。公開端點也沒有任何流量管制:整套程式碼裡找不到限流或金鑰額度的邏輯,一支 API 公開之後,用量天花板就是 Cloudflare 帳號本身的免費額度,Workers 的每日請求數與 D1 的每日讀寫量各有各的上限。還有表格設計器產生的單筆查詢端點,路徑是字面的 /api/表名/:id,而執行器又是字串完全比對,所以照 REST 的直覺打 /api/products/5 會得到 404,要照它產生的字面路徑送、把 id 當參數帶,這一點跟一般框架的路由習慣不同,容易踩。

部署的坑,GitHub issue 都替你踩過一輪

講部署。前置很單純:Node.js 18 以上、pnpm、一個 Cloudflare 帳號、Wrangler 命令列。流程是複製專案、裝依賴、建一個 D1 資料庫、把 wrangler 設定檔裡的 database_id 換成你自己的,檔案裡留的是作者自己的資料庫 ID,不改的話部署不會動,接著跑兩份遷移 SQL,再一行指令部署上去。想在部署前先看一眼,官方也提供本機預覽模式,用 Wrangler 在本機跑一份再推。這段步驟按 README 與設定檔寫成,我沒有實際部署一輪,已知的坑直接列在下面。全部走免費方案就跑得起來:Workers 免費版每天十萬次請求、單次 10ms 的 CPU 時間,對內部工具等級的用量綽綽有餘;D1 的用量同樣計在帳號的免費額度裡。這套工具本身沒有授權費、沒有訂閱,成本就是你自己的 Cloudflare 用量。

最先撞的坑幾乎人人都會中:部署完打開網站,登入時告訴你系統未正確配置管理員憑證。原因是管理員帳號密碼不吃設定檔,要用 wrangler secret 分別設定兩個環境變數,而 README 的安裝段落沒寫這一步,只藏在 wrangler 設定檔的註解裡。這件事在 GitHub 上留了兩筆紀錄,一筆是 2025 年 7 月的已解決 issue,答案就是補設那兩個 secret;另一筆是 2026 年 5 月還開著的提問,問的仍然是管理員帳號密碼在哪裡。

另一個要有心理準備的:介面只有簡體中文。標題列、表單、文件頁、官方截圖全部是簡中,沒有多語言切換。看得懂的人無妨,在意的人要知道這點,改是改得動,因為授權是 MIT,成本自己衡量。

專案的體質也先講清楚。它在 GitHub 上有 190 顆星、28 個 fork,MIT 授權附正式授權檔,商業使用沒有障礙;依賴清單乾淨,沒有分析或遙測套件,伺服器端唯一的對外請求是登入時把 Turnstile 權杖送去 Cloudflare 官方端點驗證(前端另從公共 CDN 載入 Monaco 編輯器)。但 main 分支的最後一次 commit 停在 2025 年 8 月,到今天一年多沒有動靜;官方示範站也打不開了,只會得到 Cloudflare 的 522 錯誤,意思是邊緣節點等不到後端回應,GitHub 上 2026 年 5 月就有人回報同樣狀況,那個 issue 開到現在沒人回。把這些條件擺在一起,我的建議是把「持續維護的產品」從期待裡拿掉,把它當一份 MIT 授權的參考實作:程式碼不大,技術棧單純,Nuxt 3 加 Element Plus 的前端、Cloudflare Workers 加 D1 的後端,要讀要改都在自己的能力範圍內。

拿它當內部工具,別直接當對外產品

回到判斷。適合的場景很明確:團隊內部工具、原型驗證、個人專案需要快速弄一層資料 API 給前端或自動化腳本叫用,而且你已經在 Cloudflare 生態裡。這些情境下,SQL 即介面直接省掉一整層樣板程式碼,Worker 和 D1 都在你的帳號裡,資料不落在別人家。TechMoon 介紹過的 SubsTracker 就是同類思路的自架工具,把訂閱管理搬上 Cloudflare Workers;想先補平台背景,可以看我們的 Cloudflare Workers 教學

不適合的場景也一樣明確:直接開放給整個網際網路、當正式產品的 API 層。不是因為它寫得差,而是它的安全模型停在「管理介面不被人找到」的假設上:管理 API 沒有伺服器端驗證、require_auth 不生效、預設還帶著公開寫入端點,這幾件事在對外場景都是硬傷。真要上,起碼先補三道鎖:把管理介面套上 Cloudflare Access 這類零信任閘道、清掉示範路由、確認管理端點的位址不會外流。更穩的做法是把它當參考讀完,照自己的需求長一份。

方向上它剛好和 SQLBot 相反:SQLBot 是讓不寫 SQL 的人用提問的方式查資料庫,這個工具是讓會寫 SQL 的人自己定義介面。兩者都是把資料庫的門檻往不同方向搬,你要哪個方向,取決於你的團隊裡 SQL 是常識還是稀缺技能。資料要放哪也是同一家族的問題,像 Meow 這類把資料收進 Cloudflare D1 的自架筆記工具,用的都是同一套 Cloudflare 底層。

最後給一句話收尾:這是一份機制簡單到一頁講完、邊界重要到不能不看的原始碼。拿去自架內部工具,它是快的;拿去對外營運,先補鎖。原始碼都在 GitHub 上,讀完再決定,不會花你太多時間。對學生專題、接案原型或團隊裡的小工具來說,它省下的時間看得到;對要扛流量的正式服務來說,把它當教材比當地基更合適。

Sliven 褚崇名
Sliven 褚崇名

每日分享科技新知、免費資源以及 WordPress、虛擬主機相關主題,任何問題歡迎在科技月球下方留言,或是發送 Email 至 [email protected] 與我聯繫。

文章: 1311

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


Share to...