"experimentalDecorators": true,
"emitDecoratorMetadata": true,
npm install reflect-metadata -S
import Express, { Router, Request, Response, NextFunction } from 'express'
import { getResponseData, checkLogin } from '../utils/index'
interface RequestWithBody extends Request {
body: {
[key: string]: string | undefined
}
}
const homePageHtml = `
<html>
<body>
<a href="/showData" >展示数据</a>
<a href="/logout" >退出登录</a>
</body>
</html>
`
const loginPageHtml = `
<html>
<body>
<form method="post" action="/login">
<input type="password" name="password" />
<button>登陆</button>
</form>
</body>
</html>
`
export class LoginController {
home(req: Request, res: Response, next: NextFunction) {
if (req.session?.isLogin) {
res.send(homePageHtml);
} else {
res.send(loginPageHtml);
}
}
login(req: RequestWithBody, res: Response) {
if (req.session?.isLogin) {
res.json(getResponseData(false, '已经登录过'))
} else {
if (req.body?.password === '123456' && req.session) {
req.session.isLogin = true;
res.json(getResponseData(true))
} else {
res.json(getResponseData(false, '登录失败'));
}
}
}
logout(req: Request, res: Response) {
if (req.session) {
req.session.isLogin = undefined;
}
res.json(getResponseData(true));
}
}
import { Request, Response } from 'express'
import { getResponseData, checkLogin } from '../utils/index'
import { get, use, controller } from '../decorator/'
import * as Data from '../utils/data.json'
@controller('/')
export class DataController {
@get('/showData')
@use(checkLogin)
router(req: Request, res: Response) {
res.json(getResponseData(Data))
}
}
controller 对控制器定义的路由统一收集,然后统一定义路由
import router from '../router';
import { RequestHandler } from 'express'
import { Methods } from './request'
export function controller(root: string) {
return function <T extends { new(...args: any[]): any }>(construct: T) {
for (let key in construct.prototype) {
let pathStr: string = Reflect.getMetadata('path', construct.prototype, key)
let method: Methods = Reflect.getMetadata('method', construct.prototype, key);
let middlewares:RequestHandler[] = Reflect.getMetadata('middlewares', construct.prototype, key) || [];
if (root) {
pathStr = root == '/' ? pathStr : root + pathStr
}
if (pathStr && method) {
router[method](pathStr, ...middlewares, construct.prototype[key]);
}
}
}
}
use 对处理方法,使用中间件
import { RequestHandler} from 'express'
export function use(middleware: RequestHandler) {
return function (target: any, key: string, dec: PropertyDescriptor) {
let middlewares = Reflect.getMetadata('middlewares', target, key) || [];
middlewares.push(middleware);
Reflect.defineMetadata('middlewares', middlewares, target, key);
}
}
request 获取处理方法上的定义的请求方式,请求路由
import 'reflect-metadata'
export enum Methods {
GET = 'get',
POST = 'post'
}
function requestMethods(methods:Methods) {
return function (path: string) {
return function (target: any, key: string, dec: PropertyDescriptor) {
Reflect.defineMetadata('path', path, target, key);
Reflect.defineMetadata('method', methods, target, key);
}
}
}
export const get = requestMethods(Methods.GET)
export const post = requestMethods(Methods.POST)
import { Router } from 'express';
export default Router();
引入路由,添加控制器
import express, { } from 'express';
import bodyParser from 'body-parser'
import cookieSession from 'cookie-session'
import './controller/LoginController'
import './controller/DataController'
import router from './router'
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieSession({
name: 'session',
keys: ['typescript-api'],
maxAge: 24 * 60 * 60 * 10000
}))
app.use(router);
app.listen(8000, () => {
console.log("server success!");
})