Flat Weather开发手记:后端服务篇(上)

cloudserver

上一篇博客中我讲述了这款天气app的UI设计,不过设计归设计,没有功能可不行,天气数据从哪里来?app应该如何获取天气数据,这是这篇博客将要讲述的,这篇博客将会讲述我为这款app编写后端程序的故事。

由于这是我第一次编写服务器应用,也是我第一次设计API,第一次接触容器服务,所以说这篇博客只是记录了我在这次项目中获得的经验,我的设计可能并不巧妙并且错误百出,所以仅供参考。

说道APP如何获取网络数据,稍微有点经验的人肯定会说调用API啊,解析Json啊,没有问题,我在这里稍微提一下。

  • Restful API

Restful(Representational State Transfer) 架构是现在流行的一种软件架构风格

理解RESTful架构 没听过的话可以看一下阮一峰老师的博客

MikeTech.it的app后台与网站通信就是利用了Restful API:

  • 问题引入:为什么要设计后端

上篇博客也提到了,想要获得天气数据,现有的第三方api服务完全可以,比如聚合数据上就有很多第三方天气api可以使用,再比如和风天气也是一个很著名的中国天气数据API提供商。但是我对flat weather的要求是不只有中国城市的天气,而且要有外国城市的天气数据,可是在和风天气上这个外国天气的数据是要收钱的,而且每个月也不便宜。不过这可难不倒我,在看看外国也有一些天气API的提供商比如 open weather api,可以提供全球的天气数据。那么说道这里可能问题就已经解决了。用户请求中国城市的时候调用和风天气的api,用户请求外国城市的时候调用open weather api的数据不就完了?是的,我一开始也是这么想的,在编写app的时候我先实现了对和风天气API的调用。不过不就之后,我就发现问题了,这个需求使得app的内部变得很复杂而且难以维护。

复杂主要体现在以下几点:

  • 第三方API请求参数不同

和风天气请求参数为 city=shanghai 代表上海天气,而open weather api 为 q=London,uk,这都不是大问题,可以写两套请求嘛,没毛病。

  • 第三方API的返回数据设计不合理

来看看我的app的需求,在主界面上,用户可以看见现在的天气,未来若干小时的天气,和未来数天的天气预报。

接下来看看不同API提供商的API设计:

能看出来,两个提供商的api设计完全不同,和风天气的不错,几乎满足了我的全部需求,daily_forecase,hourly_forecast和now字段中储存着小时天气预报,每日天气预报,和现在的天气状况。

但是Open Weather API这边就不乐观了,这个接口只是提供了现在的天气,没有未来的天气预报,未来的天气预报在另一个接口里,这样的话,如果我想拿到全部数据,对于外国城市,我要先后请求open Weather API的两个不同接口才能将数据全部拿到。这样的代码要是写在app里是很麻烦的。

而且不同提供商的接口设计也不太相同,比如查看请求是否成功的状态字段,第一个用的是 “status” 值为 “OK”代表这个请求是成功的,二第二个接口使用的是 cod 字段,值为200,也是成功的意思,这样的话,在app中要是想要判断请求是否可用也得写两套代码。而且日期字段表示方式也不一样,和风天气的日期值为 “2017-01-19 08:51”而同样是日期,Open Weather API 为 1484812528 ,这是UNIX时间,要经过转换才能被看懂。

就因为这一点使得app中的请求代码变得异常繁琐。不过要是硬着头皮写那也可以实现,只不过看起来不太优雅。

  • 难以维护 + 被动

刚才说了API设计和我的app需求设计不匹配的问题,现在来说说维护,其实,免费试用别人的api都是有代价的,和风天气API,每天每个开发者key只能请求3000次,而open weather api每天只能请求1000次,要是一开始就把你的开发者key写死在app里面的话,要是真有一天超过了3000次的话将不会得到天气数据,而你只能干瞪眼而没有办法。

