什么是openapi 3.0

OpenAPI 3.0.0 是 OpenAPI 规范的第一个正式版本,因为它是由 SmartBear Software 捐赠给 OpenAPI Initiative,并在2015年从 Swagger 规范重命名为 OpenAPI 规范。

介绍:

OpenAPI 规范(OAS),是定义一个标准的、与具体编程语言无关的RESTful API的规范。OpenAPI 规范使得人类和计算机都能在“不接触任何程序源代码和文档、不监控网络通信”的情况下理解一个服务的作用。如果您在定义您的 API 时做的很好,那么使用 API 的人就能非常轻松地理解您提供的 API 并与之交互了。

如果您遵循 OpenAPI 规范来定义您的 API,那么您就可以用文档生成工具来展示您的 API,用代码生成工具来自动生成各种编程语言的服务器端和客户端的代码,用自动测试工具进行测试等等。

具体请看官方文档

openapi 中文文档 https://openapi.apifox.cn/

swagger openapi3.0官方文档 https://swagger.io/specification/

请大家一定要先看看官方文档,避免下文对于yaml的配置无法理解,也不需要死记,因为平常的配置不会就查文档

swagger https://editor.swagger.io/ 在线查看文档

为什么需要openapi3.0

在以往的项目中,如果项目想要给别人提供api文档的话,有二种方法,

一种就是项目集成swaager ,然后通过注解的方式来生成对方可访问的api文档,在与前端对接的时候提供便利

优点: 提供了对外可访问的api

缺点:对代码有严重的侵入式,不可维护,需要在控制层写很多不必要的代码

框架代表: swagger2.0, knife4j

代码示例:

