简化基于Scala的Web API开发

news2024/12/26 11:09:00

虽然说使用 Scala 语言的语法来写 SpringBoot 微服务已经可以让 Scala 开发者们兴奋不已了,但说实话,这并没有很大程度上发挥二者各自的最大威力。

单向上来讲,从 SpringBoot 微框架出发,Java、Scala 等 Java 虚拟机上的语言都会收益,这只是发挥了 SpringBoot 微框架的最大效能。但反过来,从 Scala 出发,使用 SpringBoot 微框架又会让 Scala 开发者受到一些束缚。

比如像 case class 这样的 Scala 语言特性为了避免序列化兼容性等问题,我们一般不建议使用,但这确是 Scala 提供的最迷人的装备之一,另外,Scala 依赖 Java 的各项生态是很融洽的,但反过来又会因为二进制兼容性等问题感觉如芒在背。

不过,某些特殊的场景下,我们还是可以为 SpringBoot 和 Scala 找到比较恰当的契合点,Web API 就是这样的场景之一。

1)使用 SpringBoot 开发的 Web API 作为微服务独立部署,属于 Endpoints 类型的应用,这种类型的应用因为独立部署和运行,所以可以最大程度上容忍各种兼容性和复杂的“文化理念”,反正有冲突 Endpoint 内部解决,不会外溢到外面给别人带来麻烦。

这不同于类库之类的依赖型(Dependencies)软件实体,它们更多偏组件性质,不能独立“存活”,需要“寄人篱下”,所以,如果它们有一堆自己的关联依赖,那么,就会带来更多兼容性以及冲突解决的负担。所以,作为 Endpoint 类型软件实体的 Web API 微服务,使用 Scala 是可以容忍 Scala 在依赖重和兼容性层面的“缺点”。

2)Web API 对外提供给用户的 API 接口是弱类型的,所以,我们在实现 Web API 期间即使使用各种强类型的对象和语言,其实对用户来说是无感知的,只要做好强类型数据对象和弱类型 API 之间的适配和转换,使用 Scala 的各种语言特性必然无虞。

所以,基于以上两点考虑,我们可以在使用 SpringBoot 开发 Web API 的时候进一步深入使用 Scala 语言的一些特性。

鉴于我们已经实现了一个 spring-boot-starter-webapi 的自动配置模块用于简化 Web API 的开发,要进一步为 Scala 在此场景开辟捷径,只要在原有 spring-boot-starter-webapi 的基础上添加 Scala 特定的一些支持,就可以很大程度上简化基于 SpringBoot 和 Scala 的 Web API 开发。

所以,我们决定创建 spring-boot-starter-webapi-scala 自动配置模块项目,该项目在享有原来 Web API 规范以及 API 文档的支持的同时,将进一步强化在使用 Scala 开发 Web API 的过程中使用 Scala 原生类型(比如 case class)作为数据对象的支持,尤其是 Scala 原生类型的序列化以及 Java 和 Scala 混合类型的序列化。

因为我们的 Web API 最终都是以 JSON 的形式来提供 API 的数据交互,所以,spring-boot-starter-webapi-scala 自动配置模块的主要一个新加功能就是加强 Scala 原生类型和混合类型的 JSON 序列化支持。

