写点什么

Nop 入门:极简服务层开发

作者:canonical
  • 2024-01-25
    北京
  • 本文字数:2561 字

    阅读完需:约 8 分钟

Nop 平台的后端服务采用 NopGraphQL 引擎来实现,它的设计相比于 SpringMVC 这种传统的 Web 框架要更加精炼、通用,仅包含数学层面上最小化的假定,通过类似数学的自动推理机制可以实现 SpringMVC 所无法达到的高度可组合性和可复用性。


NopGraphQL 引擎的实现原理可以参考文章: 为什么在数学的意义上GraphQL严格的优于REST?低代码平台中的GraphQL引擎


讲解视频:https://www.bilibili.com/video/BV1EC4y1k7s2/


以下介绍如何集成 spring 框架,并实现一个最简单的后台服务函数。

一. 引入 nop-spring-web-starter 依赖

一般情况下可以选择将 pom 文件的 parent 设置为 nop-entropy 模块,从而自动引入缺省的 maven 配置


<pom>    <parent>        <groupId>io.github.entropy-cloud</groupId>        <artifactId>nop-entropy</artifactId>        <version>2.0.0-SNAPSHOT</version>    </parent>
<dependencies> <dependency> <groupId>io.github.entropy-cloud</groupId> <artifactId>nop-spring-web-starter</artifactId> </dependency> </dependencies></pom>
复制代码

二. 实现 BizModel

NopGraphQL 中的 BizModel 类似于 SpringMVC 中的 Controller,只是它的特殊假定更少,是一种数学意义上的最小化定义。


@BizModel("Demo")public class DemoBizModel {    @BizQuery    public String hello(@Name("message") String message) {        return "Hi," + message;    }
@BizMutation public DemoResponse testOk(@RequestBean DemoRequest request) { DemoResponse ret = new DemoResponse(); ret.setName(request.getName()); ret.setResult("ok"); return ret; }}
复制代码


  1. 在类上增加@BizModel注解,指定后台的服务对象名

  2. 在服务函数上增加@BizQuery或者@BizMutation注解,分别表示无副作用的查询操作和有副作用的修改操作。@BizMutation会指示 NopGraphQL 引擎自动打开数据库事务,确保后台服务函数在事务环境中执行。

  3. 通过@Name注解指定服务函数的参数名。如果参数类型是 JavaBean,则会自动执行 JSON 解析将前台参数转换为对应类型


与 SpringMVC 的 Controller 对比,NopGraphQL 会自动推定很多事情,从而极大降低的系统的不确定性:


  1. 前端的 REST 链接根据对象名和方法名自动推定,而无需手工指定,固定格式为 /r/{bizObjName}__{bizMethod}

  2. @BizQuery允许通过 GET 和 POST 两种 HTTP 方法调用,而@BizMutation只允许通过 POST 方法调用

  3. 通过 GET 方式调用时,可以通过 URL 链接来传递参数,例如/r/Demo__hello?message=abc。通过 POST 方式调用时可以通过 URL 来传参,也可以通过 Http 的 body 使用 JSON 格式传递。

  4. 可以通过@Name来一个个的指定前台参数,也可以通过@RequestBean将前台传递过来的所有参数包装为指定的 JavaBean 类型

  5. 服务函数总是返回 POJO 对象,并指定按照 JSON 格式进行编码


如果参数是可选的,可以使用 @io.nop.api.core.annotations.core.Optional 注解来标记,否则框架会自动校验参数不能为空。

三. 通用错误处理

NopGraphQL 返回到前台的结果对象永远是ApiResponse<T>类型, 但是后台服务函数实现时并不需要像 SpringMVC 那样手工进行包装。


class ApiResponse<T>{    int status;    String code;    String msg;    T data;}
复制代码


  • status=0的时候表示执行成功,不为 0 表示执行失败

  • 失败时通过 code 来传递错误码,通过 msg 来传递国际化后的错误消息。

  • 执行成功的时候通过 data 来返回结果数据,也就是后台服务函数中的返回值。

  • Nop 平台的这种标准返回格式与前端 AMIS 框架所需要的服务返回格式一致。


后端需要把错误信息返回到前台时,直接抛出异常即可


@BizModel("Demo")public class DemoBizModel {
@BizMutation public DemoResponse testError(@RequestBean DemoRequest request) { throw new NopException(ERR_DEMO_NOT_FOUND).param(ARG_NAME, request.getName()); }}
@Locale("zh-CN")public interface DemoErrors { String ARG_NAME = "name";
ErrorCode ERR_DEMO_NOT_FOUND = define("nop.err.demo.not-found", "指定数据不存在: {name}", ARG_NAME);}
复制代码


错误码的定义和使用参见error-code.md

四. 框架中立

SpringMVC 这种框架本质上是一个 Web 框架,很多人在使用时都会不自觉的引入对特定 Web 运行时的依赖,比如使用 HttpServletRequest 和 HttpServletResponse 对象等。


NopGraphQL 强调框架的技术中立性,它仅表达业务逻辑,不依赖任何特定的运行时。即使是下载文件功能,也是通过 WebContentBean 这个 POJO 对象来返回结果,而不是使用 HttpServletResponse 中获取到的输出流。


NopGraphQL 仅使用了/graphql/r/{operationName}等少数几个 Http 端点,可以很容易的运行在任何 Web 运行时环境中,甚至可以自己使用 Netty 编写一个简单的 HttpServer 即可,不需要任何复杂的 Web 标准支持。目前 NopGraphQL 与 Spring 框架集成时底层是使用 SpringMVC 实现 URL 路由,而与 Quarkus 框架集成时是使用 JAXRS 标准注解。


有些人可能对 GraphQL 感到陌生,对于将整个前端迁移到 GraphQL 的调用模式上存在疑虑。NopGraphQL 所强调的信息中立表达的概念,为这种问题提供了一个完美的解决方案:我们通过代码表达的应该是某种技术中立的业务信息,框架可以根据这些技术中立的信息自动推导得到各种技术相关的接口形式。目前,基于 NopGraphQL 框架实现的业务函数,可以自动发布为 REST 服务、GraphQL 服务、Grpc 服务、消息队列服务、批处理服务等。比如说:


  1. 我们可以通过/r/Demo__hello?message=abc这种 REST 接口形式调用 DemoBizModel 类中的 hello 方法

  2. 也可以通过query{ Demo__hello(message:'abc') } 这种 GraphQL 请求来访问同一个服务函数

  3. 如果引入了nop-rpc-grpc模块依赖,NopGraphQL 引擎启动的时候还会自动生成如下 proto 服务定义,使得我们可以通过 grpc 来访问这个服务函数


syntax = "proto3";
package graphql.api;
message Demo__hello_request{ optional string value = 1;}
message Demo__hello_response{ optional string value = 1;}
service Demo{ rpc hello(Demo__hello_request) returns (Demo__hello_response);}
复制代码

五. 查看服务定义

设置了 nop.debug=true 的时候,Nop 平台会以调试模式启动。此时可以访问如下链接来获取所有服务定义:


  1. /p/DevDoc__graphql

  2. /p/DevDoc__beans


发布于: 刚刚阅读数: 3
用户头像

canonical

关注

还未添加个人签名 2022-08-30 加入

还未添加个人简介

评论

发布
暂无评论
Nop入门:极简服务层开发_gRPC_canonical_InfoQ写作社区