掌握Spring REST TypeScript生成器

在优锐课的java分享中,讨论了关于Spring REST TypeScript生成器,该生成器创建反映后端模型和REST服务的模型和服务。码了很多干货,分享给大家参考学习。

我注意到网络开发人员创建了TypeScript模型和服务来反映我们的后端模型和REST服务。这是一项乏味的工作。更重要的是,在他们最终反映出我们后端的功能之后,这还不是终点。因为我们总是要牢记在软件开发中很常见的一件事...更改。由于一些新的业务需求,修改了后端服务。该更改迫使前端开发人员重新分析后端服务并重构前端应用程序,以便它们与服务器端匹配。

一段时间后,我开始了Web开发的冒险之旅,并提出了可以基于Java中的类型信息生成所有这些代码的想法。我开始寻找一种TypeScript生成器,该生成器将能够基于REST接口在TypeScript中创建模型和服务。正如我的研究表明的那样,已经有一些库提供了这种功能,但是它们都不能满足我们的所有需求,例如:

  • 支持JavaBean约定。
  • 支持FasterXML / Jackson批注。
  • Spring框架的支持-生成TypeScript服务,可以调用在Spring中开发的REST API。
  • 生成的服务符合Angular和ReactJS的特定要求(Observable或Promises API)。

因此,我们决定启动一个小型的下班时间项目,该项目将提供上述功能。它可以正常工作,我们提出了可以立即使用的解决方案。它已在我们的大多数基于Angular或React的Web应用程序的商业项目中进行了测试和使用。

正如我们的经验所表明的,我们的图书馆带来了巨大的好处。平均生成的代码占Web应用程序代码库的20%,但是就节省的更改和测试工作而言,它是无价的。由于取得了如此可喜的成果,我们公司决定将项目开源。如果你的开发设置在后端使用Spring框架,在前端使用Angular或React,那么你将获得与我们相同的收益。在这篇简短的文章中,我想介绍如何使用我们的spring-rest-2-ts TypeScript生成器进行REST。

例子

为了了解spring-rest2ts生成器的功能,让我们用Java创建一个简单的模型和REST控制器,我们将展示在TypeScript中生成的内容

 1 public class BaseDTO {
 2 
 3     private int id;
 4 
 5     @JsonFormat(shape = JsonFormat.Shape.NUMBER)
 6 
 7     private Date updateTimeStamp;
 8 
 9  }
10 
11 public class OrderDTO extends BaseDTO {
12 
13     private double price;
14 
15     @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
16 
17     private LocalDateTime orderTimestamp;
18 
19 }
20 
21  

Spring REST控制器:

 1 @Controller
 2 
 3 @RequestMapping("api/order")
 4 
 5 public class OrderCtrl {
 6 
 7     @PostMapping(consumes = {"application/json"}, produces = {"application/json"})
 8 
 9     @ResponseBody
10 
11     @ResponseStatus(HttpStatus.CREATED)
12 
13     public OrderDTO createOrder(@RequestBody OrderDTO entity) {
14 
15         return entity;
16 
17     }
18 
19     @RequestMapping(path = "/{id}", method = RequestMethod.GET, produces = {"application/json"})
20 
21     @ResponseBody
22 
23     public OrderDTO getOrder(@PathVariable int id) {
24 
25         return new OrderDTO();
26 
27     }
28 
29 }
30 
31  

TypeScript中,对于DTO类,我们获得了两个具有映射继承的接口,其中每个字段都映射到各自的TypeScript类型:

 1 export interface Base {
 2 
 3     id: number;
 4 
 5     updateTimeStamp: number;
 6 
 7 }
 8 
 9 export interface Order extends Base {
10 
11     price: number;
12 
13     /**
14 
15      *    pattern : dd-MM-yyyy hh:mm:ss
16 
17      */
18 
19     orderTimestamp: string;
20 
21 }

 