基本上,我们会沿用 SpringBoot 在 Web 层 JSON 序列化默认方案上 Jackson 的选型,进一步依赖其 jackson-module-scala(https://github.com/FasterXML/jackson-module-scala)来完成特定于 Scala 对象类型的 JSON 序列化工作。

依然基于 http://start.spring.io 创建我们的 spring-boot-starter-webapi-scala 项目,然后在原有脚手架项目的基础上进行配置裁剪和补足,最终完成项目的 pom.xml 内容类似于:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.keevol.springboot</groupId>
  7. <artifactId>spring-boot-starter-webapi-scala</artifactId>
  8. <version>0.0.1-SNAPSHOT</version>
  9. <packaging>jar</packaging>
  10. <name>spring-boot-starter-webapi-scala</name>
  11. <description>web api boot starter for scala</description>
  12. <parent>
  13. <groupId>org.springframework.boot</groupId>
  14. <artifactId>spring-boot-starter-parent</artifactId>
  15. <version>1.3.3.RELEASE</version>
  16. <relativePath /> <!-- lookup parent from repository -->
  17. </parent>
  18. <properties>
  19. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  20. <java.version>1.8</java.version>
  21. <scala.version>2.11.7</scala.version>
  22. <scala.maven.version>3.2.2</scala.maven.version>
  23. </properties>
  24. <dependencies>
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter-web</artifactId>
  28. </dependency>
  29. <dependency>
  30. <groupId>com.keevol.springboot</groupId>
  31. <artifactId>spring-boot-starter-webapi</artifactId>
  32. <version>1.0.0</version>
  33. </dependency>
  34. <dependency>
  35. <groupId>org.scala-lang</groupId>
  36. <artifactId>scala-library</artifactId>
  37. <version>${scala.version}</version>
  38. </dependency>
  39. <dependency>
  40. <groupId>org.scala-lang</groupId>
  41. <artifactId>scala-compiler</artifactId>
  42. <version>${scala.version}</version>
  43. </dependency>
  44. <dependency>
  45. <groupId>com.fasterxml.jackson.module</groupId>
  46. <artifactId>jackson-module-scala_2.11</artifactId>
  47. <version>2.6.3</version>
  48. </dependency>
  49. <dependency>
  50. <groupId>com.fasterxml.jackson.module</groupId>
  51. <artifactId>jackson-module-paranamer</artifactId>
  52. <version>2.7.1</version>
  53. </dependency>
  54. </dependencies>
  55. <build>
  56. <plugins>
  57. <plugin>
  58. <groupId>org.springframework.boot</groupId>
  59. <artifactId>spring-boot-maven-plugin</artifactId>
  60. </plugin>
  61. </plugins>
  62. </build>
  63. </project>

当前 pom.xml 中有几点内容需要大家重点关注:

  • 添加了原来的 spring-boot-starter-webapi 自动配置模块依赖,目的是继续享有其对 Web API 规范以及 API 文档等功能的支持。
  • 添加了针对 scala-library 和 scala-compiler 的依赖,毕竟这是为 Scala 项目服务的一个自动配置模块项目,这里配置了,所有使用 Scala 开发 Web API 的项目就不需要再逐一配置了。
  • 添加了针对 jackson-module-scala 和 jackson-module-paranamer 的依赖,主要目的是强化针对 Scala 原生类型和混合数据类型到 JSON 序列化支持。

暂时我们不需要提供更多的功能支持,所以,只要通过 mvn install 或者 mvn deploy 将我们的 spring-boot-starter-webapi-scala 项目发布之后就可以供相关开发者使用了。

如果我们对原来实现汇率查询用的 Web API 进行重构,现在的 Maven 构建文件 pom.xml 可以直接简化成如下形式:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.keevol.springboot.chapter5</groupId>
  7. <artifactId>currency-webapi-with-scala</artifactId>
  8. <version>0.0.1-SNAPSHOT</version>
  9. <packaging>jar</packaging>
  10. <name>currency-webapi-with-scala</name>
  11. <description>Demo project for Spring Boot</description>
  12. <parent>
  13. <groupId>org.springframework.boot</groupId>
  14. <artifactId>spring-boot-starter-parent</artifactId>
  15. <version>1.3.1.RELEASE</version>
  16. <relativePath /> <!-- lookup parent from repository -->
  17. </parent>
  18. <properties>
  19. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  20. <java.version>1.8</java.version>
  21. <scala.version>2.11.7</scala.version>
  22. </properties>
  23. <dependencies>
  24. <dependency>
  25. <groupId>com.keevol.springboot</groupId>
  26. <artifactId>currency-rates-service</artifactId>
  27. <version>1.0-SNAPSHOT</version>
  28. </dependency>
  29. <dependency>
  30. <groupId>com.keevol.springboot</groupId>
  31. <artifactId>spring-boot-starter-webapi-scala</artifactId>
  32. <version>0.0.1-SNAPSHOT</version>
  33. </dependency>
  34. <dependency>
  35. <groupId>org.springframework.boot</groupId>
  36. <artifactId>spring-boot-starter-test</artifactId>
  37. <scope>test</scope>
  38. </dependency>
  39. </dependencies>
  40. <build>
  41. <plugins>
  42. <plugin>
  43. <groupId>org.springframework.boot</groupId>
  44. <artifactId>spring-boot-maven-plugin</artifactId>
  45. </plugin>
  46. <plugin>
  47. <groupId>net.alchim31.maven</groupId>
  48. <artifactId>scala-maven-plugin</artifactId>
  49. <version>3.2.2</version>
  50. <executions>
  51. <execution>
  52. <id>compile-scala</id>
  53. <phase>compile</phase>
  54. <goals>
  55. <goal>add-source</goal>
  56. <goal>compile</goal>
  57. </goals>
  58. </execution>
  59. <execution>
  60. <id>test-compile-scala</id>
  61. <phase>test-compile</phase>
  62. <goals>
  63. <goal>add-source</goal>
  64. <goal>testCompile</goal>
  65. </goals>
  66. </execution>
  67. </executions>
  68. <configuration>
  69. <recompileMode>incremental</recompileMode>
  70. <scalaVersion>${scala.version}</scalaVersion>
  71. <args>
  72. <arg>-deprecation</arg>
  73. </args>
  74. <jvmArgs>
  75. <jvmArg>-Xms64m</jvmArg>
  76. <jvmArg>-Xmx1024m</jvmArg>
  77. </jvmArgs>
  78. </configuration>
  79. </plugin>
  80. </plugins>
  81. </build>
  82. </project>

我们现在只要配置针对 spring-boot-starter-webapi-scala 自动配置模块的依赖就可以了,当然,Scala 编译插件 scala-maven-plugin 这里是直接配置当前项目,可以根据前面的思路进一步简化配置。

因为之前是使用 Java 来定义值对象(Value Object),所以,这次我们直接使用 Scala 的 case class 来完成同样目的:

  1. package com.mengma.springboot..vocase class Quote(symbol: String, sell: BigDecimal, buy: BigDecimal)

然后为了演示混合类型到 JSON 序列化的目的,我们在原来的 API 基础上开放一个查询最近 n 条行情的 Web API 接口定义:

  1. ...
  2. @RequestMapping(value = Array("/list"), method =
  3. Array(RequestMethod.GET), produces = Array(APPLICATION_JSON_VALUE))
  4. def listQuote(symbol: String, @RequestParam(required = false) lastN: Int =
  5. 10): WebApiResponse[List[Quote]] = {
  6. // Just a demo, you should retrieve the quotes from your counterparty serivces
  7. // as per the requested currenypair symbol
  8. val quotes = List(Quote("USD/JPY",
  9. BigDecimal("113.94"), BigDecimal("113.96")), Quote("USD/JPY",
  10. BigDecimal("112.94"), BigDecimal("112.96")), Quote("USD/JPY",
  11. BigDecimal("111.94"), BigDecimal("111.96")) )
  12. val
  13. response:WebApiResponse[List[Quote]] = new Web-ApiResponse[List[Quote]]
  14. response.setCode(WebApiResponse.SUCCESS_CODE) response.setData(quotes)
  15. response
  16. } ...

可以看到,我们的 Web API 返回结果混合了 Java 对象类型(WebApiResponse)以及 Scala 对象类型(List 和 Quote),当然,只是实例代码,我们只是构造了模拟的行情数据,实际情况下,大家需要根据上游外汇交易商提供的行情数据进行下发。

最后,为了序列化可以成功,我们需要将 com.fasterxml.jackson.module.scala.DefaultScalaModule 注入 SpringBoot 的应用容器中,从而完成 Scala 类型数据序列化的整个准备工作:

  1. @SpringBootApplication
  2. class ScalaCurrencyWebApiApplication {
  3. // 其他Bean定义...
  4. @Bean def jacksonModuleScala(): Module =
  5. DefaultScalaModule}object ScalaCurrencyWebApiApplication{
  6. def main(args: Array[String]) {
  7. SpringApplication.run(classOf[ScalaCurrencyWebApiApplication], args: _*)
  8. }
  9. }

通过 mvn spring-boot:run 启动我们的 Web API 微服务,访问 http://localhost:8080/list?symbol=USDJPY,即可得到如图 1 所示的结果。


图 1 汇率查询效果示意图

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/71646.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]JAVA毕业设计体育用品购物系统(系统+LW)

