一、GraphQL

  最近服务端的同事分享了GraphQL,他分享的目的就是要把我们与他们的数据库隔离,这么做我们也求之不得。

  我们组目前维护着一个后台管理系统,会直接读取数据库中的表,如果能隔离的话,就不需要写Model文件了。

  后面再进一步了解后,明白了服务端推这个GraphQL的用意,其实就是让我们自己去维护GraphQL服务,包括客户端也去自己维护。

  那这和我直接读取数据库做路由,区别不是很大了,无法解决当前我们的痛点,而且我在前端页面中还需要制定数据结构,比之前还多了一步。

  况且如果需要缓存的话,还不能直接调用GraphQL的接口。如果我们人员充沛的话,这么分一点问题都没有,但是现在人员非常紧张。

  我们还要花大精力做数据整合和处理,而前端常规的工作诸如性能优化、页面交互、组件化、工程化等都没时间深入研究。基于此,还得另辟蹊径。

二、通用接口

  由于后台管理系统大部分的操作都是增删改查(数据库基于MySQL,ORM基于Sequelize),所以可以抽象出一套这类的通用接口,从而就能避免在 Router 和 Service 两层中新增不必要的文件。

  • api/get:读取一条数据(单表查询)

  • api/gets:读取多条数据(单表查询)

  • api/head:读取聚合数据,例如count()、sum()、max()和min()

  • api/post:提交数据,用于增加记录api/put:更新数据

  这套接口的研发受到了 APIJSON 这套开源项目的启发。

  数据库表都是单表查询,不支持联表,若要联表则单独创建接口。查询条件的语法直接参照 Sequelize,没有做单独的语法编译。

  由于接口的参数是一个JSON格式的对象,因此全部采用 post 的请求方式(Content-Type: application/json)。

  以 api/get 为例,基于KOA框架,在 Service 层的方法是:

  /**
* 数据库查询一条记录
*/
async getOne(tableName, where={}) {
return this.models[tableName].findOne({
where,
raw: true
});
}

  在 Router 层的方法是:

  /**
* 读取一条记录
* {
* TableName : { 查询条件 }
* }
* TableName是Model文件的名称,并非数据库表名
*/
router.post('/get',
async (ctx) => {
const { body } = ctx.request;
const tableName = Object.keys(body)[0]; //表名
const where = body[tableName]; //查询条件
// 将表名和查询条件传递给数据库方法
const data = await services.common.getOne(tableName, where);
ctx.body = { code: 0, data };
});

  其中 TableName 是服务端中Model的文件名(并非数据库中的表名),对象中的字段都是SQL的查询条件。

  粗略估算一下,如果将管理系统的接口替换成通用接口,那么可节省至少450个接口,占总接口的40%左右,并且 Service 中的方法也会大大减少。

  已将通用接口的前端代码整合到 shin-admin 中,后端代码整合到 shin-server 中。

Node.js躬行记(8)——通用接口的更多相关文章

  1. Node.js躬行记(2)——文件系统和网络

    一.文件系统 fs模块可与文件系统进行交互,封装了常规的POSIX函数.POSIX(Portable Operating System Interface,可移植操作系统接口)是UNIX系统的一个设计 ...

  2. Node.js躬行记(4)——自建前端监控系统

    这套前端监控系统用到的技术栈是:React+MongoDB+Node.js+Koa2.将性能和错误量化.因为自己平时喜欢吃菠萝,所以就取名叫菠萝系统.其实在很早以前就有这个想法,当时已经实现了前端的参 ...

  3. Node.js躬行记(12)——BFF

    BFF字面意思是服务于前端的后端,我的理解就是数据聚合层.我们组在维护一个后台管理系统,会频繁的与数据库交互. 过去为了增删改查会写大量的对应接口,并且还需要在Model.Service.Router ...

  4. Node.js躬行记(23)——Worker threads

    Node.js 官方提供了 Cluster 和 Child process 创建子进程,通过 Worker threads 模块创建子线程.但前者无法共享内存,通信必须使用 JSON 格式,有一定的局 ...

  5. Node.js躬行记(1)——Buffer、流和EventEmitter

    一.Buffer Buffer是一种Node的内置类型,不需要通过require()函数额外引入.它能读取和写入二进制数据,常用于解析网络数据流.文件等. 1)创建 通过new关键字初始化Buffer ...

  6. Node.js躬行记(6)——自制短链系统

    短链顾名思义是一种很短的地址,应用广泛,例如页面中有一张二维码图片,包含的是一个原始地址(如下所示),如果二维码中的链接需要修改,那么就得发代码替换掉. 原始地址:https://github.com ...

  7. Node.js躬行记(15)——活动规则引擎

    在日常的业务开发中,会包含许多的业务规则,一般就是用if-else硬编码的方式实现,这样就会增加逻辑的维护成本,若无注释,可能都无法理解规则意图. 因为一旦规则有所改变,那么就需要修改代码再发布代码, ...

  8. Node.js躬行记(19)——KOA源码分析(上)

    本次分析的KOA版本是2.13.1,它非常轻量,诸如路由.模板等功能默认都不提供,需要自己引入相关的中间件. 源码的目录结构比较简单,主要分为3部分,__tests__,lib和docs,从名称中就可 ...

  9. Node.js躬行记(21)——花10分钟入门Node.js

    Node.js 不是一门语言,而是一个基于 V8 引擎的运行时环境,下图是一张架构图. 由图可知,Node.js 底层除了 JavaScript 代码之外,还有大量的 C/C++ 代码. 常说 Nod ...

随机推荐

  1. 使用docker搭建最新版本的gitea,并配置HTTPS访问

    使用docker搭建最新版本的gitea,并配置HTTPS访问 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 简介 之前有搭建 ...

  2. 7.7、深入解析openstak工作流程

    1.openstack的使用: (1)使用openstack创建的用户默认是default域,角色是user; (2)域-->角色-->用户-->项目 (3)配额在管理员登录后再项目 ...

  3. springBoot-Quartz快速入门

    springBoot-Quartz快速入门 开发环境 JDK1.8.Maven.Idea 技术栈 SpringBoot 2.1.6.quartz 2.3.0等 数据库准备 说明:数据库脚本由Quart ...

  4. 安卓手机改造服务器——基本环境配置(CentOS7 arm32)

    安装好CentOS系统之后,我们需要对环境进行一些基本的配置,让Linux更好用 写在前面 注意:本文章是针对arm32的CentOS7进行配置的,其他系统或不同架构不要尝试. 配置yum镜像源 1. ...

  5. DRF之过滤排序分页异常处理

    一.过滤 对于列表数据要通过字段来进行过滤,就需要添加 django-filter 模块 使用方法: # 1.注册,在app中注册 settings.py INSTALLED_APPS = [ 'dj ...

  6. SpringCloud:feign对象传参和普通传参及遇到的坑

    对象传参: #使用@RequestBody来指定传参对象 @RequestMapping(value = "/v2/matterCode/genCode", method = Re ...

  7. 1.3.5、通过Method匹配

    server: port: 8080 spring: application: name: gateway cloud: gateway: routes: - id: guo-system4 uri: ...

  8. 深入理解Java容器——HashMap

    目录 存储结构 初始化 put resize 树化 get 为什么equals和hashCode要同时重写? 为何HashMap的数组长度一定是2的次幂? 线程安全 参考 存储结构 JDK1.8前是数 ...

  9. Django基础009--Paginator分页

    1.引入 from django.core.paginator import Paginator 2.Paginator对象提供的方法 articles = models.Article.object ...

  10. python 元组推导式

    >>> b=(page for page in range(10))>>> print(b)<generator object <genexpr> ...