后端开发:如何写出可靠的接口
发布时间 - 2019-06-26 00:00:00 点击率:次毕业进入现在的公司已近一年,完整参与了部门新项目两期的开发上线过程,作为一名后端开发,觉得最痛苦的是上线前和上线后的改 bug 阶段,面对各种突如其来、莫名其妙的bug,头昏脑涨、手忙脚乱、越改越懵,经常导致实验式改 bug、改一个 bug 又出现
俩 bug 的之类的惨剧,我就忍不住想,为什么每次上线前都会有这么多bug呢?
前几天还读到一篇豆瓣文章,没有总结的就不是经验,只是经历。程序员也不能业务来了就写代码,有bug了就改bug,这样技术很难提升,也就难怪每次都会有那么多bug了。有的开发人员工作多年,接口还是时不时500,前期忙着写代码,后期忙着改bug,心累。
我从一期熟悉业务、框架,写一写边缘接口,到二期负责一个小模块,尝试数据库、程序的设计,中间磕磕绊绊,昨天也顺利上线,模模糊糊也感觉到了一些经验,于是努力总结下,虽然简单,也许能给自己和读者一些启发。(本文只针对初级水平,简单的bug,不涉及高并发、海量数据等复杂问题)
一. 接口为什么出bug?
辛辛苦苦写的接口,自己测的时候好好的,怎么别人一调就出错了呢??(此处应有表情包,请自行脑补)当然可能是运行环境的问题,不过程序统一部署在服务器上,这一般是架构师或者运维负责的工作,至于编程语言或者操作系统的问题,也通通不在今天考虑范围内,今天,我们只考虑自己写出的bug。
事实上,运行中的程序所涉及的,无非三样:资源(cpu、内存等)+ 算法(程序运行流程)+ 数据(用户输入、数据库、第三方接口等)。通常我们认为资源是可靠的,出现bug主要是由于算法的不可靠或者数据的异常。
更进一步,机器严格按照0/1执行指令,算法上一次执行正常,为什么这一次会失败?本质上还是因为数据变了,而算法没能覆盖此情况,因此,要想保证接口的稳定,主要从两方面考虑:保证数据的可靠性、算法的健壮性,而算法的健壮性也就是考虑到数据的各种情况,两者密不可分。
二. 如何写出bug更少的接口?
如前分析,数据的变化是接口bug最常见、本质的原因。而其中,用户输入又是数据变化最主要的原因。而程序必然要有用户输入,否则毫无意义。
编程界有句名言:永远不要相信用户输入。你永远不知道,用户会在一个期待姓名的输入框里都输入些什么。不要因为前端做了过滤你就放心,一方面是用户可能会使用爬虫等手段直接访问你的接口,另一方面,前端也是你的用户,沟通也存在误差,前端可能会使用错误的方式调用你的接口,而这种错误可能会更加隐蔽。
第一条建议:严格校验用户的输入,包括格式、内容。
我知道很多人都懒得去逐条检验用户输入,觉得只要功能正常就ok了,但是,这经常会导致后期改bug时投入更多的经历。经常测试提了bug,你查来查去,发现是前端传错了参数,或者没有合理限制用户输入,当然你可以很刚,让前端去改,但这个过程已经浪费了你大量的时间精力,还不如一开始自己做好检验,返回合适的错误消息,会为你后期节省大量的精力。
对于PHP等动态语言,尤其如此,例如我们使用Laravel框架,我会在所有接口入口处,首先使用$request->validate()检验所有输入数据的格式,如有必要,还会写代码进一步校验输入内容,比如时间范围、请求数据是否有效等等。
第二条建议:考虑用户的骚操作,重复提交、延时提交
重复提交应该是大多数后端都能想到的情况,也就是接口的幂等性,有些资源只能操作一次,必须进行校验,其实不仅是重复提交,还包括同一事件被两人重复处理的情况。
而对于延时提交,其实是测试给我提bug后我才意识到的问题模式。例如我们通过get接口返回给用户某种资源,用户可以通过post接口回传资源id并提交修改,由于是自己的get接口返回的,我们可能想着只验证id合法就行了,看似形成严格闭环,但如果用户停留在此页面延时提交,则可能在此期间资源过期,或者资源已被他人修改,而改用户也成功修改的bug。其实进一步思考,你会发现,这跟高并发情景下的资源失效有异曲同工之处。
第三条建议:检验数据库、第三方接口的返回数据
除了用户输入,常见的数据来源还有数据库、第三方接口。相对而言,这些数据接口会可靠的多,而且内容格式也更规范。不过为了接口的稳定性,最好也做一些检验。如常见的数据为空的情况,就要及时中止程序执行并抛出合适的信息。
对了,对于数据库,我还遇到过bug,就是主从延迟导致的数据更新问题,由于经验尚浅,这类问题不很擅长,就不再写。
第四条建议:程序算法尽可能覆盖异常情况
这条实际上是对前三条的补充,有些不合法的用户输入你可以直接中止程序并返回错误信息,但有些情况可能需要程序继续运行,进行特殊处理,这些情况你在程序设计之初应该尽量考虑周全,后期bug会少很多,也更容易维护。
三. 如何写出更高效的接口
最后,再写一点点关于关于接口效率、代码质量的思考。
1. 影响接口效率的主要是数据库操作
以我有限的经历来看,接口耗时长基本都是因为数据库操作不合理,我们大多数的业务代码并不会有性能问题。我见过不少在for循环里查询数据库的代码,一定要避免,我们可以先一次性取出所有数据,然后逐个去处理。例如我们会在框架层记录所有数据库操作,调试接口时即可看到所有数据库操作以及相应耗时,该合并的查询要合并,该优化的耗时查询相应去优化。
2. 合理使用Exception,日志
这条主要针对php语言,由于历史原因,我看到不少代码靠return中止程序并传递错误信息,这样在代码复杂、调用层次深了以后极难维护,远没有Exception机制直观方便。还有,重要信息一定要写日志,便于后期发现问题及调试,也可用来自证清白。
3. 代码要合理划分、抽象
不要复制粘贴代码,重复的功能要独立出来;设计时要合理考虑需求变更、扩展;写小而专注的函数,不要把复杂功能一坨实现;这样写的代码才易于修改、测试以及扩展。这块我做的也不好,上线后看自己的代码都是一坨一坨,难以维护,接下来还要多思考,多实践。
四. 结束语
祝大家写的代码都没有bug!
更多Laravel相关技术文章,请访问Laravel教程栏目进行学习!
# 后端开发
# php
# laravel
# 架构
# for
# 循环
# 接口
# 并发
# 事件
# 算法
# 数据库
# bug
# 后期
# 会在
# 自己的
# 都是
# 第三方
# 会有
# 你可以
# 错了
# 这条
# 忙着
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
简单实现Android文件上传
Laravel如何实现多级无限分类_Laravel递归模型关联与树状数据输出【方法】
Android中AutoCompleteTextView自动提示
EditPlus中的正则表达式实战(5)
北京网站制作的公司有哪些,北京白云观官方网站?
Laravel如何发送邮件和通知_Laravel邮件与通知系统发送步骤
Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南
Laravel如何实现数据库事务?(DB Facade示例)
Laravel的契約(Contracts)是什么_深入理解Laravel Contracts与依赖倒置
手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?
如何在IIS7中新建站点?详细步骤解析
Laravel如何将应用部署到生产服务器_Laravel生产环境部署流程
中国移动官方网站首页入口 中国移动官网网页登录
今日头条微视频如何找选题 今日头条微视频找选题技巧【指南】
javascript基于原型链的继承及call和apply函数用法分析
如何用已有域名快速搭建网站?
如何在腾讯云免费申请建站?
如何打造高效商业网站?建站目的决定转化率
Laravel怎么在Controller之外的地方验证数据
如何在Windows环境下新建FTP站点并设置权限?
七夕网站制作视频,七夕大促活动怎么报名?
网站页面设计需要考虑到这些问题
如何在自有机房高效搭建专业网站?
如何在IIS7上新建站点并设置安全权限?
Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】
如何在局域网内绑定自建网站域名?
Laravel如何集成Inertia.js与Vue/React?(安装配置)
Laravel如何处理异常和错误?(Handler示例)
Laravel如何自定义分页视图?(Pagination示例)
Laravel路由怎么定义_Laravel核心路由系统完全入门指南
Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】
Laravel表单请求验证类怎么用_Laravel Form Request分离验证逻辑教程
微信小程序 HTTPS报错整理常见问题及解决方案
微信小程序 require机制详解及实例代码
Laravel中的withCount方法怎么高效统计关联模型数量
Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程
如何在橙子建站上传落地页?操作指南详解
瓜子二手车官方网站在线入口 瓜子二手车网页版官网通道入口
如何在万网ECS上快速搭建专属网站?
Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全
laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程
如何在阿里云服务器自主搭建网站?
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
如何在不使用负向后查找的情况下匹配特定条件前的换行符
iOS发送验证码倒计时应用
Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能
Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程
Laravel中间件如何使用_Laravel自定义中间件实现权限控制
如何在云指建站中生成FTP站点?