[附源码]JAVA毕业设计体育用品购物系统&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术…

神经网络流程图用什么画,神经网络识别流程图解

1、如何通过人工神经网络实现图像识别 人工神经网络&#xff08;Artificial Neural Networks&#xff09;&#xff08;简称ANN&#xff09;系统从20 世纪40 年代末诞生至今仅短短半个多世纪&#xff0c;但由于他具有信息的分布存储、并行处理以及自学习能力等优点&#xff0c;…

【2】AHB协议学习

目录 1、ahb2.0协议:1.1、基本传输1.2 传输类型1.3 突发操作1.4 控制信号1.41 传输方向1.4.2 传输大小1、ahb2.0协议: AHB是为提出高性能可综合设计的要求而产生的AMBA总线。 它是一种支持多总线主机和提高带宽操作的高性能总线。 1.1、基本传输 AHB传输包含两个截然不同的…

远程桌面-系统管理员不允许使用保存的凭据登录远程计算机

当你使用本机 Microsoft RDP 客户端(mstsc.exe)连接到远程 Windows 主机时,可以保存登录凭据,以避免每次都输入这些凭据。你只需要在 RDP 连接窗口中勾选“记住我”选项。在这种情况下,Windows 会将你的远程桌面密码保存到 Windows 凭据管理器。 此外,还有一件更重要的事…

