天野 CRUD REST API
今天,我们将用简单的示例创建一个Deno CRUD REST API。最近,我介绍了有关 VDOM (Vue, 天野, Oak, 和 MongodB) 堆栈应用程序。 天野是JavaScript和TypeScript的婴儿安全运行时。许多读者要求我写一篇文章,以使用Deno创建rest api。

通常,如果您熟悉Node.js,那么Deno就是这样。除了它’在很多方面都有所改善’从底部到顶部创建,以更好地实现Node.js。
为什么 I 采用 天野 over 节点? ?
由于Deno和Node.js具有相同的目的,因此’可以直接比较两者。
节点 | 天野 | |
---|---|---|
发动机 | V8 | V8 |
写在 | C ++& 的JavaScript | 锈& Typescript |
包裹管理 | 包管理器:npm | 使用网址 |
导入包装 | CommonJS语法 | ES模块 |
安全 | 完全访问 | 许可访问 |
TypeScript支持 | 没有内置 | 内置 |
好吧,酷!那么,如何在系统中安装Deno? ?
安装最新版本
带壳:
1 |
卷曲 -fsSL https://deno.land/x/install/install.sh | sh |
使用PowerShell:
1 |
iwr https://deno.land/x/install/install.ps1 -useb | iex |
有关更多详细信息,请检查 天野’的官方安装指南。
安装后使用以下命令检查Deno的版本 地–version

现在您可以运行 地repl 打开REPL(读取-执行-打印循环)并开始键入一些JavaScript。