而且要是突然有一天,和风天气的API突然变了,比如 status字段名称突然变成了code字段,那这可就尴尬了,你必须得推送新的app版本才能修复这个版本。这个不说,那有些用户要是不知道这个事的话每次开app都会由于找不到status字段而崩溃而造成很差的用户体验,这样很容易就造成客户流失。

这一个缺点是最致命的,前两个点如果在app中多下点功夫还能解决,但是这最后一个,主动权在api提供商那里,所以必须得解决这个问题。

  • 规划自己的后端

上面提到了那些问题,为了化被动为主动,我的做法就是自己设计服务器后端了,服务器后端对于不同的城市分开请求和风API和Open Weather API,相当于一个中继,然后生成自己设计的Restful API返还给app,这样统一API接口后app那边就好写了。

还有一个优点,对于API请求数量限制问题,比如每天1000次,我的服务器可以解决这个问题,我注册两个开发者key,然后在服务器中设立一个原子计数器,当一天内请求超过1000此后让服务器变更请求第三方API的key就可以完美的解决请求数量限制的问题。

还有一些优点,比如可以自己构建缓存系统,不用每次都请求第三方api拿数据,或者你也可以把这些数据留在服务器上然后做数据分析之类的(比如全年中国各个城市都有多少雾霾天)都是可以的。

最主要的一点就是化被动为主动了,第三方api如果变动的话只要重新设计服务器端就可以了可以及时发布变更而不用用户来更新app。

如果以后要加入什么新的功能,直接更新自己的服务器应用代码就好。

  • API设计

刚才既然提到了第三方的API设计和我的需求不符合,那么来自己设计API吧。既然决定了要写服务器应用,这也是必然的一步。

http://weather.miketech.it/v1/weather?city=sheffield-gb

注:请不要访问这个地址,我把端口删掉了,访问不会成功的。

上面的链接是我设计的第一个请求天气的接口路径,请求方式为POST,其中牵扯到了几个设计思路

  1. API的域名部署在专用域名下

这里是weather.miketech.it,是我为这个API准备的专用域名

  1. 版本号存放在Url里,这里是v1

代表第一版本api,这个很必要,比如我app的下一个版本更改了字段设计,那么我就会把路径改到v2,当然不能在v1连接上直接改!那样做使用旧版本app的人不就会请求到错误的信息了嘛!

  1. 路径(End Point)

带表API的具体地址,一般只能出现名词,比如这里是weather,代表这个API是请求天气的

  1. 请求参数

这里是city,是一个必要参数代表了需要求求哪一个城市,后面的sheffield-gb代表英国谢菲尔德。

现在来看看请求这个资源之后返回的数据:

其中identifier是这个城市的唯一识别码

location为位置,Summary为实时天气状况,icon代表天气状态0-9有不同的含义,tmp为温度,date为日期

其中还包含三个数组hourly,daily,detail,也很易懂,就是app主界面那三个tab中的数据。

最后有个status字段,这个是必要的,是服务器向用户返回的状态码,说几个常见的状态代码含义:

200:请求成功 OK

201:新建成功 CREATED

202:操作已经加入任务队列 ACCEPTED

204:删除成功 NO CONTENT

400:请求错误 INVALID REQUEST

401:无权限 UNAUTHORIZED

403:禁止访问FORBIDDEN

404:不说你也知道,请求记录不存在 NOT FOUND

500:服务器内部错误 INTERNAL SERVER ERROR

有了这个API接口,使得在app那头的代码编写变得异常方便,并且这也是设计一个互联网产品的一般姿势,前端(app)+后端(服务器应用)

在之后设计这个界面的时候:

就需要设计一个能够同时返回多个城市天气数据的API,这也体现出来了自己设计后端服务的好处,可以自己随时定制扩展,应对各种需求,虽然都是我一个人写的代码。。。

好了,这篇主要是讲述了一下为什么要去设计后端服务,和Restful API的一些设计思路,下一篇将会来实践一下编写出来后端应用并且部署到服务器上。

 

 

打赏

Leave a Reply

Your email address will not be published. Required fields are marked *