最近 和别人一块运维 开源 产品,后台需要用到 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/);
});
});
复制代码

 

posted on   小迷瞪  阅读(436)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示