Request

request对象表示HTTP请求,并具有请求query字符串、参数、body、HTTP headers等的属性。除了添加新的属性和方法外,还包含原型的属性和方法。

随着系列文章的发布,我们将继续研究使用request对象;

Response

response对象表示程序在接收到HTTP请求时发送HTTP响应。它最重要的方法就是send,它发送HTTP响应,所以客户端能够接收到它。send函数接受不同类型的数据,例如string,object,数组或缓冲区。send使用数据结束响应过程,也可以使用end函数结束响应过程。

与request对象一样,我们将继续深入研究和使用它。

app.get('/', (request, response) => {
response.send({
hostname: request.hostname,
path: request.path,
method: request.method,
});
});

Controllers

创建一个Express应用的常见方法叫做mvc。controller是mvc的关键组件,它包含了应用程序中处理客户端请求的主要逻辑。为了使项目具有良好的可读性,我创建了一个app类,并且使用外置路由挂载相应的controller函数。

在server脚本中加载应用,监听端口。 src/server.ts

app.listen(process.env.PORT || 3001, () => {
logger.info(`Server running at http://localhost:${process.env.PORT} in ${process.env.NODE_ENV}`);
});

下面代码定义了app类,通过构造函数创建express应用,注册中间件,初始化路由器,连接数据库。src/app.ts:

class App {
app: express.Application = express();
private _routes: Router; constructor(mongoUrl: string) {
this.app = express();
this.initializeStaticFolder(this.app);
this.initializeMiddlewares(this.app); this._routes = new Router();
this._routes.initializeRouter(this.app); this.mongoSetup(mongoUrl);
this.app.use((request: Request, response: Response) => {
return response.status(404).json({ code: -1, data: null, msg: "Notfound" })
});
}
//初始化中间件
private initializeMiddlewares = (app: express.Application): void =>{
app.use(express.json());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
}
//初始化静态文件夹
private initializeStaticFolder = (app: express.Application): void =>{
const folder = "assets";
const fileFolder = path.resolve(folder);
app.use(express.static(fileFolder))
}
//连接数据库
private mongoSetup = (connStr: string): void => {
mongoose.connect(connStr, { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true, useFindAndModify: false }).then(
() => { logger.info("MongoDB connection success!"); }
).catch(
(err) => { logger.error("MongoDB connection error. Please make sure MongoDB is running. " + err); }
);
}
} export default new App(MONGODB_URI).app;

  下面代码定义了应用程序的总路由器类,通过构造函数实例化外置路由和控制器;定义初始化路由函数,将express应用程序传递给外置路由器。src/router.ts:

export class Router {
private _clientRouter: ClientRouter; constructor() {
const clientController = new ClientController();
this._clientRouter = new ClientRouter(clientController);
} //registered routing.
initializeRouter = (app): void => {
this._clientRouter.router(app);
}
}

下面的代码定义了client的外置路由器,涉及到了client的增删改查功能。src/auth/client/clientRouter.ts

export class ClientRouter {
private _clientController: ClientController;
private _router: Router; constructor(clientController: ClientController) {
this._clientController = clientController;
this._router = Router();//创建一个express的外置路由
this.initRouter(this._router);
} //配置路由与controller.
private initRouter = (router: Router): void => { router.route("")
.get(this._clientController.getClients)
.post(this._clientController.create); router.route("/:id")
.patch(this._clientController.update)
.delete(this._clientController.delete);
} //将外置路由配置给express应用程序
router = (app: express.Application): void => {
app.use("/api/v1/admin/clients", this._router);
}
}

下列代码定义了client的控制器类,该类中的函数要被传递给clientRouter使用,上下文发生了变化,所以采用箭头函数保证this的指向正确。src/auth/client/clientController.ts

export class ClientController
{
private _iclientRepository: IClientRepository;
constructor(iClientRepository: IClientRepository)
{
this._iclientRepository = iClientRepository;
} create = async(req: Request, res: Response, next: NextFunction): Promise<void | Response>=>{
try
{
const { clientId, clientName, grants } = req.body;
const body = { clientId, clientName, grants };
const client = await this._iclientRepository.create(body);
if(client){
return this.responseSuccess(201, client, "Created.", res);
}
else{
return this.responseWarn(200, {code: ErrCode.CLIENTID_OR_CLIENTNAME_EXISTS}, "ClientName or clientId field is already exists.", res);
}
}
catch (e)
{
logger.error(e);
next(e);
} } getClients = async(req: Request, res: Response, next: NextFunction): Promise<void | Response>=>{
try
{
let pageSize = req.query.pageSize || 5;
let page = req.query.page || 1; pageSize = (Number)(pageSize);
page = (Number)(page);
const clients = await this._iclientRepository.getClients(page, pageSize);
if(clients){
return this.responseSuccess(200, clients, `${clients.length} client.`, res);
}
else{
return this.responseWarn(200, {code: ErrCode.CLIENT_NOCONTENT}, "0 client.", res);
}
}
catch (e)
{
logger.error(e);
next(e);
}
} update = async(req: Request, res: Response, next: NextFunction): Promise<void | Response>=>{
try
{
const { id } = req.params;
const body = req.body;
const clientName = body.clientName; if (body.clientId || body.clientId === "") {
delete body.clientId;
}
if (body.clientSecret || body.clientSecret === "") {
delete body.clientSecret;
} const client = await this._iclientRepository.update(id, clientName, body);
if(client){
return this.responseSuccess(200, client, `${client.clientName} has been updated.`, res);
}
else{
return this.responseWarn(200, {code: ErrCode.INVALID_CLIENT}, "The client is notfound or clientName/clientId field is already exists.", res);
}
}
catch (e)
{
logger.error(e);
next(e);
}
} delete = async(req: Request, res: Response, next: NextFunction): Promise<void | Response>=>{
try
{
const { id } = req.params;
const client = await this._iclientRepository.delete(id);
if(client){
return this.responseSuccess(204, null, "deleted.", res);
}
else{
return this.responseWarn(200, {code: ErrCode.CLIENT_NOTFOUND}, "The client is notfound.", res);
}
}
catch (e)
{
logger.error(e);
next(e);
}
} private responseSuccess = (statusCode: number, data: object, msg: string, res: Response): void =>{
res.status(statusCode).json({
code: 0,
data,
msg
});
} private responseWarn = (statusCode: number, data: object, msg: string, res: Response): void =>{
res.status(statusCode).json({
code: 1,
data,
msg
});
}
}

  

