最近 和别人一块运维 开源 产品,后台需要用到 midway框架,所以进行学习。

首先就是midway的搭建,

首先 npm init midway ,初始化项目,选择 koa-v3 template

启动项目 npm run dev,此刻对应后台地址可以访问。

编写Controller

import { Controller,Get } from '@midwayjs/decorator';

@Controller('/')
export class WeatherController{ @Get('/weather')
async getWeatherInfo():Promise<string>{
return "Hello Weather!";
}
}

添加参数处理

import { Controller,Get,Query } from '@midwayjs/decorator';

@Controller('/')
export class WeatherController{
@Get('/weather')
async getWeatherInfo(@Query('id') cityId:string):Promise<string>
{
return cityId;
}
}

编写Service

import { Provide } from '@midwayjs/decorator';
import { makeHttpRequest } from '@midwayjs/core';
import { WeatherInfo } from '../interface'; @Provide()
export class WeatherService{
async getWeather(cityId:string):Promise<WeatherInfo> {
const result = await makeHttpReauest(`http://www.weather.com.cn/data/cityinfo/${cityId}.html`,{
dataType:'json'
});
if(result.state===200){
return result.data;
}
}
}

在service里面 @Provide()是用来注入

在Controller中进行注入

@Inject()

weather:Weather;

weather.controller.ts代码修改如下

import { Controller,Get,Inject,Query } from '@midwayjs/decorator';
import { WeatherInfo } from '../interface';
import { WeatherService } from '../service/weather.service'; @Controller('/')
export class WeatherController{ @Inject()
weatherService:WeatherService; @Get('/weather')
async getWeatherInfo(@Query('cityId') cityid:string):Promise<WeatherInfo>{
return this.weatherService.getWeather(cityid);
}
}

模板渲染

使用view-nunjucks组件

npm i @midwayjs/view-nunjucks --save

安装好组件之后在src/configuration.ts文件中启用组件

 import * as view from '@midwayjs/view-nunjucks';

@Configuration({

  import[view],

       importConfigs:[join(_dirname,'./config')]

})

然后在src/config/config.default.ts中配置组件,指定 nunjucks模板。

import { MidwayConfig } from '@midwayjs/core';

export default{
view:{
defaultViewEngine: 'nunjucks'
}
}

然后在根目录设置模板内容,view/info.html

<!DOCTYPE html>
<html>
<head>
<title>天气预报</title>
<style>
.weather_bg {
background-color: #0d68bc;
height: 150px;
color: #fff;
font-size: 12px;
line-height: 1em;
text-align: center;
padding: 10px;
} .weather_bg label {
line-height: 1.5em;
text-align: center;
text-shadow: 1px 1px 1px #555;
background: #afdb00;
width: 100px;
display: inline-block;
margin-left: 10px;
} .weather_bg .temp {
font-size: 32px;
margin-top: 5px;
padding-left: 14px;
}
.weather_bg sup {
font-size: 0.5em;
}
</style>
</head>
<body>
<div class="weather_bg">
<div>
<p>
{{city}}({{WD}}{{WS}})
</p>
<p class="temp">{{temp}}<sup>℃</sup></p>
<p>
气压<label>{{AP}}</label>
</p>
<p>
湿度<label>{{SD}}</label>
</p>
</div>
</div>
</body>
</html>

然后调整Controller代码,将返回JSON变成模板渲染

主要是用 @midwayjs/koa 里面的Context

this.ctx.render('info',result.weather);

错误处理

定义错误 在src/error/weather.error.ts

import { MidwayError } from '@midwayjs/core';

export class WeatherEmptyDataError extends MidwayError{

  constructor(err?:Error){

    super('weather data is empty',{

      cause:error
    });
    if(err?.stack){       this.stack = err.stack;
    }
  } }

在service代码中进行抛出错误

throw new WeatherEmptyDataError

通过拦截器进行错误处理

在src/filter/weather.filter.ts中进行处理

import { Catch } from '@midwayjs/decorator';

import { Context } from '@midwayjs/koa';

import { WeatherEmptyDataError } from '../error/weather.error';

@Catch(WeatherEmptyDataError)

export class WeatherErrorFilter{

  async catch(err:WeatherEmptyDataError,ctx:context){

    ctx.logger.error(err);
    return '<html><body><h1>weather data is empty</h1></body></html>';
  } }

然后在生命周期ready时候启用filter

在ContainerLifeCycle中的OnReady

里面启用this.app.useFilter([ WeatherErrorFilter ]);

单元测试

import { createApp, close, createHttpRequest } from '@midwayjs/mock';
import { Framework, Application } from '@midwayjs/koa'; describe('test/controller/weather.test.ts', () => { let app: Application;
beforeAll(async () => {
// create app
app = await createApp<Framework>();
}); afterAll(async () => {
// close app
await close(app);
}); it('should test /weather with success request', async () => {
// make request
const result = await createHttpRequest(app).get('/weather').query({ cityId: 101010100 }); expect(result.status).toBe(200);
expect(result.text).toMatch(/北京/);
}); it('should test /weather with fail request', async () => {
const result = await createHttpRequest(app).get('/weather'); expect(result.status).toBe(200);
expect(result.text).toMatch(/weather data is empty/);
});
});

最新文章

  1. javascript的defer和async的区别。
  2. .Net分布式异常报警系统-客户端及服务端API
  3. LightOJ1348 树链剖分
  4. uLua Unity工作机制
  5. linux下source命令的基本功能
  6. Collection_Other
  7. NSString常用方法
  8. centos下配置多个tomcat同时运行
  9. Python:urllib和urllib2的区别(转)
  10. [转]JavaScript函数和数组总结
  11. 彻底理解Java的Future模式
  12. [HNOI 2016]树
  13. 优雅的使用git
  14. 【C++笔记】析构函数(destructor)
  15. WEUI控件JS用法
  16. jQuery中的事件绑定的几种方式
  17. 我发起了一个 .Net 平台上的 直播平台 开源项目 BalaBala
  18. 数据仓库与ODS
  19. Mac下配置Golang环境
  20. (windows下)安装mysql

热门文章

  1. webpack从零开始打造react项目(更新中...)
  2. 不符合Json格式都能被Gson 转成对象使用!!!
  3. 配置中包含maven属性,在idea中本地启动无法正常获取配置
  4. Linux出现Read-only file system错误解决方法
  5. java字符串和图片相互转换
  6. 最好用的 vue v-for直接循环案例
  7. maven-标准目录结构,常用命令,生命周期,概念模型图
  8. windows 系统的端口问题
  9. Java 一次操作多条数据
  10. locust socektio协议压测