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

目录

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

前言

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

deno的serve库使用

import { serve } from "https://deno.land/[email protected]/http/server.ts"

引入完毕之后,我们随便写点代码,监听一下8099端口,就很简单的实现一个http服务器了

// deno的
import { serve } from "https://deno.land/[email protected]/http/server.ts";
serve(() => new Response("Hello World\n", { port: 8099 }));

deno简易封装一个http服务器(路由-上篇)_第1张图片
不过,这好像有点太方便了,少了很多东西。
在node里面的时候,比如我们用express
这一对比确实少了点什么

// 这是node.js的
const express = require('express')
const app = express();
app.get('/', (req, res) => {
    res.send('hello')
})

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

好吧那我们只能通过这个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> | 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<string, Route>()
Routes.forEach(route => RouteMap.set(route.path, route))

然后最后在创建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简易封装一个http服务器(路由-上篇)_第3张图片

访问定义好的路由
deno简易封装一个http服务器(路由-上篇)_第4张图片
deno简易封装一个http服务器(路由-上篇)_第5张图片

代码下载

上面的代码比较片面,我提供了完整的代码下载地址,然后我也会慢慢的更新这个东西的,我就借此东西来让自己对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 }
  ]
})

你可能感兴趣的:(deno,http,服务器,javascript,typescript)