在express中使用ES7裝飾器構建路由

Tuzilow發表於2020-09-12

在Java的Spring框架中,我們經常會看到類似於@Controller這樣的註解,這類程式碼能夠極大的提高我們程式碼的可讀性和複用性。而在Javascript的ES7提案中,有一種新的語法叫做decorator,它能夠在Javascript中實現與註解相同的功能。

@tuzilow/express-decorator

@tuzilow/express-decorator是由本人開發的一個簡單的express裝飾器包,具有@Controller@RootUrl@Get等API,能夠方便快捷的構建express後臺介面。

正式開始

建立package.json

執行npm init,並使用npmyarn新增以下依賴

{
  "name": "decorator-demo",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "@tuzilow/express-decorator": "^0.0.3",
    "express": "^4.17.1"
  },
  "devDependencies": {
    "@babel/cli": "^7.11.6",
    "@babel/core": "^7.0.0",
    "@babel/node": "^7.0.0",
    "@babel/plugin-proposal-class-properties": "^7.10.4",
    "@babel/plugin-proposal-decorators": "^7.10.5",
    "@babel/preset-env": "^7.0.0",
    "babel-eslint": "^9.0.0"
  },
  "scripts": {
    "start": "babel-node index"
  }
}

建立.babelrc

{
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose": true }]
  ],
  "presets": ["@babel/preset-env"]
}

建立index.js並編寫程式碼

首先,編寫一個普通的express應用

import express from 'express';

const Server = express();

Server.get('/', (req, res) => {
  res.json({
    title: 'hello world',
  });
});

Server.listen(3000, () => {
  console.info('running in http://localhost:3000');
});

執行無誤後使用@tuzilow/express-decorator對其進行改造

import express from 'express';
import { Controller, Get } from '@tuzilow/express-decorator';

const Server = express();

@Controller
class User {
  @Get('/')
  home(req, res) {
    res.json({
      title: 'hello world',
    });
  }
}

Server.use(new User());

Server.listen(3000, () => {
  console.info('running in http://localhost:3000');
});

執行結果與前面普通的express應用的執行結果相同,如果想要設定統一的父級路由,可以使用@RootUrl

import express from 'express';
import { Controller, Get, RootUrl } from '@tuzilow/express-decorator';

const Server = express();

@Controller
class User {
  @RootUrl('/user') url() {}
  
  @Get('/')
  home(req, res) {
    res.json({
      title: 'hello world',
    });
  }
   
  @Get('/list')
  list(req, res) {
    res.json({
      title: 'this is a list',
    });
  }
}

Server.use(new User());

Server.listen(3000, () => {
  console.info('running in http://localhost:3000');

這樣請求路徑就會變為http://localhost:3000/userhttp://localhost:3000/user/list,因為該裝飾器包只提供了簡易的API,因此傳遞引數、設定header等操作需要使用express的方法

import express from 'express';
import { Controller, Get, RootUrl, Post } from '@tuzilow/express-decorator';

const Server = express();

@Controller
class User {
  @RootUrl('/user') url() {}

  @Get('/')
  home(req, res) {
    res.json({
      title: 'hello world',
    });
  }

  // query傳參
  @Get('/getOne')
  getOne(req, res) {
    const { id } = req.query;
    res.json({
      title: 'hello world',
      id,
    });
  }

  // params傳參
  @Get('/list/:id')
  getItem(req, res) {
    const { id } = req.params;
    res.json({
      title: 'hello world',
      id,
    });
  }

  // body傳參
  @Post('/create')
  create(req, res) {
    const { id } = req.body;
    res.json({
      code: 0,
      id,
    });
  }
}

Server.use(new User());

Server.listen(3000, () => {
  console.info('running in http://localhost:3000');
});

專案原始碼

相關文章