VMware之安装配置CentOS7

安装步骤&#xff1a; 1、打开VMware虚拟机 创建新的虚拟机 2、根据你安装的虚拟机版本选择相应的 Workstation 什么是ISO镜像文件&#xff1f; 1、iso文件只是一个只读文件 2、.iso是电脑上光盘镜像&#xff08;CD Mirror&#xff09;的存储格式之一&#xff0c;因为其是根据I…

【Python游戏】震惊,csdn小编居然用Python实现一个天天酷跑小游戏 | 附源码

前言 halo&#xff0c;包子们上午好 很多小伙伴还记得我们曾经的timi 天天酷跑 嘛 今天小编直接用Python给大家整一个天天酷跑小游戏 真的超级得劲哟 废话不多说&#xff0c;直接上才艺 相关文件 关注小编&#xff0c;私信小编领取哟&#xff01; 当然别忘了一件三连哟~~ 公…

HTML大学班级活动网页设计 、大学校园HTML实例网页代码 、本实例适合于初学HTML的同学

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

Qt 官方示例学习:dragdroprobot

参考链接 Qt开发技术&#xff1a;图形视图框架&#xff08;二&#xff09;场景QGraphicsScene、QGraphicsItem与QGraphicsView详解QGraphicsScene的功能 程序运行效果 要点 模块拆分 界面方面可以分为两个大体&#xff0c;色盘与机器人&#xff1b; 主体界面 使用 QGraph…

破译大脑的黑匣子,离不开这把“钥匙”

得了脑卒中&#xff0c;身体还能恢复如初吗&#xff1f; 这个真实的案例&#xff0c;也许会给很多人带去欣慰。2022年吉林大学第一医院的一位脑卒中患者&#xff0c;从入院到手术完成只用了75分钟&#xff0c;三周后完全康复&#xff0c;回归正常生活。 以计算之力守护生命之光…

聚观早报 | Apple Music推出新功能;苹果汽车最早于2026年发布

