现在的软件开发都是分工非常明确的,一个开发团队通常都会有:服务端开发人员若干
、Android端开发人员若干
、iOS端开发人员若干
、Web前端开发人员若干
、 这些端是靠接口
把他们联系在一起的,接口
就是这些端进行交换数据的通道。
通常,客户端
(Android端
、iOS端
、Web前端
)需要的数据比较多一些。客户端
要向服务端要数据,就必须定义规则,规则就是接口
。
接口
是怎么定义的呢?接口通常是根据产品经理
的原型制定的。
接口
定义好之后,服务端
和客户端
分别基于这个定义好的接口
进行实现。
但是刚定义好,客户端
是无法向服务端
要数据的,因为服务端
还没实现好呢? 而客户端
在开发的时候就要要数据,客户端
是严重依赖数据的, 因为客户端
通常是展示UI,而UI中的数据基本上来自于服务端
。 这怎么办呢?客户端
总不能等着服务端
实现好了再开工吧! 对于这种情况,有很多的方法可以解决:
初级一点儿的程序员的做法:造一堆假数据在自己的代码里。这种方法显然是不合理的,造成代码难以维护,正式发布的时候,一旦忘记了删除掉这些假数据,会出现很多的Bug。
高级一点儿的程序员的做法:用一些Mock
库。Mock
的代码与实际的代码是分开的,这样确实很好, 但是这个有点独乐乐的味道,因为每个端都要这么干,团队成员可能有很大的学习成本,因为这种方式不统一,而且还不是真实的网络环境。 当你切换到真实的网络环境下很可能会出现预料不到的问题。
最高级的做法:利用接口文档自动生成Mock
接口。因为定义接口
一定要写接口
文档, 有很多工具可以根据接口文档生成Mock
接口,比如EasyMock,当然,这个也需要一定的学习成本,但是这个 学习成本是非常低的,语法非常简单,而且只需要些文档的那个人学,但是是整个团队受益,客户端再也不用各自学一些Mock
库了,而且这是真实的网络环境, 只是没有逻辑而已。这样,客户端
开发起来就会顺畅很多,可以将问题提前暴露出来, 而不是等到集成测试阶段一下子爆发。还可以提高开发效率。
退而求其次的做法:但是很多团队仍然不愿意使用这种方法,因为他们说,把自己的接口文档放在公网上,这个不安全。这时候, 就是我们的ngnix上场的时候了。我们将客户端需要的接口数据按照一定的规则放在ngnix的html
目录中,利用rewrite
功能把对应接口的数据返回给客户端。
下面是我ngnix的一个配置示例:
location / {
root html;
index index.html index.htm;
if ($http_x_user_agent ~ "com\.unionx\.edu\.online") {
rewrite ^/(.*)$ /edu_online/$1-response-body.json break;
}
if ($http_x_user_agent ~ "com\.unionx\.yilingdoctor") {
rewrite ^/(.*)$ /yilingdoctor/$1-response-body.json break;
}
}
说明:
Android端发起HTTP请求的时候, 会在X-User-Agent
请求头里面包含这个Android App
的包名。
iOS端发起HTTP请求的时候, 会在X-User-Agent
请求头里面包含这个iOS App
的BundleID
。
iOS App
的BundleID
与Android App
的包名类似,都是一个App
的唯一标志, 在项目开始之前,项目经理应该尽量确保他们两个设置成一样的字符串(一般是域名倒置),这样就统一了,当然不一样也可以,只是麻烦一些。
这里是匹配包名或者BundleID
的,匹配到就可以确定是哪个App
了。 这样一个ngnix就可以为不同的App的接口造模拟数据了。
这里没有使用HTTP标准的请求头User-Agent
, 而是自定义了一个X-User-Agent
, 这是因为在浏览器里面使用XHR发起请求的时候,浏览器为了安全考虑, 是不允许修改User-Agent
这个请求头的值的, 所以我们才自定义了一个X-User-Agent
,表示对User-Agent
的扩展。 具体可以参考:https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-setrequestheader()-method
注意:对于HTTP POST
请求,会出现问题,具体解决办法请看POST请求静态资源,返回405 Not Allowed