Typescript node starter 3. App Router Controller的更多相关文章

  1. Typescript node starter 2.Router Middleware

    Router 路由器对象是中间件和路由的一个独立实例.可以将它视为一个“迷你应用程序”,仅能够执行中间件和路由功能.每个Express应用程序都有一个内置的应用程序路由器. 路由器的行为类似于中间件本 ...

  2. Typescript node starter 1.Express Typescript

    启动项目 Express 是一个nodejs框架,用于构建Web后端应用程序.它非常的灵活,你可以用你喜欢的方式去使用他.在这个系列文章里,记录了我使用typescript express去构建一个w ...

  3. Cannot declare class app\home\controller\Cases because the name is already in use

    Cannot declare class app\home\controller\Cases because the name is already in use 命名空间冲突了 use 模型类的时候 ...

  4. thinkphp报错Call to undefined method app\index\controller\Index::fetch()

    因为要写一个系统,所以又重新下载了thinkphp,然后安装了一下.回忆起这个问题很容易让新手朋友费解.会出现如下报错:Call to undefined method app\index\contr ...

  5. SAP Netweaver的负载均衡消息服务器 vs CloudFoundry的App Router

    Message server for ABAP Netweaver SAP传统应用经典的三层架构: 起到负载均衡的消息服务器(Message Server)在图中没有得到体现.然后,消息服务器在我们每 ...

  6. 控制器不存在:app\admin\controller\Document

    控制器不存在:app\admin\controller\Document 报错: 控制器不存在:app\admin\controller\Document 但是我在代码里面找了半天没出现Documen ...

  7. Thinkphp6框架学习:($this->error()undefined)Call to undefined method app\index\controller\Admin::error()

    最近在使用Thinkphp6框架的时候,想做一个初始化来验证登录状态. 当没有Session::get(‘adminUid’)的时候就应该跳转到admin\adminLogin的方法中,和以前Tp5的 ...

  8. tp6 控制器不存在:app\index\controller\Index

    tp6 控制器不存在:app\index\controller\Index config/app.php 修改如下 'auto_multi_app' => true,

  9. AngularJS之手动加载模块app和controller

    使用ng的页面中一般都是使用模块自动加载,页面的结构一般是这样的 加载angularjs脚本 加载业务代码脚本(或者写在script标签中) html结构代码(带有ng指令) 就像这样 app.htm ...

随机推荐

  1. React Native 报错 Error: spawn EACCES 权限

    权限不足,运行命令修改权限 chmod android/gradlew

  2. Flutter-Tips

    1.报错:flutter: Another exception was thrown: Could not find a generator for route RouteSettings原因是一个工 ...

  3. ath10k MAC地址

    使用openwrt下ath10k驱动QCA9880修改其MAC地址方式 1. 使用artGUI修改9880寄存器方法(该方法有严重后遗症,目前还没有找到修改回去的方法) 2. 使用preinit修改其 ...

  4. .NET Core + K8S + Loki 玩转日志聚合

    1. Intro 最近在了解日志聚合系统,正好前几天看到一篇文章<用了日志系统新贵Loki,ELK突然不香了!>,所以就决定动手体验一下.本文就带大家快速了解下Loki,并简单介绍.NET ...

  5. pandas之cut

    cut( )用来把一组数据分割成离散的区间. cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_low ...

  6. 【工具】 - BeanUtils增强篇

    public class BeanPlusUtils extends BeanUtils { public static <S, T> List<T> copyListProp ...

  7. postman~界面介绍

    本文摘抄自https://www.jianshu.com/p/b8b02afa74b1 官方文档:https://learning.getpostman.com/docs/postman/launch ...

  8. 牛客练习赛64 如果我让你查回文你还爱我吗 线段树 树状数组 manacher 计数 区间本质不同回文串个数

    LINK:如果我让你查回文你还爱我吗 了解到了这个模板题. 果然我不会写2333... 考试的时候想到了一个非常辣鸡的 线段树合并+莫队的做法 过不了不再赘述. 当然也想到了manacher不过不太会 ...

  9. ios 生成字母加数字的随机数

    文章来自:http://blog.csdn.net/baidu_25743639/article/details/73801700 近期项目第三方登录之后默认创建账号和密码,就用随机数生产,这里只需要 ...

  10. JS 鼠标、键盘事件对象

    鼠标事件对象     mouseEvent鼠标事件对象     e.clientX 在可视区的x和y的坐标     e.pageX 在页面文档的X和Y的坐标 <script> docume ...