Deno REST API简单的 Deno REST API
在首次发布两年后,Deno v1.0 终于来了。
那么,Deno到底是什么呢?
Deno 是一个简洁、现代且安全的 JavaScript 和 TypeScript 运行时环境,它使用 V8 引擎,并用 Rust 语言编写。Deno官方网站
Node.js(流行的服务器端 JavaScript 运行时)的创始人 Ryan Dahl 在 2018 年 JSConf EU 大会上发表了题为“我对 Node.js 的十件遗憾”的演讲,正式发布了 Deno (从标题就能看出我们接下来要讨论的内容)。换句话说,如果你熟悉 Node.js,那么 Deno 就和它很像。只不过 Deno 在很多方面都进行了改进,它是从底层重新构建的,旨在成为 Node.js 的一个更优秀的实现。
与 Node.js 的简单比较
由于 Deno 和 Node.js 的用途相同,因此可以直接比较两者。
| 节点 | 迪诺 | |
|---|---|---|
| 引擎 | V8 | V8 |
| 用……写 | C++ 和 JavaScript | Rust 和 Typescript |
| 包裹管理 | 包管理器:npm | 使用URL |
| 进口包裹 | CommonJS 语法 | ES模块 |
| 安全 | 完全访问权限 | 授权访问 |
| TypeScript 支持 | 未内置 | 内置 |
Deno教程
我们来和迪诺玩一会儿吧。
迪诺的装置
要安装 Deno,只需将此命令行复制并粘贴到终端中即可。
curl -fsSL https://deno.land/x/install/install.sh | sh
更多详情请查看Deno官方安装指南。
完成后,您将可以使用该deno命令。
您可以运行命令deno --help获取 Deno 提供的选项和子命令列表,也可以运行deno <subcommand> --help命令获取特定子命令的更多信息,例如:deno run --help
现在你可以运行deno或deno repl打开 REPL(读取-执行-打印循环),然后开始编写一些 Javascript 代码。
$ deno repl
Deno 1.0.0
exit using ctrl+d or close()
> console.log("Hello World !")
Hello World !
截至2020年5月14日(具体时间取决于您阅读本文的时间),REPL仅支持Javascript:
有很多方法可以改进 REPL,而无需引入 TypeScript 编译器。我们应该首先改进这些方面(例如改进检查功能和 Tab 键自动补全)。一旦 REPL 的功能达到 Node.js REPL 的水平,我们就可以开始研究如何使用 TypeScript 来进一步提升 REPL 的性能。Ryan Dahl 对 REPL 中 TypeScript 支持的评论
运行 Deno 应用
使用deno run <entry-point>命令启动 Deno 应用。
入口点可以是.js文件、.ts文件,甚至是指向应用程序入口点的 URL,Deno 会自动下载、编译并运行它:
例如:deno run https://deno.land/std/examples/welcome.ts
$ deno run https://deno.land/std/examples/welcome.ts
Download https://deno.land/std/examples/welcome.ts
Compile https://deno.land/std/examples/welcome.ts
Welcome to Deno 🦕
如果再次运行该程序,它将直接编译,无需再次下载,现在已被 Deno 缓存:
$ deno run https://deno.land/std/examples/welcome.ts
Compile https://deno.land/std/examples/welcome.ts
Welcome to Deno 🦕
--reload你可以使用标志强制重新加载原始源代码。
deno run --reload https://deno.land/std/examples/welcome.ts
如果您使用浏览器打开https://deno.land/std/examples/welcome.ts URL,您将看到包含代码及其文档的页面。
Deno 网站的示例页面提供了其他示例。
让我们构建一个简单的 REST API
我们将使用Oak 框架和 TypeScript(如果你愿意,也可以使用 Javascript)。
我们首先创建一个app.ts文件,该文件Application从https://deno.land/x/oak/mod.ts和router'./router.ts'导入内容。
import { Application } from 'https://deno.land/x/oak/mod.ts'
import router from './routes.ts'
然后我们需要设置环境变量HOST,PORT
const HOST = '127.0.0.1'
const PORT = 7700
现在让我们从https://deno.land/x/oak/mod.tsroutes.ts创建文件导入并创建路由。Router
import { Router }from 'https://deno.land/x/oak/mod.ts'
import { getBooks, getBook, addBook, updateBook, deleteBook } from './controller.ts'
const router = new Router()
router.get('/books', getBooks)
.get('/books/:isbn', getBook)
.post('/books', addBook)
.put('/books/:isbn', updateBook)
.delete('/books/:isbn', deleteBook)
export default router
注意:函数getBooks、getBook、addBook和updateBook是deleteBook从本地文件导入的,只是我们还没有创建它们。
创建好路由器之后,让我们app.ts添加以下代码来完成我们的工作:
const app = new Application()
app.use(router.routes())
app.use(router.allowedMethods())
console.log(`Listening on port ${PORT} ...`)
await app.listen(`${HOST}:${PORT}`)
现在,让我们创建 controller.ts 文件,并为 book 定义一个接口IBook,然后声明一个 book 对象的初始数组:
interface IBook {
isbn: string;
author: string;
title: string;
}
let books: Array<IBook> = [{
isbn: "1",
author: "Robin Wieruch",
title: "The Road to React",
},{
isbn: "2",
author: "Kyle Simpson",
title: "You Don't Know JS: Scope & Closures",
},{
isbn: "3",
author: "Andreas A. Antonopoulos",
title: "Mastering Bitcoin",
}]
现在让我们逐一实现这些函数。
getBooks:返回列表中的所有书籍。
const getBooks = ({ response }: { response: any }) => {
response.body = books
}
getBook:根据 ISBN 返回一本书,如果找不到则返回错误消息。
const getBook = ({ params, response }: { params: { isbn: string }; response: any }) => {
const book: IBook | undefined = searchBookByIsbn(params.isbn)
if (book) {
response.status = 200
response.body = book
} else {
response.status = 404
response.body = { message: `Book not found.` }
}
}
addBook:将一本书添加到书籍列表中。
const addBook = async ({ request, response }: { request: any; response: any }) => {
const body = await request.body()
const book: IBook = body.value
books.push(book)
response.body = { message: 'OK' }
response.status = 200
}
updateBook:如果书籍存在则更新,否则返回错误消息。
const updateBook = async ({ params, request, response }: { params: { isbn: string }; request: any; response: any }) => {
let book: IBook | undefined = searchBookByIsbn(params.isbn)
if (book) {
const body = await request.body()
const updateInfos: { author?: string; title?: string } = body.value
book = { ...book, ...updateInfos}
books = [...books.filter(book => book.isbn !== params.isbn), book]
response.status = 200
response.body = { message: 'OK' }
} else {
response.status = 404
response.body = { message: `Book not found` }
}
}
deleteBook:从书籍列表中删除书籍。
const deleteBook = ({ params, response }: { params: { isbn: string }; response: any }) => {
books = books.filter(book => book.isbn !== params.isbn)
response.body = { message: 'OK' }
response.status = 200
}
将函数添加到文件中后,我们需要导出它们,以便在文件controller.ts中使用它们。router.ts
/* return the book if found and undefined if not */
const searchBookByIsbn = (isbn: string): ( IBook | undefined ) => books.filter(book => book.isbn === isbn )[0]
export { getBooks, getBook, addBook, updateBook, deleteBook }
注意:searchBookByIsbn()这只是一个辅助函数。
你想了解更多关于迪诺的信息吗?
这里有一些资源:Deno 的官方网站、API 文档,你还可以在Deno 的优秀列表中找到更多资源、库和框架。
文章来源:https://dev.to/am77/deno-v1-0-303j







