Jmix 中 REST API 的两种实现

你知道吗,在 Jmix 中,REST API 有两种实现方式!

很多应用是采取前后端分离的方式进行开发。这种模式下,对前端的选择相对灵活,可以根据团队的擅长技能选择流行的 Angular/React/Vue 之一,或者前端为App/小程序等手机应用。Jmix 的一种典型应用场景就是作为这种类型应用程序的高级别管理 UI 和后端。为此,Jmix 提供了强大的通用 REST API 功能,支持包括开箱即用的实体、文件、元数据、用户会话的 API 以及经过简单配置就能支持的业务逻辑(服务)REST API。

由于 Jmix 是基于 Spring Boot 框架,因此也支持 Spring 的 RestController。那么对于 Spring 的 REST API 机制和 Jmix 提供机制,究竟有什么不同,而我们在开发时又该如何选择呢?本文将通过具体的代码示例,介绍这两种 API 的区别,相信看完之后,该如何选择您心里应该有数了。

数据模型和服务

我们假设一个简单的场景,为了给用户提供凑单功能,我们在后端写一个服务用于查询低于某个价格的产品( Product),并将满足条件的产品列表返回给客户端。

数据模型

首先我们构建一个简单的 JPA 实体: Product 类,包含名称和价格两个属性:

@JmixEntity
@Table(name = "SLS_PRODUCT")
@Entity(name = "sls_Product")
public class Product {
    @JmixGeneratedValue
    @Column(name = "ID", nullable = false)
    @Id
    private UUID id;

    @InstanceName
    @Column(name = "NAME")
    private String name;

    @Column(name = "PRICE")
    private Double price;

    ... // 其他属性
}

实体通过 Jmix Studio 创建可以选择其他实体特性,比如版本、实体审计、软删除属性等。

服务

可以像普通 Spring Boot 应用那样,自己手动创建一个 @Service 类。也可以通过 Jmix Studio 提供的创建 bean 的功能创建 Service。这里我们用 Jmix Studio 创建一个 Bean,该功能默认创建带 @Component 注解的类,我们手动将类注解修改为 @Service

@Service("sls_ProductService")
public class ProductService {

    @Autowired
    private DataManager dataManager; // 插入代码段时,默认注入带有权限检查的 DataManager

    public List getProductsCheaperThan(Double price){

        // 注意,这里我们并没有对输入参数 price 做检查

        List productList = dataManager.load(Product.class)
                .query("select p from sls_Product p " +
                        "where p.price < :priceInput")
                .parameter("priceInput", price)
                .list();

        return productList;
    }
}

这里的加载实体列表代码,我们通过 Studio 的代码段功能自动添加。

服务中,我们使用了 Jmix 的 DataManager 和 JPQL 查询语句加载实体,并使用方法的输入参数作为 JPQL 的参数。Jmix 的持久层也支持 Spring Data Repository 或者 MyBatis。而使用 DataManager 的一个好处是可以利用 Jmix 的安全机制,控制 API 调用方对实体的访问权限。

Jmix 服务 API

Jmix 服务(Service) API 可以将任意 Spring bean 作为 HTTP 接口开放。Jmix 负责 HTTP 交互,例如,提供 HTTP 响应编码、进行错误处理等。下图是 Jmix 服务 API 的流程图:

Jmix 中 REST API 的两种实现

可以看到,作为应用程序开发者,仅需要编写服务代码。另外,还需做一些配置:

  1. 在项目的 resources 目录添加 rest-services.xml,用于配置可作为 REST API 使用的服务及其方法,内容如下:

  1. 在项目的 application.properties 文件中,设置 jmix.rest.services-config 参数,指定上面配置的 xml 文件:
jmix.rest.services-config = com/abmcode/sales/rest-services.xml

完成这些配置之后,就可以通过 REST 客户端调用了,URL 为 /rest/services/<service_name>/<method_name></method_name></service_name>。例如,通过 Postman 调用:

Jmix 中 REST API 的两种实现

服务 API 会默认使用 Jmix 的安全机制:API 端口需要使用认证 token 进行访问,而且用户需要有访问 REST API 和所查询实体的权限。另外,Jmix 的服务 API 也支持匿名访问

Spring 控制器 API

然后我们再看看 Spring 的 RestController 方式。首先,我们定义一个控制器:

@RestController("sls_ProductController")
@RequestMapping("/products")
public class ProductController {
    @Autowired
    private ProductService productService;

    @GetMapping("priceunder")
    public List getPriceUnder(@RequestParam Double price) throws Throwable {

        if (price < 0) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "价格参数必须大于 0"); // 自定义控制器层的参数检查,抛出请求异常。
        }

        return productService.getProductsCheaperThan(price);
    }
}

Jmix 中的控制器接口默认都是匿名的,但是为匿名用户配置能访问实体信息又不够安全,Jmix 提供了一个应用程序属性,支持使用 Jmix 安全机制对自定义控制器进行保护:

支持逗号分隔的多个 pattern
jmix.rest.authenticatedUrlPatterns=/products/**

然后,重启服务就可以通过 Postman 进行调用。注意,这里的 URL 与服务 URL 不同,直接使用了控制器中定义的路径:

Jmix 中 REST API 的两种实现

结论

通过上面的代码,我们可以看到,在 Jmix 中使用两种类型的 REST API 其实都不复杂,但是,也是各有优势:

Jmix 服务 API

  • 不用编写控制器代码,仅通过 XML 配置即可使用
  • 默认使用 Jmix 的安全机制
  • 可以使用 Fetch plan 定义返回实体的字段

Spring 控制器

  • 更加灵活,可以使用 Spring 控制器自定义 HTTP 状态码、响应类型或者异常错误
  • 除了使用服务层的实体控制外,还可以在控制器层使用自定义的 DTO 对返回实体的信息做进一步控制

因此,在大多数情况下,我们仅使用 Jmix 的服务 API 就能够满足使用要求。针对部分复杂场景可以使用 Spring 控制器 API。

文中使用的 Jmix 版本:1.3.1

Original: https://www.cnblogs.com/abmcode/p/16738772.html
Author: 世开Coding
Title: Jmix 中 REST API 的两种实现

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/616033/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【Spring学习】过滤器和拦截器

    1、认识过滤器(Filter) 1.1、过滤器的定义 过滤器是JavaWeb的三大组件之一,是实现Filter接口的Java类。 过滤器是实现对请求资源(jsp、servlet、h…

    Java 2023年6月5日
    077
  • 日常踩坑_jpa存储时失败,报错SQL Error: 1064, SQLState: 42000错误

    背景交代 使用jpa的save保存对象时,发现死活存不进去,然后报错了SQL Error: 1064, SQLState: 42000错误 然后,机智的我当然是把原生sql粘贴出来…

    Java 2023年6月7日
    081
  • Java基础(标识符,数据类型,数据转换,变量)

    注释 Java中的注释有3种: 单行注释 // 多行注释 /**/ 文档注释 /***/ 注释不会被执行,是给我们写代码的人看的 书写注释是一个非常好的习惯 标识符 Java所有的…

    Java 2023年6月16日
    090
  • 注解和反射

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月7日
    080
  • linux基本命令

    cd 切换文件夹 cd /home 绝对路径 以包目录开头 cd admin 相对路径 不以包目录开头 cd .. 返回上级目录 cd ~ 到自己的家目录 /home/admin …

    Java 2023年6月16日
    077
  • nginx –增加 headers-more-nginx-module

    已经编译好的编nginx需要添加headers-more-nginx-module模块来自定义响应头 1.需要下载headers-more-nginx-module wget ht…

    Java 2023年5月30日
    073
  • Mac VMWare NAT模式安装 CentOS 7-操作教程

    学习大数据离不开 Linux 系统,网络上大部分文章都是在 Windows 系统下使用 VMWare Workstation 安装 CentOS ,并使用 NAT 模式配置网络。本…

    Java 2023年6月16日
    084
  • Spring中属性注入的几种方式以及复杂属性注入详解

    在Spring框架中,属性的注入我们有多种方式,我们可以通过set方法注入,可以通过构造方法注入,也可以通过p名称空间注入,方式多种多样,对于复杂的数据类型比如对象、数组、List…

    Java 2023年6月5日
    0101
  • Windows 常用的快捷键

    键盘功能键 键盘功能键:Tab 、Shift 、Ctrl 、Alt 、空格 、 Enter 、 Window 、 ↑ 、 ↓ 、 ← 、 → *键盘快捷键:全选 、 复制 、 粘贴…

    Java 2023年6月8日
    096
  • VS Code插件

    怎么安装插件? 方法一: 按F1或Ctrl+Shift+p,输入extensions,点击第一个安装扩展就可以 方法二: ctrl + P 然后输入 ext install 方法三…

    Java 2023年6月7日
    0109
  • 自定义博客园主题

    博客园主题代码GitHub地址 https://github.com/yushixin-1024/Cnblogs-Theme-SimpleMemory 该项目Fork自https:…

    Java 2023年6月8日
    0119
  • SpringBoot项目解决全局响应返回中文乱码问题

    一、问题 新建的基于SpringBoot的MVC项目,在请响应体中,如果有中文,会显示为乱码。 二、解决方案 1、在application.properties中设置: Origi…

    Java 2023年5月30日
    065
  • 为什么一定要从DevOps走向BizDevOps?

    数字经济时代,数字化转型成为社会的普遍共识和行动。越来越多的业务运行在数字化基座之上, 软件系统正成为业务创新的价值核心和创新引擎。在这一趋势下,软件产业面临着许多新挑战和新机遇:…

    Java 2023年6月8日
    070
  • Spring是如何解决循环依赖(引用)的?

    首先什么是循环依赖,比如A->B->A,正常我们普通的类怎么解决呢,就是先 new A(),new B() ,然后再 setB,setA ,也比较好解决。 那么大家为什…

    Java 2023年6月5日
    077
  • GBase 8t数据更新

    插入数据 插入元组 insert into &#x8868;&#x540D;(&#x5217;&#x540D;…) values (&#…

    Java 2023年6月9日
    069
  • Java中类变量(静态变量)和类方法(静态方法)

    类变量 类变量也叫静态变量或静态属性,是该类所有对象共享的变量任何一个该类的对象去访问它时,取得都是一样的值 语法: 访问修饰符 static 数据类型 变量名 static 访问…

    Java 2023年6月6日
    089
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球