让’s 跑 some 天野 example
入口点可以是 .js 文件, .ts 文件或什至指向应用程序入口点的URL,Deno将下载,编译并为您运行:
例如: 地run //deno.land/std/examples/welcome.ts
从操场出来并构建一个API?
就像在 我们之前的例子,我们’将使用Oak框架和Typescript(如果需要,也可以使用JavaScript)。
首先,创建三个文件 应用程序, 路由器 和 控制器
在里面 应用程序 文件,我们必须导入 应用 从 //deno.land/x/oak/mod.ts 和路由器从‘./router.ts‘.
然后设置端口和主机
1 2 3 4 5 6 7 8 |
进口 { 应用 } 从 '//deno.land/x/oak/mod.ts' 进口 路由器 从 './router.ts' const 环保 = 天野.环保.反对() const 主办 = 环保.主办 || '127.0.0.1' const 港口 = 环保.港口 || 7700 const 应用程式 = 新 应用() |
之后,添加router.ts的代码。在这个文件中,我们必须导入 路由器 从 //deno.land/x/oak/mod.ts 并创建路线。
1 2 3 4 5 6 7 8 9 10 11 |
进口 { 路由器 }从 '//deno.land/x/oak/mod.ts' 进口 { 得到Books, 得到Book, addBook, updateBook, 删除Book } 从 './controller.ts' const 路由器 = 新 路由器() 路由器.得到('/图书', 得到Books) .得到('/ 图书 /:isbn', 得到Book) .发布('/图书', addBook) .放('/ 图书 /:isbn', updateBook) .删除('/ 图书 /:isbn', 删除Book) 出口 默认 路由器 |
在上述代码的第2行,功能 得到Books, 得到Book, addBook, updateBook 和 删除Book 是从本地文件导入的’s just we haven’t created them yet.
在控制器中创建这些功能之前,让我先完成 应用程序 首先归档。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
进口 { 应用 } 从 '//deno.land/x/oak/mod.ts' 进口 路由器 从 './router.ts' const 环保 = 天野.环保.反对() const 主办 = 环保.主办 || '127.0.0.1' const 港口 = 环保.港口 || 7700 const 应用程式 = 新 应用() 应用程式.采用(路由器.路线()) 应用程式.采用(路由器.允许edMethods()) 安慰.日志(`倾听 上 港口 ${港口} ...`) 等待 应用程式.听(`${主办}:${港口}`) |
现在它’s time to create 控制器 在此文件中,让我们定义书籍的界面 我订了,然后声明一个book对象的初始数组:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
接口 我订了 { 伊斯本: 串; 作者: 串; 标题: 串; } 让 图书: 数组<我订了> = [{ 伊斯本: "1", 作者: “罗宾·维鲁克”, 标题: “反应之路”, },{ 伊斯本: "2", 作者: “凯尔辛普森”, 标题: “您不了解JS:范围& Closures", },{ 伊斯本: "3", 作者: “安德里亚斯·安东诺普洛斯”, 标题: “掌握比特币”, }] |
在哪里实现的功能 控制器?
现在我们’将实现我们在我们定义的功能 路由器.
功能 | 路线 | 描述 |
---|---|---|
得到Books | GET /书籍 | 归还所有书 |
得到Books | GET / 图书 / {isbn} | 还书 |
addBook | POST /书籍 | 加一本书 |
updateBook | 放置/ 图书 / {isbn} | 更新一本书 |
删除Book | 删除/ 图书 / {isbn} | 删除一本书 |
得到Books:返回列表中的所有书籍。
1 2 3 |
const 得到Books = ({ 响应 }: { 响应: 任何 }) => { 响应.身体 = 图书 } |
得到Book:按其isbn返回一本书,如果找不到则返回错误消息。
1 2 3 4 5 6 7 8 9 10 |
const 得到Book = ({ 参数, 响应 }: { 参数: { 伊斯本: 串 }; 响应: 任何 }) => { const 书: 我订了 | 未定义 = searchBookByIsbn(参数.伊斯本) 如果 (书) { 响应.状态 = 200 响应.身体 = 书 } 其他 { 响应.状态 = 404 响应.身体 = { 信息: `书 不 发现.` } } } |
addBook:将书籍添加到书籍清单。
1 2 3 4 5 6 7 |
const addBook = 异步的 ({ 请求, 响应 }: { 请求: 任何; 响应: 任何 }) => { const 身体 = 等待 请求.身体() const 书: 我订了 = 身体.值 图书.推(书) 响应.身体 = { 信息: '好' } 响应.状态 = 200 } |

updateBook:更新一本书(如果存在),否则返回错误消息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
const updateBook = 异步的 ({ 参数, 请求, 响应 }: { 参数: { 伊斯本: 串 }; 请求: 任何; 响应: 任何 }) => { 让 书: 我订了 | 未定义 = searchBookByIsbn(参数.伊斯本) 如果 (书) { const 身体 = 等待 请求.身体() const updateInfos: { 作者?: 串; 标题?: 串 } = 身体.值 书 = { ...书, ...updateInfos} 图书 = [...图书.过滤(书 => 书.伊斯本 !== 参数.伊斯本), 书] 响应.状态 = 200 响应.身体 = { 信息: '好' } } 其他 { 响应.状态 = 404 响应.身体 = { 信息: `书 不 发现` } } } |

删除Book:从书籍清单中删除书籍。
1 2 3 4 5 |
const 删除Book = ({ 参数, 响应 }: { 参数: { 伊斯本: 串 }; 响应: 任何 }) => { 图书 = 图书.过滤(书 => 书.伊斯本 !== 参数.伊斯本) 响应.身体 = { 信息: '好' } 响应.状态 = 200 } |

在这里,我们完成 控制器。完整的代码是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
接口 我订了 { 伊斯本: 串; 作者: 串; 标题: 串; } 让 图书: 数组<我订了> = [{ 伊斯本: "1", 作者: “罗宾·维鲁克”, 标题: “反应之路”, },{ 伊斯本: "2", 作者: “凯尔辛普森”, 标题: “您不了解JS:范围& Closures", },{ 伊斯本: "3", 作者: “安德里亚斯·安东诺普洛斯”, 标题: “掌握比特币”, }] const 得到Books = ({ 响应 }: { 响应: 任何 }) => { 响应.身体 = 图书 } const 得到Book = ({ 参数, 响应 }: { 参数: { 伊斯本: 串 }; 响应: 任何 }) => { const 书: 我订了 | 未定义 = searchBookByIsbn(参数.伊斯本) 如果 (书) { 响应.状态 = 200 响应.身体 = 书 } 其他 { 响应.状态 = 404 响应.身体 = { 信息: `书 不 发现.` } } } const addBook = 异步的 ({ 请求, 响应 }: { 请求: 任何; 响应: 任何 }) => { const 身体 = 等待 请求.身体() const 书: 我订了 = 身体.值 图书.推(书) 响应.身体 = { 信息: '好' } 响应.状态 = 200 } const updateBook = 异步的 ({ 参数, 请求, 响应 }: { 参数: { 伊斯本: 串 }; 请求: 任何; 响应: 任何 }) => { 让 书: 我订了 | 未定义 = searchBookByIsbn(参数.伊斯本) 如果 (书) { const 身体 = 等待 请求.身体() const updateInfos: { 作者?: 串; 标题?: 串 } = 身体.值 书 = { ...书, ...updateInfos} 图书 = [...图书.过滤(书 => 书.伊斯本 !== 参数.伊斯本), 书] 响应.状态 = 200 响应.身体 = { 信息: '好' } } 其他 { 响应.状态 = 404 响应.身体 = { 信息: `书 不 发现` } } } const 删除Book = ({ 参数, 响应 }: { 参数: { 伊斯本: 串 }; 响应: 任何 }) => { 图书 = 图书.过滤(书 => 书.伊斯本 !== 参数.伊斯本) 响应.身体 = { 信息: '好' } 响应.状态 = 200 } / *如果找到则返回书,如果没有则返回未定义* / const searchBookByIsbn = (伊斯本: 串): ( 我订了 | 未定义 ) => 图书.过滤(书 => 书.伊斯本 === 伊斯本 )[0] 出口 { 得到Books, 得到Book, addBook, updateBook, 删除Book } |
为什么 searchBookByIsbn 用于 控制器?
这是一个通过ISBN ID查找图书的辅助函数,我们在第26行调用此函数。
Run the 天野 code now
1 |
地跑 -允许-环保 -允许-净 应用程式.ts |
从GitHub下载源代码
如果您喜欢这篇文章,请放心与他人分享。

