deno|deno简易封装一个http服务器(路由-上篇)


目录

  • 前言
  • deno的serve库使用
  • 路由的实现
  • 代码下载

前言 deno提供了一个用于当http服务器的库,不过,我好像没翻到这玩意有路由。感觉写起来就很不爽了。
如果是我没翻到的话,望提醒,那这篇文章当做自己学习deno的一个纪念吧。
deno serve的官方文档地址:HTTP Server APIs
这便萌生了我想着自己简易封装一个自己用的动机,毕竟deno生态暂时不是特别好,也许自己用着用着就变成了造福大众的了呢。bug肯定有,目前只用于自己超级小业务的使用,菜轻喷。
deno的serve库使用
import { serve } from "https://deno.land/std@0.128.0/http/server.ts"

引入完毕之后,我们随便写点代码,监听一下8099端口,就很简单的实现一个http服务器了
// deno的 import { serve } from "https://deno.land/std@0.128.0/http/server.ts"; serve(() => new Response("Hello World\n", { port: 8099 }));

deno|deno简易封装一个http服务器(路由-上篇)
文章图片

不过,这好像有点太方便了,少了很多东西。
在node里面的时候,比如我们用express
这一对比确实少了点什么
// 这是node.js的 const express = require('express') const app = express(); app.get('/', (req, res) => { res.send('hello') })

不难看出,我们需要的是路由机制,不过好像没看到这个serve里头有路由这种东西。我只能看到这个serve的request里头带了个url
deno|deno简易封装一个http服务器(路由-上篇)
文章图片

好吧那我们只能通过这个url来实现一个最简单的路由机制了。
路由的实现 我们拿到了请求的url,那我们就要对url的路径进行处理,我们这边就不做过多的处理,因为是简易的封装,就不考虑太多的东西了,也就是能用就行的程度(轻喷)
我就简单的写了一个方法拿了一下路由的后缀,使用了正则表达式去处理的,肯定有bug
/** * 获取url的后缀 * @param url * @returns */ export const getUrlSuffix = (url: string): string => { const mFilter = ['http://', 'https://'] // 剔除掉前面的头,方便处理 mFilter.forEach(text => { url = url.replace(text, '') }) const mRegex = url.match(/\/(.*)/g) if (mRegex) return mRegex[0].replace(/\?.*/, '') return '' }/* 输入url:http://127.0.0.1:8099/lll 返回后缀:/lll */

然后定义一个路由表
先定义好接口形式
type RouteMethods = 'get' | 'GET' | 'post' | 'POST' | 'put' | 'PUT' | 'delete' | 'DELETE' | 'update' | 'UPDATE'// 路由表 export interface Route{ // 路由路径 path: string, // 请求方法 method: RouteMethods, // 回调函数 callback: (request: Request) => Promise | Response }

然后我们定义好路由的表形式
回调函数也包好
控制器
// 查询用户 export const UserSelect = async(req: Request) => { return new Response('select') }// 删除用户 export const UserDelete = async(req: Request) => { return new Response('delete') }// 修改用户 export const UserUpdate = async(req: Request) => { return new Response('update') }

路由表
import { Route } from '../interface/Route.ts' import * as UserControl from '../control/user.ts'// 定义路由表 const routes: Route[] = [ { path: '/select', method: 'GET', callback: UserControl.UserSelect }, { path: '/delete', method: 'GET', callback: UserControl.UserDelete }, { path: '/update', method: 'GET', callback: UserControl.UserUpdate }, ]export default routes

然后我自己的思路是将定义好的路由用一个map存起来,直接通过路径就能匹配到一整个路由
// 把路由丢到map里头 const RouteMap = new Map() Routes.forEach(route => RouteMap.set(route.path, route))

【deno|deno简易封装一个http服务器(路由-上篇)】然后最后在创建serve那里进行回调函数编写的时候就这样子写
// 路由的全局配置 const mHandle = (req: Request) => { // 这里是获取路由的路径 const mRoutePath = getUrlSuffix(req.url) // 从map中获取路由 const mRoute = RouteMap.get(mRoutePath) // 当找不到该路由,则直接返回404 if (!mRoute || mRoute.method.toLowerCase() !== req.method.toLowerCase()) return new Response('404', { status: 404 }) return mRoute.callback(req) }serve(mHandle, { port: 8099 })

大概就是这样子就封完了一个最简易且满是bug的路由
访问没有定义的路由
deno|deno简易封装一个http服务器(路由-上篇)
文章图片

访问定义好的路由
deno|deno简易封装一个http服务器(路由-上篇)
文章图片

deno|deno简易封装一个http服务器(路由-上篇)
文章图片

代码下载 上面的代码比较片面,我提供了完整的代码下载地址,然后我也会慢慢的更新这个东西的,我就借此东西来让自己对deno的理解更进一步
git地址:gitee里下载
最终的实现效果是:
// example/index.ts import HttpServer from '../mod.ts' import { RouteRequest, RouteResponse } from '../src/interface/Route.ts'// 调用的例子 const UserSelect = (req: RouteRequest, res: RouteResponse) => { return res.send('sb') }new HttpServer({ port: 8099, routes: [ { path: '/select', method: 'GET', callback: UserSelect } ] })

    推荐阅读