真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

node后端路由自動(dòng)加載怎么實(shí)現(xiàn)

這篇文章主要介紹“node后端路由自動(dòng)加載怎么實(shí)現(xiàn)”的相關(guān)知識(shí),小編通過實(shí)際案例向大家展示操作過程,操作方法簡單快捷,實(shí)用性強(qiáng),希望這篇“node后端路由自動(dòng)加載怎么實(shí)現(xiàn)”文章能幫助大家解決問題。

10年積累的成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有秦皇島免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

背景

今天來談?wù)刵ode后端中路由的問題。

我們前端同學(xué)或者是nodejs服務(wù)端的同學(xué),在你們使用express和koajs寫接口的時(shí)候, 咱們是不都要寫路由 比如如下

登錄接口router.post('/user/login', user.login);

獲取用戶信息接口router.get('/user/info', checkAuth, user.xxx);

這種寫法很常見, 先注冊路由,再指定后續(xù)要執(zhí)行的中間件方法。

可是當(dāng)接口越來越多,比如有1000個(gè)接口, 就得這樣注冊1000次,多了我認(rèn)為是一件很麻煩且不優(yōu)雅的事情

koa&express 路由注冊示例

const express = require('express');
const router = express.Router();
const user = require('../../controllers/user');
const tokenCheck = require('../../middleware/token_check_api');

//用戶注冊
router.post('/user/register', user.register);
//用戶登錄
router.post('/user/login', user.login);
router.post('xxx', tokenCheck, user.xxx);
...假裝還有有1000個(gè)

寫1000個(gè)接口就要在router.js里注冊1000次嗎?

eggjs路由注冊示例

'use strict';

// egg-router extends koa-router

import { Application } from 'egg';

export default (app: Application) => {
  const { router, controller, middleware } = app;
  router.get('/', middleware.special(), controller.home.index);
  router.get('/1', middleware.special(), controller.home.index1);
  ....
  router.get('/error', controller.home.error);
};

**這種項(xiàng)目擴(kuò)大時(shí)候, 我認(rèn)為這種配置會(huì)顯得很冗余,所以就需要實(shí)現(xiàn)一種路由自動(dòng)加載的機(jī)制來改善它優(yōu)化它。

1、提升效率

2、更優(yōu)雅的編寫

常見的路由自動(dòng)加載

接觸下來, 我發(fā)現(xiàn)有幾個(gè)框架用不同方法實(shí)現(xiàn)了路由自動(dòng)加載。

一、think系列

第一個(gè)是thinkPHP和thinkjs, 參考鏈接 thinkjs.org/zh-cn/doc/3…

他兩的關(guān)系屬于是thinkjs是后來按照thinkPHP的思想設(shè)計(jì)開發(fā)的。

他兩路由自動(dòng)加載屬于基于文件的, 就是說你按控制器的名字和方法名寫好,直接就可以訪問路由,不需要額外的配置。

1、thinkphp的路由自動(dòng)加載

tp是 按模塊/控制器/方法文件名 自動(dòng)加載

module?/controller/Action

比方下面這個(gè)Admin模塊下, AdlistController.class.php里 index方法 他的路由就會(huì)自動(dòng)加載為 Admin/adList/index

node后端路由自動(dòng)加載怎么實(shí)現(xiàn)

2、thinkjs的路由自動(dòng)加載

控制器文件文件自動(dòng)加載邏輯

1)、應(yīng)用初始化,創(chuàng)建實(shí)例
....

2)、遍歷控制器目錄, 加載控制器

得到目錄文件對應(yīng)的導(dǎo)出class的 Map
例如 Controller目錄下 他會(huì)加載出來模塊、控制器、方法掛在他的app上。

node后端路由自動(dòng)加載怎么實(shí)現(xiàn)

{
  '/order': [class default_1 extends default_1],
  '/user': [class default_1 extends default_1]
}

3、控制器匹配部分

上一步是在thinkjs應(yīng)用啟動(dòng)階段做的事情。

這一步 控制器匹配部分 是在當(dāng)請求進(jìn)來的時(shí)候做的事情。

就是當(dāng)請求進(jìn)來,會(huì)先進(jìn)過,think-router 把module, controller, action ,解析出來掛在ctx上。

在這里拿ctx上本次請求的module, controller, action去和啟動(dòng)時(shí)掛在app的 module, controller, action,列表去匹配, 如果有就執(zhí)行。

think-controller的匹配邏輯詳見 github.com/thinkjs/thi…

thinkjs和koa-router路由匹配的區(qū)別

