koa返回json数据_Koa-spring:后端太忙,让我自己写服务(下)

98aa019405d84895091f0e8fd94bcb55.png

关于这篇文章

  • 自定义装饰器
  • 继承的应用
  • 涨过的见识
如果你感兴趣,可以fork项目,自己体验一下
Koa-spring:closertb/koa-spring
related-client: closertb/koa-spring-client
技术栈:koa + Sequelize + routing-controllers + typescript
上一篇:Koa-spring:后端太忙,让我自己写服务(上) · Issue #40 · closertb/closertb.github.io

自定义装饰器

去年我特别看好装饰器在前端的发展前景,直到React开始推崇Hooks,并持续大热,这严重压缩了Javascript中类的应用(没记错的话:上一次是函数式编程)。而现阶段的装饰器是依赖于类的,在未来可能这种局面可能会被改变,一种全新的装饰器语法会诞生。还未了解过装饰器的,可以看一下[阮一峰:ES6入门之装饰器](ECMAScript 6入门)

在上一篇文章写到利用中间件来处理那些重复的逻辑,但遗憾的是,不是所有的重复逻辑都适合用中间件来处理。比如上一章讲过Sequelize的查询结果是一个包装过的结构,在赋值成响应体时,需要调用toJson方法或则使用JSON.stringify格式化。开始在查询时设置了{ query: { raw: true }}, 查询的结果没有被包装,比较干净,所以开始是直接使用中间件来处理分页:

async function PaginationMiddleWare(ctx: any, next: (err?: any) => Promise<any>): Promise<any> {
  const { request: { body = {}, query = {} } } = ctx;
  const params = Object.assign({}, query, body);
  const { pn = 1, ps = 10 } = params;
  const data = ctx.body || [];
  const total = data.length || 0;
  const count = pn * ps;
  const isEnough = total > count || total > (pn - 1) * ps;
  ctx.body = {
    datas: isEnough ? data.slice((pn - 1)*ps, total > count ? ps : undefined) : data.slice(0, ps),
    total,
    pn: isEnough ? +pn : 1,
    ps: +ps
  }
  await next();
}

但由于后面意识到这种暴力查询,面对成千上万条数据时,慢的会让人觉得这是个bug;加上对属性getter方法的需求,不得不放弃{ raw:true }这个设置;另外的考虑就是:搜索请求参数的处理。为了不重复写上面的逻辑,所以考虑用装饰器来处理,即先从查询数据获取请求的目标数据(一般分页就10条或20条数据),再对目标数据进行格式化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个使用 Koa + JSON + JWT + Token 的图书管理系统后端服务器的示例代码。 首先,安装必要的依赖: ```bash npm install koa koa-router koa-bodyparser jsonwebtoken uuid ``` 其koaKoa 框架本身,koa-router 是路由模块,koa-bodyparser 是解析请求体的模块,jsonwebtoken 是生成和验证 JWT 的模块,uuid 是生成唯一标识符的模块。 然后,创建一个 index.js 文件,输入以下代码: ```javascript const Koa = require('koa'); const Router = require('koa-router'); const bodyParser = require('koa-bodyparser'); const jwt = require('jsonwebtoken'); const uuid = require('uuid'); const app = new Koa(); const router = new Router(); const books = [ { id: '1', name: 'JavaScript 高级程序设计', author: 'Nicholas C. Zakas' }, { id: '2', name: 'JavaScript DOM 编程艺术', author: 'Jeremy Keith' }, { id: '3', name: 'JavaScript 语言精粹', author: 'Douglas Crockford' }, ]; const secret = 'my-secret'; router.post('/login', async (ctx) => { const { username, password } = ctx.request.body; if (username === 'admin' && password === 'admin123') { const token = jwt.sign({ username }, secret, { expiresIn: '1h' }); ctx.body = { token }; } else { ctx.status = 401; ctx.body = { message: 'Invalid credentials' }; } }); router.get('/books', async (ctx) => { const token = ctx.request.headers.authorization; if (!token) { ctx.status = 401; ctx.body = { message: 'Missing authentication token' }; return; } try { const decoded = jwt.verify(token, secret); ctx.body = { books }; } catch (error) { ctx.status = 401; ctx.body = { message: 'Invalid authentication token' }; } }); router.post('/books', async (ctx) => { const token = ctx.request.headers.authorization; if (!token) { ctx.status = 401; ctx.body = { message: 'Missing authentication token' }; return; } try { const decoded = jwt.verify(token, secret); const { name, author } = ctx.request.body; const id = uuid.v4(); books.push({ id, name, author }); ctx.body = { id }; } catch (error) { ctx.status = 401; ctx.body = { message: 'Invalid authentication token' }; } }); app.use(bodyParser()); app.use(router.routes()); app.use(router.allowedMethods()); app.listen(3000, () => console.log('Server is running on http://localhost:3000')); ``` 该代码实现了以下功能: 1. 登录接口:POST /login,接受用户名和密码,验证成功后返回一个 JWT。 2. 获取图书列表接口:GET /books,需要在请求头带上 JWT,验证成功后返回图书列表。 3. 添加图书接口:POST /books,需要在请求头带上 JWT,验证成功后添加一本图书,并返回该图书的 ID。 这个示例代码是一个比较简单的图书管理系统后端服务器,可以根据实际需求进行修改和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值