【Day 28】Deno + Oak 建立 Restful API (1)

https://ithelp.ithome.com.tw/upload/images/20201014/20109963EeoAMWDT8V.jpg

前言

在 NodeJS 的时候,要建立一个网页我们时常会搭配像是 Express、Koa、Hapi 这些框架,说到学习一个语言,最先开始的一定是 ,那小编今天就要来撰写 Restful API,搭配的框架是 oak,它是目前 star 数最高的套件,相信有玩 Koa 的朋友跟这套件应该很熟悉,关於 oak 官方的介绍,我们在这里也列给大家:

A middleware framework for Deno's http server, including a router middleware.
This middleware framework is inspired by Koa and middleware router inspired by koa-router.

是的,oak 它的灵感就是来自於 Koa,以及 Koa-router。
避免有些读者并不知道 Koa,我们会大概提一下 Koa 的架构,然後就进入实作 Restful API。

Koa

https://ithelp.ithome.com.tw/upload/images/20201016/20109963vCrCKnfIa0.jpg
Koa 是基於 NodeJS 的 HTTP 框架,是由 Express 原班人马打造的,Koa2 使用的 async/ await 来做异步开发,与 Express 最大的不同是 Express 是渐进式的,也就是中间件一个接续一个执行;而 Koa 则因为中间件支持 generator,所以它的执行顺序是洋葱式的。

洋葱式: 当从中间件开始执行,遇到 next 会进入下一个中间件,一直执行到最後一个中间件;顺序相反时,则是执行上一个 next 之後的程序,一直执行到第一个中间件才发出响应。

那因为 oak 跟 koa 实在太像,接下来我们就直接带实作拉~~~~

Oak

这里我们将介绍如何使用 Oak 来开发一个 Restful API,他将支援以下功能:

  • 新增 Todo
  • 修改 Todo
  • 显示 Todo
  • 显示单笔 Todo
  • 删除 Todo

事情预告:如果还没安装好环境的朋友,请先到前一天安装好环境唷!!

正式开始

  1. 先建立好资料夹名称为 oak
  2. 新增档案 server.ts ,这档案主要负责启动 browser,以及使用路由:
    那因为目前都还是空的,所以就先来个 Hello World 吧~~
// 第一次执行 Deno 会访问这网址并安装好 oak
import { Application, Router } from "https://deno.land/x/oak/mod.ts";
const app = new Application();
const port = 8080; 
const router = new Router();  // 宣告一个新路由
router.get("/", ({ response }: { response: any }) => {
  response.body = {
    message: "Hello World",
  };
});
app.use(router.routes());
app.use(router.allowedMethods());

await app.listen({ port });    // 将跑在 127.0.0.1:8080 唷

当建立好了,使用 $ deno run --allow-net server.ts 就能将专案起起来罗~~ Hello World

这里的 router.get会接收两个参数,第一个是 路径,第二个是函数,这里我们宣告 response:any,代表 response 这个变量可以是 any 型,与就是避免掉 Typescript 的严格检查,而 response.body 则是回传的内容。 app.use(router.routes()) 是在说明要使用 router 变数中所有的路径,app.use(router.allowedMethods()) 则是在说允许访问的方法(Get, Post, Put, Delete等)。

3.新建 controllers 资料夹,并建立 todo.ts:
最後才会来撰写 controller 这些方法唷,但是先定义起来

export default {
  getAllTodos: () => {},   // 显示 Todo
  createTodo: async () => {},    // 新增 Todo
  getTodoById: () => {},   // 显示单笔 Todo
  updateTodoById: async () => {},  // 修改 Todo
  deleteTodoById: () => {},  // 删除 Todo
}
  1. 建立 routes 资料夹,并建立 routes.js:
import { Router } from "https://deno.land/x/oak/mod.ts";
const router = new Router();
// 引入刚刚建立在 controller 里的方法
import todoController from "../controllers/todo.ts";
router
  .get("/todos", todoController.getAllTodos)
  .post("/todos", todoController.createTodo)
  .get("/todos/:id", todoController.getTodoById)
  .put("/todos/:id", todoController.updateTodoById)
  .delete("/todos/:id", todoController.deleteTodoById);
export default router;
  1. server.js 引入 router,因为有 router 了,所以可以删除部分在 server.ts 里的程序,并且使用刚刚引入的 router:

引入 router

import todoRouter from './routes/routes.js';

删除程序:

// 这一段是要删除的唷
const router = new Router();
router.get("/", ({ response }: { response: any }) => {
  response.body = {
    message: "Hello World",
  };
});
app.use(router.routes());
app.use(router.allowedMethods());
// 这一段是要删除的唷

使用刚刚引入的 router (名称为: todoRouter)

app.use(todoRouter.routes());
app.use(todoRouter.allowedMethods());
  1. 在 server.ts 添加 event listener ,监听端口:
app.addEventListener("listen", ({ secure, hostname, port }) => {
  const protocol = secure ? "https://" : "http://";
  const url = ${protocol}${hostname ?? "localhost"}:${port};
  console.log(Listening on: ${port});
});
  1. 建立 interface 资料夹,并且建立 Todo.ts 介面:
export default interface Todo {
  id: string,
  todo: string,
  isCompleted: boolean,
}

这里的介面是为了约束使用者传进来的资料格式

  1. 建立 stubs 资料夹,以及 todos.ts,并建立 Mock 的资料(假资料):
import { v4 } from 'https://deno.land/std/uuid/mod.ts';
import Todo from '../interfaces/Todo.ts';
let todos: Todo[] = [
  {
    id: v4.generate(),     // 自动产生 string 的 id
    todo: 'walk dog',
    isCompleted: true,
  },
  {
    id: v4.generate(),
    todo: 'eat food',
    isCompleted: false,
  },
  {
    id: '3',
    todo: 'eat food',
    isCompleted: false,
  },
];

export default todos;

接下来明天我们就要开始实作 Controller 了。

结论

  • 介绍了 Koa
  • 介绍了 Oak
  • 开始实作 Oak Restful API

/images/emoticon/emoticon06.gif


<<:  Flutter学习Day3 Widget 观念 StatelessWidget (下)

>>:  【Day 29】Deno + Oak 建立 Restful API (2)

【企业 WFH 新型态,文件加密护资安】活动分享

跟大家分享一个线上研讨会,有兴趣的可以参考喔~ 居家办公、分流上班等远距办公的企业模式,俨然默默地成...

无线网路安全-邪恶的双胞胎(Evil Twin) & 流氓接入点(Rogue Access Point)

作为安全专家,我们应该尽最大努力做出风险意识,明智的决策。窃听,仅密文攻击,流氓接入点和邪恶双胞胎...

Day1:Tensorflow?Keras?

  最初接触Tensorflow的时候,还是在1.x版本,那时候Keras支援性不高,因此和同学之间...

【C#】Creational Patterns Abstract Factory Mode

The Abstract Factory pattern provides an interface...

Day 19-制作购物车系统之将资料汇入脚本

今天要把前面几天的资料(包括MongoDB连线、产品等)汇入到脚本 以下内容有参考教学影片,底下有附...