加入配置:

 @Bean(value = "defaultApi2")public Docket defaultApi2() {Docket docket=new Docket(DocumentationType.SWAGGER_2).apiInfo(new ApiInfoBuilder()//.title("swagger-bootstrap-ui-demo RESTful APIs").description("# swagger-bootstrap-ui-demo RESTful APIs").termsOfServiceUrl("http://www.xx.com/").contact("1796789910@qq.com").version("1.0").build())//分组名称.groupName("2.X版本").select()//这里指定Controller扫描包路径.apis(RequestHandlerSelectors.basePackage("com.example.springbootknife4jintegrate.controller")).paths(PathSelectors.any()).build();return docket;}

控制层需要加入更多注解

 @ApiImplicitParam(name = "name",value = "姓名",required = true)@ApiOperation(value = "例子")@ApiOperationSupport(author = "1796789910@qq.com")

并且需要加入一些配置,这对于开发来说,非常难受.

第二种.由开发手动去编写接口文档提供外部访问

例如 小幺鸡,yapi, apifox 他们都可以提供在线访问的接口地址,但是,需要开发人员手动去填写,严重耽误开发进度

新型开发模式如何解决

先看下项目架构图

api与业务系统节藕开,api服务只设计接口,提供对外访问的api文档,业务系统负责实现API接口.

优点:

1.节藕合:业务系统不需要去写一些不必要的配置,以及注解.

2.安全:所有的接口权限是一个服务,对api的控制更加高效

3.开发高效,开发先设计接口,然后先把接口文档给到前端,随后在开发,双方无需等待

4.对于开发来说,先定义清楚接口,对于业务逻辑更加清晰,避免反工

架构实现

1.api服务

新建一个springboot项目增加以来配置

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.2</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>spring-boot-openapi-integrat</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-boot-openapi-integrat</name><description>spring-boot-openapi-integrat</description><properties><openapi.generator.version>5.2.0</openapi.generator.version><openapi.package>com.openapi</openapi.package>//jdk版本在11或更高版本<maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- spring web 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>jakarta.validation</groupId><artifactId>jakarta.validation-api</artifactId><version>2.0.2</version></dependency><dependency><groupId>org.openapitools</groupId><artifactId>jackson-databind-nullable</artifactId><version>0.2.1</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>3.0.0</version></dependency><dependency><groupId>io.swagger</groupId><artifactId>swagger-annotations</artifactId><version>1.5.22</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-deploy-plugin</artifactId><version>3.0.0-M1</version><configuration><updateReleaseInfo>true</updateReleaseInfo></configuration></plugin><plugin><groupId>org.openapitools</groupId><artifactId>openapi-generator-maven-plugin</artifactId><version>${openapi.generator.version}</version><executions><execution><id>open</id><goals><goal>generate</goal></goals><configuration><!-- API specifications should be split to multiple YML files, when the feature is implemented:https://github.com/OpenAPITools/openapi-generator/issues/6379 -->//api定义的yml文件所在 <inputSpec>${project.basedir}/src/main/resources/openapi.yaml</inputSpec><generatorName>spring</generatorName><apiPackage>${openapi.package}.open.controller</apiPackage><modelPackage>${openapi.package}.open.controller.model</modelPackage><supportingFilesToGenerate>ApiUtil.java</supportingFilesToGenerate><modelNamePrefix>Open</modelNamePrefix>//如果api定义为 /users 或者 /oders 那么这里要加上对于的路径 order 否则无法生成对应的api接口<apisToGenerate>users</apisToGenerate><configOptions><delegatePattern>true</delegatePattern></configOptions></configuration></execution></executions></plugin></plugins></build>
</project>

添加配置文件: openapi.yaml 名称可以随便命名,不过pom.xml哪里也需要修改

配置就只能自己去看官方文档了或者如果实在不知道的,就访问 https://editor.swagger.io/ 地址

里面会有一些案例,复制下来,放到yaml文件中

自己防着来一下就好了

我贴上我的例子吧:

openapi: 3.0.3
info:title: SpringBoot Open APIsdescription: SpringBoot Open APIsversion: 1.0.0-SNAPSHOT
externalDocs:description: Check the source code hereurl: https://gitee.com/xxx/spring-boot-integrate
servers:- url: http://localhost:8080/v1description: LOCAL Environmentvariables:env:default: devenum:- dev    # DEVELOPMENT ENVIRONMENT- gamma  # GAMMA ENVIRONMENT- url: http://localhost:8080/v1description: applicationion Environment URLpaths:/users:get:summary: '检索用户'description: '检索帐号下所有用户信息'operationId: ListUsersparameters:- $ref: '#/components/parameters/IndexParam'- $ref: '#/components/parameters/LimitParam'- name: namedescription: '用户名'in: queryschema:type: stringminLength: 2maxLength: 255- name: keyworddescription: '模糊搜索'in: queryschema:type: stringresponses:'200':description: '用户列表'content:application/json:schema:$ref: '#/components/schemas/UserList''500':$ref: '#/components/responses/Fault'default:$ref: '#/components/responses/Error'post:summary: '添加用户'description: '添加用户信息'operationId: CreateUserrequestBody:content:application/json:schema:$ref: '#/components/schemas/CreateUserRequest'responses:'201':description: '创建用户成功'content:application/json:schema:$ref: '#/components/schemas/User''500':$ref: '#/components/responses/Fault'default:$ref: '#/components/responses/Error'/users/{id}:delete:summary: '删除用户'description: '删除用户信息'operationId: DeleteUserparameters:- name: idin: pathschema:type: stringrequired: trueresponses:'200':description: '删除用户成功''500':$ref: '#/components/responses/Fault'default:$ref: '#/components/responses/Error'put:summary: '更新用户'description: '更新用户信息'operationId: UpateUserparameters:- name: idin: pathschema:type: stringrequired: truerequestBody:content:application/json:schema:$ref: '#/components/schemas/UpateUserRequest'responses:'200':description: '更新用户成功'content:application/json:schema:$ref: '#/components/schemas/User''500':$ref: '#/components/responses/Fault'default:$ref: '#/components/responses/Error'
components:securitySchemes:ApiKeyAuth: # arbitrary name for the security schemetype: apiKeyname: Authorization   # name of the header, query parameter or cookiein: header                  # can be "header", "query" or "cookie"schemas:UpateUserRequest:type: objectproperties:name:description: '用户的名称'type: stringminLength: 2maxLength: 64remark:description: '用户备注'type: stringCreateUserRequest:type: objectproperties:name:description: '用户的名称'type: stringminLength: 2maxLength: 64remark:description: '用户备注'type: stringUserList:description: '用户列表'type: objectproperties:users:description: '用户列表'type: arrayitems:$ref: '#/components/schemas/User'pagination:$ref: '#/components/schemas/Pagination'User:description: '用户'type: objectproperties:id:description: '用户的唯一标识'type: stringname:description: '用户的名称'type: stringminLength: 2maxLength: 64remark:description: '用户备注'type: stringPagination:description: '分页'type: objectproperties:index:type: integerdescription: '当前页'limit:type: integerdescription: '每页数量'total:type: integerformat: int64description: '总数'Error:type: objectproperties:error:allOf:- $ref: '#/components/schemas/ErrorBody'- type: objectproperties:details:type: arrayitems:$ref: '#/components/schemas/ErrorBody'required: [ error ]Fault:type: objectproperties:fault:type: objectproperties:code:type: stringdefault: "InternalFault"message:type: stringdefault: "服务内部错误, 请联系管理员"ErrorBody:type: objectproperties:code:type: stringid:type: stringmessage:type: stringtarget:type: stringrequired: [ code, id, message ]parameters:IndexParam:name: indexin: querydescription: "当前页"schema:type: integerminimum: 1default: 1LimitParam:name: limitin: querydescription: "每页数量"schema:type: integerdefault: 10

里面定义了用户的一些基本操作.

定义好了之后,我们使用maven的命令来生成对应的代码

mvn clean compile package

如果成功的话,会在对应的项目中生成一个target目录,里面的class 目录里面就对应生成的接口了

完整的项目图

说明api服务以及搭建成功了,接下来我们需要搭建服务层.

2.业务服务

还是一样新建一个springboot服务

Pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.5</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>spring-boot-api-service-integrat</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-boot-api-service-integrat</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>com.example</groupId><artifactId>spring-boot-openapi-integrat</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version><scope>provided</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

请注意,增加了一个api服务的依赖 spring-boot-openapi-integrat 这是我们刚刚新建的api服务

控制层

/*** 实现生成的接口,然后实现对应的服务既可*/
public class UsersApiDelegateImpl implements UsersApiDelegate {private final UserService userService;private final UserConversion userConversion;public UsersApiDelegateImpl(UserService userService,UserConversion userConversion) {this.userService = userService;this.userConversion = userConversion;}@Overridepublic ResponseEntity<OpenUser> createUser(OpenCreateUserRequest openCreateUserRequest) {User user = this.userService.createUser(this.userConversion.toUser(openCreateUserRequest));return ResponseEntity.status(HttpStatus.CREATED).body(this.userConversion.toControllerOpenUser(user));}@Overridepublic ResponseEntity<Void> deleteUser(String id) {this.userService.deleteUser(id);return ResponseEntity.ok().build();}@Overridepublic ResponseEntity<OpenUser> upateUser(String id, OpenUpateUserRequest openUpateUserRequest) {User user = this.userService.upateUser(id, this.userConversion.toUser(openUpateUserRequest));return ResponseEntity.status(HttpStatus.CREATED).body(this.userConversion.toControllerOpenUser(user));}
}

这里实现了api服务生成的接口,然后,在控制层去实现对应的接口就好了,

转换层

一般来说,控制层传递的对象需要专程 model 层,然后才能在 service层进行服务操作开发,然后在操作数据库的时候需要转换为数据库层对应的实体,这样子做的好处是隔离.

代码示例:

@Component
public class UserConversion {public User toUser(OpenCreateUserRequest openCreateUserRequest){return new User().setName(openCreateUserRequest.getName()).setRemark(openCreateUserRequest.getRemark());}public User toUser(OpenUpateUserRequest openUpateUserRequest){return new User().setName(openUpateUserRequest.getName()).setRemark(openUpateUserRequest.getRemark());}public OpenUser toControllerOpenUser(User user){if(user == null) return  null;return new OpenUser().id(String.valueOf(user.getId())).name(user.getName()).remark(user.getRemark());}
}

启动项目,如果我们想添加用户的话请求

http://localhost:8080/v1/users post

其他请求同理,

总结

Open3.0 开发模式不仅仅是对于开发来说,对于整个公司都是有利的,开发的api逻辑清晰,前端对接高效,每个字段都有注释

统一的result api风格,对外提供api更加便捷,好了文章介绍就到这里了,喜欢的同学给作者点个关注,谢谢.

OPENAPI3.0 与 SpringBoot 开发实战: 新型高效开发模式,实现代码与API分离,高效开发,开发必看!!!相关推荐

  1. Xamarin iOS开发实战上册-----2.2.2 使用代码添加视图

    Xamarin iOS开发实战上册-----2.2.2  使用代码添加视图 如果开发者想要使用代码为主视图添加视图,该怎么办呢.以下将为开发者解决这一问题.要使用代码为主视图添加视图需要实现3个步骤. ...

  2. 微信小游戏开发实战教程14-闯关模式的实现

    这是微信小游戏开发实战系列的第14篇. 本文主要内容是介绍精致1010闯关模式的设计和实现思路. 如果你没有任何的游戏开发经验,欢迎阅读我的"人人都能做游戏"系列教程,它会手把手的 ...

  3. 【Go API 开发实战 1】该教程所实现的 API 功能

    本教程所实现的 API 功能 本教程通过实现一个账号系统,来演示如何构建一个真实的 API 服务器,构建方法和技术是我根据之前的服务器开发经验不断优化沉淀而成.通过实战展示了 API 构建过程中各个流 ...

  4. 在线客服系统源码开发实战总结:需求分析及前端代码基本技术方案

    在这个系列文章里,我尝试将自己开发唯一客服系统(gofly.v1kf.com)所涉及的经验和技术点进行梳理总结. 文章写作水平有限,有时候会表达不清楚,难免有所疏漏,欢迎批评指正 该系列将分成以下几个 ...

  5. 高效背诵面试题、回答问题的技巧,求职者必看!

    程序员们在进行面试的时候肯定会被问道很多技术题目,提前看面试题是一个非常好的帮助,但苦于自己记不住回答不上来.这里小千就总结了一下面试题回答技巧,帮助大家更好的记忆和回答问题,废话不多说下面上货了~ ...

  6. 阿里云物联网平台python开发手册_阿里云物联网平台之云端API调用(即云端开发教程)...

    本文介绍如何调用物联网平台的云端API,很多时候控制台上操作不太方便,需要通过API调用来完成或者通过调用API封装接口,以做到二次开发等.如产品管理,设备管理,规则创建等.分别介绍通过common ...

  7. Android Studio App开发入门之在活动之间传递消息(附源码 超详细必看)(包括显示和隐式Intent,向上一个和下一个Activity发送数据)

     运行有问题或需要源码请点赞关注收藏后评论区留言~~ 显示Intent和隐式Intent Intent是各个组件之间的信息沟通的桥梁,既能在Activity之间沟通,又能在Activity与Servi ...

  8. 视频教程-FFmpeg音视频开发实战6 iOS/Android/windows/Linux-其他

    FFmpeg音视频开发实战6 iOS/Android/windows/Linux 先后就职于德国BOSCH,iBabyLabs等企业担任架构设计师,主程, 精通嵌入式Linux,iOS,Android ...

  9. [原创].NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(前篇)...

    .NET 业务框架开发实战之十 第一阶段总结,深入浅出,水到渠成(前篇) 前言:这个系列有段时间没有动了.主要是针对大家的反馈在修改代码.在修改的过程中,也有了一些新的体会,这里和大家分享一下,同时也 ...

最新文章

  1. 69:shell脚本介绍 | shell脚本结构 | 执行data命令用法 | shell脚本中变量
  2. Delphi 2010 refactor / refactoring 重构不能使用的原因以及解决
  3. 16、IN和NOT IN用法详解
  4. Java 第7章 数组
  5. 深入探讨!Batch 大小对训练的影响
  6. 五分钟学会企业的OpenStack(T版)——简介及安装方式
  7. 心动网络:PolarDB助力心动网络打造爆款手游
  8. Web PostMessage
  9. huffman算法c语言程序,哈夫曼算法构造代码
  10. 接口与继承:不允许继承的类
  11. java开发常用的linux命令,Java开发中最常用的Linux命令整理
  12. 2022机修钳工(中级)特种作业证考试题库模拟考试平台操作
  13. 离散数学知识点及错题集合 第七章
  14. afuwin64教程_AMI刷BIOS工具下载|AFUWIN(AMI刷BIOS工具) v4.47官方最新版 附使用教程_星星软件园...
  15. 行业缩减他却增加!海尔智家研发投入创新高
  16. 不同RAID硬盘利用率参考
  17. STM32单片机语音声控智能台灯可调光冷暖光人检测锂电池供电太阳能和USB充电
  18. 理想电流源与理想电压源
  19. 【日记】20220219启动项目蓝屏
  20. Oracle基础学习

热门文章

  1. roguelike2d 摄像机参数设置
  2. react----元素的在窗口范围内的拖动(react-rnd)
  3. 杂项题(MISC)和web安全题【1】
  4. Facebook股价跌破20美元 这些股东早已抛售股票 包括扎克本人
  5. 巴菲特旗下公司持有470亿美元苹果股票 他用的却是20美元的三星翻盖机
  6. 北理计算机学院2005年机试真题
  7. 李开复:我的大学生活琐忆
  8. 面试时谁都紧张,但我有诀窍!
  9. c# 方法参数 传值or传引用?(ref,out,可变参数params,可选参数,命名参数)
  10. Adobe欲统一相机RAW格式的格式——DNG数码负片_我是亲民_新浪博客