今日要闻&#xff1a;苹果Apple Music推出新功能&#xff1b;微软向索尼提供10年游戏协议&#xff1b;Adobe裁员约百人以削减成本&#xff1b;苹果汽车最早于2026年发布&#xff1b;微软考虑开发一款“超级应用”苹果Apple Music推出新功能 12 月 7 日消息&#xff0c;据报道&a…

[附源码]Python计算机毕业设计Django智慧园区运营管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Jetson NX 增加 swap空间

在开启多路测试的时候&#xff0c;发现SWAP空间不够了&#xff0c;板子非常的卡&#xff0c;解决的办法就是增加SWAP空间。 增加空间 生成swapfile文件操作如下 #新增swapfile文件大小自定义 sudo fallocate -l 4G /var/swapfile #配置该文件的权限 sudo chmod 600 /var/swa…

2023中国AIoT产业全景图谱报告发布,小匠物联荣获行业先锋大奖

12月7日&#xff0c;由智次方主办的「中国AIoT产业年会」在深圳成功举办。与会嘉宾包括原国务院参事石定寰、中国工程院院士倪光南、中国工程院院士张平、亚信集团联合创始人田溯宁等各个领域重量级专家。小匠物联作为参展单位&#xff0c;出席本次大会&#xff0c;并获得了年会…

深入理解Linux网络技术内幕(十二)——中断事件一般性参考数据

文章目录前言统计数据通过/proc和sysfs文件系统调整本部分涉及的函数和变量本部分涉及的文件和目录前言 这篇博客的内容不是很多&#xff0c;主要是介绍几种一般性信息&#xff0c;适用于前面所讲涉及中断事件和帧的处理 统计数据 有关帧接收的统计数据保存在各个CPU数组net…

SMOKE模型排放清单处理技术及在多模式下实践应用方法与VOCs排放量核算

【查看原文】SMOKE模型排放清单处理技术及在多模式下实践应用方法与VOCs排放量核算 随着我国经济快速发展&#xff0c;我国面临着日益严重的大气污染问题。近年来&#xff0c;严重的大气污染问题已经明显影响国计民生&#xff0c;引起政府、学界和人们越来越多的关注。大气污染…

嵌入式开发为啥不适合macOS系统?

关注星标公众号&#xff0c;不错过精彩内容作者 | strongerHuang微信公众号 | strongerHuangMac电脑适合做嵌入式开发吗&#xff1f;不定期有小伙伴问我类似的问题&#xff0c;我的回答是&#xff1a;不适合&#xff01;至于为什么&#xff0c;只要你用心观察一下身边做嵌入式软…

入行必看:数字后端工程师有哪些就业机会?

今年高校毕业生人数首破千万&#xff0c;对于即将踏入IC这个行业的应届生来说&#xff0c;今年的就业形势不大乐观。 很多迷茫的同学问了我一些问题&#xff1a; 如果我开始做一名后端工程师&#xff0c;5年后我会做些什么&#xff1f;我能切换到一个设计的工作吗&#xff1f…

数据图表工具-FineReport数字控件

1. 概述 1.1 版本 报表服务器版本 功能变更 11.0 -- 1.2 应用场景 1.2.1 填报控件 填报报表中可以通过该控件输入数字信息&#xff08;整数、负数、小数&#xff09;&#xff0c;录入填报的数据&#xff0c;如下图所示&#xff1a; 1.2.2 参数控件 参数面板处可以通过该…

[附源码]Python计算机毕业设计SSM基于网络C++实验管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

只会用 Go 写 O(N²) 的冒泡排序算法?来看看优化后最好情况下的 O(N) 算法吧

只会用 Go 写 O N 的冒泡排序算法&#xff1f;来看看优化后最好情况下的 O N 算法吧冒泡排序图片演示普通的冒泡排序算法优化算法小结耐心和持久胜过激烈和狂热。 哈喽大家好&#xff0c;我是陈明勇&#xff0c;今天分享的内容是使用 Go 实现冒泡排序算法。如果本文对你有帮助&…