Egg 服务 Service

1,049 阅读3分钟

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。

心若有所向往 何惧道阻且长

持续更新中...

系列文章传送门:

简介

上文中我们介绍了 http 中常用的几种请求方式,本文中我们来学习一下 Service,首先我们要知道 Service 是什么? Service 是在复杂业务场景下用于做业务逻辑封装的一个抽象层。那么为什么需要 Service 呢? 因为在实际应用中,Controller 一般不会自己产出数据,也不会包含复杂的逻辑,所以我们就把复杂的过程应抽象为业务逻辑层 Service

好处:

  • 保持 Controller 中的逻辑更加简洁。
  • 保持业务逻辑的独立性,抽象出来的 Service 可以被多个 Controller 重复调用。
  • 将逻辑和展现分离,更容易编写测试用例。

新建Service

  • app 文件下新建 service,在 service 下新建 article.js 文件

  • app/service/article.js 中编写如下代码,可以看出 Service 的命名规范和写法和 Controller 是非常类似的。同样 Service 里的方法也是异步方法,所以要使用 async 关键字

    'use strict';
    
    const Service = require('egg').Service;
    
    class ArticleService extends Service {
      async getArticle(id) {
        // 实际开发此处应该去数据库中查询对应的文章详情
        // const article = await this.ctx.query(`select * from articles where id = ?`, id)
        // 因为没有连接数据库,所以此处使用模拟数据
        const article = {
          id: id,
          title: '尤雨溪都不知道的100个vue小知识',
          content: '这是内容这是内容这是内容这是内容这是内容这是内容',
          author: 'vience'
        }
        return article;
      }
    }
    
    module.exports = ArticleService;
    
  • app/controller/artile.js 中编写获取文章详情的方法 getArticle() 方法,通过 ctx.service.article.getArticle() 调用 service中的 getArticle() 方法。使用严格 GET 模式参数从ctx.params 中获取。

    // 根据id获取文章
    async getArticle() {
      const { ctx } = this;
      const res = await ctx.service.article.getArticle(ctx.params.id);
      ctx.body = res
    }
    
  • app/router.js 中配置上面方法的路由地址

    // 访问路径: http://127.0.0.1:7001/getArticle/0002
    router.get('/getArticle/:id', controller.article.getArticle);
    
  • 使用下面命令运行项目,然后在浏览器中输入 http://localhost:7001/getArticle/0001

    # use npm
    npm run dev
    open http://localhost:7001/
    
    # use yarn
    yarn dev
    open http://localhost:7001
    
  • 效果

    getArticle

注意事项

  • Service 文件必须放在 app/service 目录,可以支持多级目录,访问的时候可以通过目录名级联访问。

    app/service/biz/user.js => ctx.service.biz.user
    app/service/sync_user.js => ctx.service.syncUser
    app/service/HackerNews.js => ctx.service.hackerNews
    
  • 一个 Service 文件只能包含一个类, 这个类需要通过 module.exports 的方式返回。

  • Service 需要通过 Class 的方式定义,父类必须是 egg.Service

  • Service 不是单例,是 请求级别 的对象,框架在每次请求中首次访问 ctx.service.xx 时延迟实例化,所以 Service 中可以通过 this.ctx 获取到当前请求的上下文。

写在最后

关注我,更多内容持续输出

🌹 喜欢就点个赞吧👍🌹

🌹 觉得有收获的,可以来一波 收藏+关注,以免你下次找不到我😁🌹

🌹欢迎大家留言交流,批评指正,转发请注明出处,谢谢支持!🌹