1、 think  think-router解析完, think-controller去匹配執(zhí)行, 他這個(gè)是動(dòng)態(tài)匹配。
2、koa-router 匹配到路由后, 自己再用koa-compose組裝一個(gè)小洋蔥圈去執(zhí)行
! 這種我的理解是程序啟動(dòng)就注冊好的順序image.png

node后端路由自動(dòng)加載怎么實(shí)現(xiàn)

node后端路由自動(dòng)加載怎么實(shí)現(xiàn)

總結(jié):thinkjs是先把你的控制器和方法加載出來, 最后當(dāng)請求進(jìn)來的時(shí)候,利用think-controller 去先匹配模塊/控制器,再匹配方法, 如果有的話就幫你執(zhí)行,沒有的話,就404

二、以egg改造版為例 裝飾器的路由自動(dòng)加載

裝飾器的寫法類似于 java spring中的注解

node框架中 nestjsmidwayjs已經(jīng)全面擁抱了裝飾器路由。

  • 寫法比較優(yōu)雅

  • 建議控制器的文件名和控制器名字保持一致, 這樣你找api也比較好找 比如控制的文件名字叫 home.ts , 那你控制器注冊也寫 @controller('/home') 來保持一致。

1、 控制器裝飾器 @controller('/order')

'use strict';

import { Context } from 'egg';
import BaseController from './base';
import { formatDate } from '~/app/lib/utils';
import { SelfController, Get } from './../router'

@SelfController('/home')
export default class HomeController extends BaseController {
  [x: string]: any;
  @validate()
  @Get("/")
  public async index(): Promise {}
  
}

2、方法裝飾器 @Get('/export')、 @Post('/list')

get接口 就是 @Get()

post的接口 就是 @Post()

  @Get("/")
  public async index(): Promise {}

  @Post("/update")
  public async update(): Promise {}

3、裝飾器路由統(tǒng)一注冊

這里統(tǒng)一按egg的方法循環(huán)注冊路由

'use strict';

import { Application, Context } from 'egg';
import 'reflect-metadata';

const CONTROLLER_PREFIX: string = '';
const methodMap: Map = new Map();
const rootApiPath: string = '';

interface CurController {
  pathName: string;
  fullPath: string;
}

/**
 * controller 裝飾器,設(shè)置api公共前綴
 * @param pathPrefix {string}
 * @constructor
 */
export const SelfController = (pathPrefix?: string): ClassDecorator => (targetClass): void => {
  // 在controller上定義pathPrefix的元數(shù)據(jù)
  // https://github.com/rbuckton/reflect-metadata

  (Reflect as any).defineMetadata(CONTROLLER_PREFIX, pathPrefix, targetClass);
};

const methodWrap = (path: string, requestMethod: string): MethodDecorator => (target, methodName): void => {
  // 路由裝飾器參數(shù)為空時(shí),路由為方法名
  const key = path ? `${requestMethod}·${path}·${String(methodName)}` : `${requestMethod}·${String(methodName)}·/${String(methodName)}`;
  methodMap.set(key, target);
};

// Post 請求
export const Post = (path: string = ''): MethodDecorator => methodWrap(path, 'post');

// Get 請求
export const Get = (path: string = ''): MethodDecorator => methodWrap(path, 'get');

export default (app: Application): void => {
  const { router } = app;
  // 遍歷methodMap, 注冊路由
  methodMap.forEach((curController: CurController, configString: string) => {
    // 請求方法, 請求路徑, 方法名 
    const [ requestMethod, path, methodName ] = configString.split(`·`);
    // 獲取controller裝飾器設(shè)置的公共前綴
    // 如果controller沒有添加SelfController裝飾器,則取文件名作為路徑
    let controllerPrefix: string | undefined | null = (Reflect as any).getMetadata(CONTROLLER_PREFIX, curController.constructor);
    if (!(Reflect as any).hasMetadata(CONTROLLER_PREFIX, curController.constructor)) {
      controllerPrefix = `/${curController.pathName.split(`.`).reverse()[0]}`;
    }
    const func: (this: Context, ...args: any[]) => Promise = async function (...args: any[]): Promise {
      return new (curController.constructor as any)(this)[methodName](...args);
    };
    // 注冊路由
    router[requestMethod](rootApiPath + controllerPrefix + path, func);
  });
};

建議使用node寫服務(wù)直接上midwayjs或者nestjs。

關(guān)于“node后端路由自動(dòng)加載怎么實(shí)現(xiàn)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。


分享題目:node后端路由自動(dòng)加載怎么實(shí)現(xiàn)
標(biāo)題鏈接:http://weahome.cn/article/picgih.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部