如我们所见,如果字段具有Jackson批注,则会将其考虑在内。 如果不是,则其转换基于Java类型到TypeScript的映射。 支持类型名称映射。 在Java中,我们通过提供适当的名称映射器来查看OrderDTO,该映射器会切断后缀DTO,然后我们获得Order类型

可观察的基础服务

模型类的映射非常容易理解。 更有趣的是Spring REST控制器的映射,在TypeScript中,该映射已生成用于调用端点的实现。 这种方法隐藏在方法名称,路径和参数下,因此代码可以抵抗后端的更改。 更重要的是,我们将返回类型转换为选定的Web框架。 对于Angular 2+,有一个生成的有效Angular服务可用于注入:

 1 @Injectable()
 2 
 3 export class OrderService {
 4 
 5     httpService: HttpClient;
 6 
 7     public constructor(httpService: HttpClient) {
 8 
 9         this.httpService = httpService;
10 
11     }

OrderCtrl生成了OrderService。 在这里,类型名称也由类型名称映射器转换。 如果REST API与Web应用程序不在同一主机上,则可以配置baseURL,它可以是整个主机引用的路径前缀

基于承诺的服务

对于使用Promise API生成器的Web框架,正确的配置还能够生成服务类:

 1 export class OrderService {
 2 
 3     baseURL: URL;
 4 
 5     public constructor(baseURL: URL = new URL(window.document.URL)) {
 6 
 7         this.baseURL = baseURL;
 8 
 9     }
10 
11     public createOrder(entity: Order): Promise<Order> {
12 
13         const url = new URL('/api/order', this.baseURL);
14 
15         return fetch(url.toString(), {
16 
17             method: 'POST',
18 
19             headers: {'Content-Type': 'application/json'},
20 
21             body: JSON.stringify(entity)
22 
23         }).then(res => res.json());
24 
25     }
26 
27     public getOrder(id: number): Promise<Order> {
28 
29         const url = new URL('/api/order/' + id + '', this.baseURL);
30 
31         return fetch(url.toString(), {method: 'GET'}).then(res => res.json());
32 
33     }
34 
35 }
36 
37  

组态

由于具有更大的灵活性,因此TypeScript生成器通过代码进行配置。 无需配置文件。 这样就可以在需要的地方轻松扩展发电机。 这是最简单的生成器配置器:

 

 1    Rest2tsGenerator tsGenerator = new Rest2tsGenerator();
 2 
 3     // Java Classes filtering
 4 
 5     tsGenerator.setModelClassesCondition(new ExtendsJavaTypeFilter(BaseDTO.class));
 6 
 7     tsGenerator.setRestClassesCondition(new ExtendsJavaTypeFilter(BaseCtrl.class));
 8 
 9     // Java model classes converter setup
10 
11     JacksonObjectMapper jacksonObjectMapper = new JacksonObjectMapper();
12 
13     jacksonObjectMapper.setFieldsVisibility(JsonAutoDetect.Visibility.ANY);
14 
15     modelClassesConverter = new ModelClassesToTsInterfacesConverter(jacksonObjectMapper);
16 
17     modelClassesConverter.setClassNameMapper(new SubstringClassNameMapper("DTO", ""));
18 
19     tsGenerator.setModelClassesConverter(modelClassesConverter);
20 
21     // Spring REST controllers converter
22 
23     restClassesConverter = new SpringRestToTsConverter(new Angular4ImplementationGenerator());
24 
25     restClassesConverter.setClassNameMapper(new SubstringClassNameMapper("Ctrl", "Service"));
26 
27     tsGenerator.setRestClassesConverter(restClassesConverter);
28 
29     // set of java root packages for class scanning
30 
31     javaPackageSet = Collections.singleton("com.blueveery.springrest2ts.examples");
32 
33     tsGenerator.generate(javaPackageSet, Paths.get("../target/ts-code"));
34 
35  

文章写道这里,感谢大家的观看。如有不足支持,欢迎补充评论。

更欢迎朋友们点赞关注,和我一起细说探讨架构那些事。

猜你喜欢

转载自www.cnblogs.com/youruike1/p/12058308.html