用 Deno 編寫一個簡單的 REST API
用 Deno 編寫一個簡單的 REST API
過去一年,Deno?和?Svelte?獲得了 2020 年的年度突破獎, Deno 作為明日之星的項目,目前生態還不是很完善,和一言不合就造輪子的大佬相比,作為代碼搬磚界的小丑 -- Copy攻城獅便只能簡單記錄下自己的學習歷程,今天想分享的是如何使用 Deno 編寫一個簡單的 REST API。
目標
熟悉 Deno 的安裝
熟悉 Deno 指令
熟悉 Deno 簡單開發
安裝及配置
具體的安裝及配置可參考官方文檔:?deno.land, 社區的安裝教程可以說是非常豐富了,這里推薦 justjavac 的鏡像站點:x.deno.js.cn。如需通過官網安裝,可將地址替換為https://deno.land/x/install/:
# 安裝最新版 ## 使用 Shell: curl -fsSL https://x.deno.js.cn/install.sh | sh ## 使用 PowerShell: iwr https://x.deno.js.cn/install.ps1 -useb | iex # 安裝某個特定版本 ## 使用 Shell: curl -fsSL https://x.deno.js.cn/install.sh | sh -s v1.0.0 ## 使用 PowerShell: $v="1.0.0"; iwr https://x.deno.js.cn/install.ps1 -useb | iex # 驗證安裝 deno --version
如我獲得的輸出為:
deno 1.6.3 (release, x86_64-unknown-linux-gnu) v8 8.8.294 typescript 4.1.3
deno help
help?真的是個神奇的指令,介紹了很多關鍵的信息,在 Linux 中,help指令是Shell內建指令,用于顯示 shell 內部指令的幫助信息。Deno 中也實現了 help 指令,我們在終端輸入deno help?或者deno --help,亦或是更簡單的deno -h,我們便能獲得大量的信息幫助我們熟悉和使用 Deno,包括簡介、文檔地址、使用方法等等:
root:~/deno# deno help deno 1.6.3 A secure JavaScript and TypeScript runtime Docs: https://deno.land/manual Modules: https://deno.land/std/ https://deno.land/x/ Bugs: https://github.com/denoland/deno/issues To start the REPL: deno To execute a script: deno run https://deno.land/std/examples/welcome.ts To evaluate code in the shell: deno eval "console.log(30933 + 404)" USAGE: deno [OPTIONS] [SUBCOMMAND] OPTIONS: -h, --help 打印幫助信息 -L, --log-level
更詳細的指令請參考 @hylerrix?的?從 CLI 指令通讀 Deno v1.x 全特性,我個人比較感興趣的是?lsp, 歡迎一起探討!
JUST DO IT
讀書破萬卷不如行千里路,馬上開始我們的探索 Deno 之路。先來一個最簡單的目錄:
. ├── mod.ts // 入口文件 ├── caseItem.ts // 接口 ├── controller.ts // 控制器 ├── db.ts // mock 數據 └── routes.ts // 路由
先不管都要填充些啥代碼,我們動手把坑挖好,里面就跳!
mkdir deno-simple-api cd deno-simple-api touch mod.ts touch caseItem.ts touch controller.ts touch db.ts touch routes.ts
在?mod.ts?中我們使用?oak?開啟一個服務:
import { Application, Router } from "https://deno.land/x/oak/mod.ts"; const app = new Application(); const router = new Router(); const port: number = 8080; router.get("/", ({ response }: { response: any }) => { response.body = { message: "Hallo Deno!", }; }); app.use(router.routes()); app.addEventListener("listen", ({ secure, hostname, port }) => { const protocol = secure ? "https://" : "http://"; const url = `${protocol}${hostname ?? "localhost"}:${port}`; console.info( `Listening on ${url}` ); }); await app.listen({ port });
執行deno run --allow-net mod.ts?然后再訪問http://localhost:8080?便能看到網頁顯示{"message":"Hallo Deno!"}。
其中
import { Application, Router } from "https://deno.land/x/oak/mod.ts";
這行代碼 Deno 通過URL導入模塊,首先會檢查本地是否已經存在該模塊。如果沒有,則轉至url?https://deno.land/x/oak/mod.ts,然后下載該依賴包并將其緩存以備將來使用。這是由于 Deno 將下載的模塊存儲在緩存中,并在下次運行時使用此緩存,這不僅速度更快,而且在離線時也可以使用該模塊。
此時,當我們不帶參數執行deno run mod.ts,Deno 會提示我們沒有權限:
Download https://deno.land/x/oak/mod.ts Warning Implicitly using latest version (v6.4.1) for https://deno.land/x/oak/mod.ts Check file:///Users/gpdi/Documents/huqi/deno/deno-simple-api/mod.ts error: Uncaught PermissionDenied: network access to "0.0.0.0:8080", run again with the --allow-net flag at processResponse (deno:core/core.js:223:11) at Object.jsonOpSync (deno:core/core.js:246:12) at opListen (deno:runtime/js/30_net.js:28:17) at Object.listen (deno:runtime/js/30_net.js:191:17) at Application.serve (server.ts:301:25) at Application.listen (application.ts:362:20) at mod.ts:22:11
這是Deno的安全功能之一:默認情況下,對主機系統重要組件(例如網絡)的訪問受到限制,您必須授予Deno顯式權限。可能的標志選擇如下:
-A,--allow -all 允許所有權限。這將禁用所有安全性。 --allow-env 允許環境訪問,例如獲取和設置環境變量。 --allow-hrtime 允許高分辨率時間測量。高分辨率時間可用于定時攻擊和指紋識別。 --allow-net=<網址白名單> 允許網絡訪問。您可以指定一個可選的,用逗號分隔的域列表,以提供允許域的允許列表。 --allow-plugin 允許加載插件。請注意這是一個不穩定的功能。 --allow-read=<文件白名單> 允許文件系統讀取訪問。您可以指定目錄或文件的可選逗號分隔列表,以提供允許的文件系統訪問的允許列表。 --allow-run 允許運行子進程。請注意,子流程未在沙箱中運行,因此沒有與 deno 流程相同的安全限制。慎用! --allow-write=<文件白名單> 允許文件系統寫訪問。您可以指定目錄或文件的可選逗號分隔列表,以提供允許的文件系統訪問的允許列表
接著我們建立模型?,在?caseItem.ts中寫入:
export default interface CaseItem { id: string; user_name: string; company: string; description: string | null; };
此處建立的是偽用戶模型,包含用戶IDid、用戶名user_name、公司company、描述description這四個字段。
再然后我們模擬下一數據,假裝來自數據庫,新建?db.ts
import CaseItem from "./caseItem.ts";
const db: Array = [{
id: "940837680722589",
user_name: "稀土君",
company: "稀土",
description: "挖掘最優質的互聯網技術 https://juejin.cn ,經常搞活動搞抽獎,快關注快關注",
}, {
id: "2330620350708823",
username: "sh晨曦時夢見兮",
company: "",
description: "",
}, {
id: "2955079655898093",
username: "大帥全能老猿",
company: "花果山",
description: "Stay Hungry, Stay Foolish.",
}];
export default db;
接著我們創建控制器實現 CURD ,新建controller.ts:
最后創建路由并注冊:
route.ts
import { Router } from 'https://deno.land/x/oak/mod.ts'; import { getUserItems, addUserItem, getUserItem, updateUserItem, deleteUserItem } from './controller.ts'; const router = new Router(); router .get('/users', getUserItems) .post('/users', addUserItem) .get('/users/:id', getUserItem) .put('/users/:id', updateUserItem) .delete('/users/:id', deleteUserItem); export default router;
mod.ts
import?{?Application,?Router?}?from?"https://deno.land/x/oak/mod.ts";
import?router?from?'./routes.ts';
const?app?=?new?Application();
const?port:?number?=?8080;
app.use(router.routes());
app.use(router.allowedMethods());
app.addEventListener("listen",?({?secure,?hostname,?port?})?=>?{
const?protocol?=?secure???"https://"?:?"http://";
const?url?=?`${protocol}${hostname????"localhost"}:${port}`;
console.info(
`Listening?on?${url}`
);
});
await?app.listen({?port?});
import?{?Application,?Router?}?from?"https://deno.land/x/oak/mod.ts";
import?router?from?'./routes.ts';
const?app?=?new?Application();
const?port:?number?=?8080;
app.use(router.routes());
app.use(router.allowedMethods());
app.addEventListener("listen",?({?secure,?hostname,?port?})?=>?{
const?protocol?=?secure???"https://"?:?"http://";
const?url?=?`${protocol}${hostname????"localhost"}:${port}`;
console.info(
`Listening?on?${url}`
);
});
await?app.listen({?port?});
接下來我們使用 REST Client 來調試上面創建的 CURD 接口。
使用?REST Client
這并不是 Deno 的相關知識,只是為了我們更方便地調試 API,REST Client允許您發送HTTP請求并直接在Visual Studio Code中查看響應。在 Visual Studio Code 中安裝 REST Client 拓展此處就不表了,安裝和使用都很便捷。使用時只需新建.http或者.rest為后綴的文件,編寫請求格式的代碼即可,如下圖中,只需在api.http中寫入GET http://localhost:8080,點擊Send Request即可發起一次請求:
接著我們編寫上面實現的 CRUD 接口調試腳本,?api.http:
首先查看下db.ts?中的所有用戶:
接著新增一條用戶信息,返回"message": "OK",再查看一下所有用戶,發現我被加入到了用戶列表中:
在然后更新一下我的 slogan,Copy Code, Copy World!,再查看一下,更新成功!:
最后再測試一下刪除接口,我被徹底“干掉”了,用戶列表又恢復了往日的平靜,大佬們依舊談笑風生,而我,似乎從來沒有來過:
小結
源碼地址:?https://github.com/hu-qi/deno-simple-api
一直糾結要不要寫這么水的文章,猶豫過,徘徊過,懷疑過,最終寫戰勝了不寫。謹以此文悼念逝去的歲月,愿暮年他日還能所有回憶!
歡迎各位大佬多多指教!
JavaScript web前端
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。