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. spring +ActiveMQ 实战 topic selecter指定接收

    spring +ActiveMQ 实战 topic selecter指定接收 queue:点对点模式,一个消息只能由一个消费者接受 topic:一对多,发布/订阅模式,需要消费者都在线(可能会导致信息 ...

  2. SQL Server数据类型对应.Net Core中的数据类型

    SQL C# bigint(sql大小:8byte) long(64位) int, integer(sql大小:4byte) int(32位) smallint(sql大小:2byte) short( ...

  3. APP自动化 -- 获取toast元素的文本内容

    一.toast元素 1.表现形式:toast元素就是下图中  “操作成功” 那个一闪而过的标签. 2.特殊点:因为一闪而过,时间太短,用UIAutomatorView截屏截不到. 二.获取方法 1.用 ...

  4. el-table 操作列(编辑or删除) 获取本行相关数据

    简单说明:开发的时候,经常会遇到表格后面跟着操作列,一般都是编辑或者删除,那么 就需要获取到 本行数据相关的id或者其他附属信息.ok,下边放代码 //vue el-table的部分代码 <el ...

  5. 今天完成了deviceman的程序,压缩成deivceman.rar

    目录在d:\android_projects\deviceman 压成了deviceman.rar 发送到了yzx3233@sina.com

  6. git chechout

    在克隆完一个的版本库时,git会在本地创建一个master分支用于跟踪远端的master分支 如git clone abc.git 默认情况下git会在本地创建一个master分支 但是,在本地mas ...

  7. ls -bash: ls: command not found

    ls -bash: ls: command not found原因:在设置环境变量时,编辑profile文件没有写正确,导致在命令行下 ls等命令不能够识别.解决方案: export PATH=/us ...

  8. Mybatis开启二级缓存(全局缓存)的方法

    Mybatis开启二级缓存的方法 开启步骤 1.在 mybatis-config.xml 的配置文件中进行显示配置,开启二级缓存(全局缓存) 2.在 Mapper.xml 文件中添加cache标签 一 ...

  9. More JOIN operations -- SQLZOO

    The JOIN operation 注意:where语句中对表示条件的需要用单引号, 下面的译文使用的是有道翻译如有不正确,请直接投诉有道 01.List the films where the y ...

  10. PHP password_get_info() 函数

    password_get_info() 函数用于返回指定散列(hash)的相关信息. PHP 版本要求: PHP 5 >= 5.5.0, PHP 7高佣联盟 www.cgewang.com 语法 ...