强型闯入DenoLand[33] - Web API 正式完成!

Node.js之父新专案Deno 1.0正式亮相| iThome

强型闯入DenoLand[33] - Web API 正式完成!

昨天笔者介绍了 deno_mongo 的使用方法,本篇就来将 Web API 剩下的逻辑完成吧!

进入正题

Day 30 中,我们已将大量的程序码都实作完成了,只剩下:

  • controllers/Usercontroller.ts
  • controllers/models/Database.ts

需要完成。

controllers/models/Database.ts

相较 UsercontrollerDatabase 封装了更底层的逻辑,它直面了整个社会被用来建立与资料库的连结:

import { MongoClient } from "https://deno.land/x/[email protected]/mod.ts";

export class DatabaseController {
  private client;
  constructor() {
    this.client = new MongoClient();
    this.client.connectWithUri("mongodb://localhost:27017");
  }
  initModels(database) {
  return this.client.database(database);
}
}

由於笔者实作的是极简易版的 Web API ,在该物件中只存在一个方法: initModels()

Class::DatabaseController 被实例化时, constructor() 就已经与 mongoDB 建立连线,而 initModels 只是用来选定使用者希望连线的资料库。

controllers/UserController.ts

在完成 Database 连线逻辑的封装後,我们进一步来看看 UserController 的实作:

import { DatabaseController } from "./models/Database.ts";
const dataBase = await new DatabaseController().initModels("test");
const collection = dataBase.collection("data");

export class userController {
  findOne(props:any){
    return collection.findOne({"name":`${props}`});
  }
  insertData(props:any){
    collection.insertOne({
      name:`${props}`
    })
  }
}

UserController.ts 负责接收路由的请求并根据请求对资料库进行操作,所以都会跟 Route.ts 内的路由相对应:

import { Router, Status, RouterContext  } from "https://deno.land/x/oak/mod.ts";
import { userController } from "../controllers/UserController.ts";
const controller = new userController();
export function UserRoutes(router: Router) {
  return router
    .get("/user/:id", async (ctx: RouterContext) => {
      const users = await controller.findOne(ctx.params.id);
      if (users) {
        ctx.response.status = Status.OK;
        ctx.response.body = users;

      } else {
        ctx.response.status = Status.NotFound;
        ctx.response.body = [];
      }
    })
    .post("/insert", async(ctx: RouterContext)=>{
      const { name } = await ctx.request.body;
      if(name){
        await controller.insertData(name)
        ctx.response.status = Status.OK;
        ctx.response.body = 'Success!'
      }
    })
}

完整原始码

完整原始码都已经上传到 github 上,如果读者有需要可以自行取用。

补充: ORM

物件关联对映(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序设计技术,用於实现物件导向程序语言里不同类型系统的资料之间的转换。从效果上说,它其实是建立了一个可在程序语言里使用的「虚拟物件资料库」。如今已有很多免费和付费的ORM产品,而有些程序设计师更倾向於建立自己的ORM工具。

物件导向是从软件工程基本原则(如耦合、聚合、封装)的基础上发展起来的,而关联式资料库则是从数学理论发展而来的,两套理论存在显着的区别。为了解决这个不匹配的现象,物件关联对映技术应运而生。

简单的说:ORM相当於中继资料。具体到产品上,例如下边的ADO.NET Entity Framework。DLINQ中实体类的属性[Table]就算是一种中继资料。

物件关联对映成功运用在不同的物件导向持久层产品中,如:TorqueOJBHibernateTopLinkCastor JDOTJDOActive RecordNHibernateADO.NET Entity Framework 等。

-- wikipedia

简单来说, ORM 就是利用物件导向将资料库连线过程与操作封装成使用者容易阅读的形式。

封装 Database.ts 的作法其实与 ORM 的概念非常相似,只是笔者不确定这样的做法是否为 ORM 。

其实 deno_mongo 本身就已经相当易懂再加上 MongoDB 并不像传统的关联式资料库,一般在操作 SQL 时,我们都需要使用 SQL 语法:

INSERT INTO customers (C_Id, Name, City, Address, Phone)
VALUES (3, '李三', '高雄县', 'ZZ路300号', '07-12345678');

这样的作法比起 ORM 封装更不易懂,若没有适当的防范,更会衍伸出常见的 SQL Injection 的攻击问题。

因此,我们可以处处看到 ORM 的身影,像是 Laravel 的 eloquent

说了这麽多 ORM 真的这麽好吗 ? 笔者大概整理了一下 ORM 的优缺点:

优点

  1. 容易理解
  2. 安全

缺点

  1. 效能较差

    因为多了一层物件封装,所以在执行上,效能会比直接对资料库操作来的更慢。

  2. 灵活度较 SQL 语法差

    这点就考验 ORM 开发者的功力了,因为 SQL 能做的事情非常多,除了一般操作还能将元素排序。

总结

长达 34 天的抗战终於告一段落了...吗?

不 ! 笔者还要继续写 !

下一篇会向大家分享在制作毕业专题时遇到的跨域存取问题,我们明天 (?) 见 !

延伸阅读

同样的事情在不同人眼中可能会有不同的见解、看法。

在读完本篇以後,笔者也强烈建议大家去看看以下文章,或许会对型别、变数宣告...等观念有更深层的看法唷!


<<:  [Golang]func的结构与特性整理-Part 2

>>:  如何替 RxJS 撰写测试 - 一般测试与弹珠图测试方法

TailwindCSS 从零开始 - 伪类变体 Pseudo-Class Variants

什麽是伪类变体 又来一个专有名词,还没学就心慌慌... 但是发现有一个熟悉名词:伪类(看到这个我就...

生存法则一:在快速变动的环境下生存

承认我们都有一些资讯焦虑 我们生活在快速变动的时代,无时无刻都有新的产业跟名词冒出,数据驱动决策、区...

Day 12:为 Hexo 装设 Google Analytics,追踪你的部落格流量(使用 Next 布景主题)

如果你曾经使用过一些 BSP 服务,基本上本身都会内建流量或人数统计的功能,帮助我们查看部落格近期人...

机器学习:资料流图(Data Flow Graphs)模型训练架构

资料流模型将运算任务描述成一个"有向无环图",节点表示资料运算和储存,节点之间的...

Day 4 - 原型 (3): 主页的元件组合

前言 今天就把刚完成的元件组合成一个页面吧。 框架 (Frame) 我先以桌面显示器为目标, 建立一...