如何搭建一个能快速迭代业务,且稳定的Java 接口服务

         在Java的web开发世界中,spring boot 如今应该是应用最普遍的的了。spring boot要作一个接口服务的底子真的很快,使用maven 引入几个spring boot的starter接能够很快的能够开始写接口了。可是他是个基础框架,它不能保证你写的代码不出错或者少出错。那如何让写的代码更简洁,更少出错呢。这个文章我不想贴代码。由于我知道你们喜欢拿来主义。因此我最后会把脚手架的代码放出来。本篇文章只写我最近一年来不断对一个系统不断重构的实践。前端

一、代码即文档mysql

      写一个接口对spring boot 来讲真的很快。你只须要关心业务就行了。接收请求,返回数据spring都为你作好了。可是写出来的接口要给前端用吧,因此你须要一个强大的接口文档工具。开源的swagger2真的是一个很强大的接口文档生成工具。写代码的同时就把文档写出来了。真正的作到了代码即文档。git

二、写可维护的接口程序员

      什么样的接口是易于扩展的,什么样的接口是易维护的。我实践过程当中发现,不管是什么方法,咱们保证他是无参/单参是最好维护的。无参就不说了,没啥好解释的。为何要单参数,不少人搞不清楚?相信你们都用AOP作过业务,也清楚AOP在接口的调用过程当中拿到的参数是个数组,在代码运行期间,你起的那些参数名其实都是被擦除的,对jvm来讲没有任何实际的意义。为何要单参数是为了保证这种信息不丢失,或者丢失了无影响。可能这么解释仍是一脸懵逼,我为何要保证接口参数名的信息不丢失/丢失了无影响,那我来讲一个具体使用场景你就明白这种设计的好处了。在电商服务中,为了保证一些访问频率高接口的响应,咱们会对这些接口作数据作缓存。怎么作缓存,不是Java小白都知道用AOP加自定义注解来无侵入代码逻辑的方式来作缓存。假设如今咱们在redis中用 PRORDUCT_DETAIL:{productId}来作key对商品的信息进行缓存。如今商品进行下架了或者上架了,你的上下架接口想必是一个,经过传一个productId和saleState来作这件事,若是你把这两个参数分开写了,你通用的AOP逻辑里就没法精准的对哪个商品的缓存进行删除。由于你AOP的逻辑里不知道哪个参数是productId。你就没法作到精准删除。若是你是单参数,你须要把productId,saleState封装成一个Dto类,这样在调用过程当中你的'productId' 这个属性名就不会丢失,你就能够精准的去作自动的缓存失效。这只是一个小的应用场景,更复杂的场景中,多参数合并为对象来传参数,这样的接口若是有业务变更也能更好的扩展。你没必要为要了业务须要多传一个参数的时候须要把全部调用的地方都改动一遍。并且有的上层接口并不必定能拿到你想要的结果,多参的接口会让你在业务改动的时候,牵一发而动全身。github

三、下降本身的工做量,才能高效。web

     在咱们写代码的时候有不少无脑工做须要作,好比你想写一个新增商品的接口。几十个属性。要存到数据库的时候,你须要把传参数的dto转成po,若是你一个个的手写set(get)这不让人崩溃吗?效率奇差不说,并且容易漏啊。不如作个BaseEntity让全部的dto和po来继承的好,BaseEntity提供一个<T> convertTo(Class<T> clazz)来作。经过反射和Spring的BeanUtils来实现一个po的生成,啥你跟说反射的性能低?大家公司缺一个调用100w次多消耗1s的服务器资源吗?追求系统的性能不要矫正过枉。你的服务真的不缺那100w次多出1s的服务器消耗。我相信国内90%的公司的服务器大部分时间都是‘半睡半醒’的状态。真把业务能作到QPS缺这1s再说吧。redis

四、一个适合的ORM框架spring

     ORM框架对Java开发来讲,最有名的莫过于之前是Mybatis/Hibernate . 如今Mybatis/Spring Data JPA。 从我在公司和我本身在家研究不断重构本身的代码来看。我更偏向于Spring Data JPA。说说个人感觉吧!Mybatis框架是个好框架我不否定,可是它须要写sql的特性就表明了开发效率真的不高。而后他有一个插件Mybatis Plus 标准的增删改查都不须要写sql了。却是解决了这种开发效率低问题。可是我依然强烈推荐JPA做为ORM。缘由以下:sql

          (1)、在基础的增删改查上,用Mybatis Plus 和JPA应该差很少,可是JPA的查询返回是Optional能避免不少NullPointException的问题。若是你用的是JDK 11 (增长了不少Optional的方法),使用JPA返回的Optional让你的的代码优美,简洁,不容易出错。数据库

         (2)、写法更简单,Mybatis Plus对属性查询须要构建QueryWapper对象,我的感受很啰嗦。Spring Data的 findByXxx更简洁,多个属性的查询用Example来作更简洁。再复杂点用Query来作也很方便。

         (3)、业务扩张之后更容易迁移,好比开始用的是mysql作数据存储,最后随着数据扩大,须要把数据存储到Mongo/ES中使用Spring Data JPA能让你快速,更小成本的作迁移。

         (4)、mybatis的动态sql很强大,可是我以为它不是一个团队协做好框架。太过自由的方式并不利于代码的质量。团队之中sql水平真的是参差不齐的,项目大了之后不少sql的xml文件也很难维护。写的多错的多,这是亘古不变的道理,一个团队中能把Java代码写好的人,真的不见得sql能写好。

PS:一个完整的电商业务均可以不写一个句SQL 使用 Spring Data全家桶作掉了,我相信只要你熟悉了Spring Data 你会喜欢他的。全部的业务均可以经过设计来避免掉复杂sql 的,若是真复杂到必需要写巨大的sql来作业务,你真的该想一想是否是选错了存储服务。

五、保护你的服务

      安全是一个API稳定的前提,若是今天被别人攻击致使服务宕机,那何谈服务稳定。 jwt+spring-security 是一个很好的套件来作这件事。并且我实践过程当中发现接口分为三足够使用了。不要设计的太过细致,太过细致的设计除了提高系统的维护复杂程度,并无什么卵用。第一类:不须要任何认证就能够访问的接口。第二类:须要C端认证的的接口。第三类:管理员才能访问的接口。用jwt+spring-security这很好实现。

六、监控你的服务

     服务快不快,稳不稳,用数听说话才最有说服力。OpenTracing的一个实现Jaeger在分布式应用中作链路追踪中很是棒。在单应用中也不是没有用武之地。用它来收集你接口的的调用时长,方便作优化仍是很棒的。

七、保证接口统一的输出。异常作统一拦截。我建议每一个接口的返回都应该用同一个ResponseVo。不要把你的异常抛给前端,你给他个500他也处理不了。在他眼里接口只有对错。对了给数据,错了给错误缘由。不要把本身都解决不了的问题抛给别人。还有真的不要把全部的代码bug拦截成‘网络错误‘。怎么就网络错误。这种’甩锅‘的错误缘由你除了给本身增长排查难度。还会让别人骂你。


屁话一大堆,该上代码了

github.com/jarven-he/s…

一、内置了swagger来作文档展现

二、jwt+spring-security来作安全认证。留好了认证的口子,留了个 todo 本身去接入你的帐户系统吧

三、内部有一组API基本上是电商中商品的所有设计。看成demo来给你参照使用。

四、统一错误处理AOP没放在里面。参照本身的业务自行实现。

五、接口跨域的问题也已经处理好了

PS: 有问题欢迎关注 程序员的摸鱼之道 讨论

相关文章
相关标签/搜索