编写API的二三事

作为程序员,我们对API这个词并不陌生,因为我们几乎每天都在和它打交道。但是有时候我们并没有意识到,我们自己也是API的作者,我们手中诞生的一个个类、一个个方法都有可能(或者本来就会)被其他同事(或者自己)用到。所以我们应当意识到,我们的代码并不是能运行就算成功,而是要用审视API的眼光来审视它们,用编写API的态度来编写它们,只有这样,别人才能放心地把它们视作强健的API来使用。

本文会结合豆瓣网的V2版API来讨论几件编写API时应当注意的事情,你会发现有很多其实属于代码可读性的范畴,的确如此,我个人并不反对Dirty&Quick的开发方式,但是涉及到接口提供与团队协作的时候,Dirty&Quick实际上是在一个大坑上面搭了一层草皮,没错,我说的就是陷阱。

友好

编写API的目的是为了被消费,那么就不应该为消费者制造消费障碍,所以在编写API时,我们就应当站在消费者的角度去考量这个API是否易用。API的友好性体现在许多方面,我不能悉数道尽,希望下面的几个例子能够起到抛砖引玉的作用。

API的命名是否友好,是否能望文生义,比如下面这个方法就是一个反例:

public Order[] GetOrder()

按照方法名称可以推断出返回结果应该是单个Order,可是却返回了一个Order数组。
这个方法还有一个重载如下:

public void GetOrder(int[] orderIds)

你绝对不会猜到它的作用是删除参数列表中的Order。

参数也是非常重要的元素,再比如这个反例:

public Order[] FindOrders(int orderId,
string orderName,
string description,
DateTime time,
string owner,
bool hasDiscount,
……)

如果方法的参数列表长到一定程度,那么很可能的情形是这些参数并不都是必须的,这时我们最好把这些参数抽象成一个对象,比如OrderOption,然后根据需要给这个OrderOption的属性赋值,对消费者来说,这种方式无疑会轻松许多:

public Order[] FindOrders(OrderOption option)

一致

API的消费方式要保持一致,比如豆瓣网获取图书信息的API地址是:

https://api.douban.com/v2/book/:id

获取音乐信息的API地址是:

https://api.douban.com/v2/music/:id

消费者会很容易推测出获取电影信息的API地址,然而我们都猜错了,获取电影信息的API地址是:

https://api.douban.com/v2/movie/subject/:id

是的,这也是个反例。

相似的反例还有,在豆瓣网,评分是一个很重要的信息元素,无论是图书、电影还是音乐的API,都返回了评分信息,用一个rating对象来表示。

图书和音乐信息里返回的rating结构如下:

"rating":
{
"max":10,
"numRaters":134555,
"average":"8.8",
"min":0
}

电影信息里返回的rating结构如下:

"rating":
{
"max":10,
"average":7.6,
"stars":"40",
"min":0
}

所以如果消费者仅仅是想知道某个条目是几星的话,对于图书和音乐,他需要将average除以2,而对于电影,他需要将stars除以10。

维持一致性是API编写者的责任,无论如何都不应该让消费者为此买单。

专注

特定领域的API要专注于它领域内的事情,不要妄图接管一切,尤其不要在API内部掩盖参数引起的错误,这只会让调试更加困难,如果你确定消费者提供的数据有问题,那就果断把异常抛给他。

但对于API自己的业务逻辑来说,却要尽可能完美的处理好各种异常情况,不要给消费者制造麻烦。

谨慎

API一旦公布,它就再也不是你一个人的玩物了。对API的任何逻辑改动,都需要先站在更高的层面上思考,尽量避免给消费者带来消极影响。倘若你贸然修改了入口位置而没有事先通知消费者,那么所有消费者的代码都会崩溃。这很糟糕,但比这更糟糕的是你悄然修改了API的内部逻辑,却没有充分考虑到所有的可能性。

比如豆瓣V1版API曾经可以获取用户收藏的电影,你可以通过参数指定起始索引和想要获取的数量,但有一天,豆瓣悄悄把这些参数都忽略了,也就是说无论你怎么调用,它永远只返回前十条。首先为此蒙受损失和遭受恶评的,永远都是依赖这些API的消费者(应用)们。

沟通

有时候我们必须要对API做一些改动,而且我们知道这么做必然会影响到消费者,那么最好的做法就是积极地沟通。如果你不确定这些改动的影响程度,那就和尽可能多的消费者一起讨论一下,让大家明白这么做的原因,可能产生哪些你没有预料到的影响,并一起找出减少彼此影响的最好的方式。

沟通的另一方面表现在接受和响应反馈,只有不断地接受反馈,进行自我调整,API才能成熟起来,API如是,程序员也如是。

发表评论

电子邮件地址不会被公开。 必填项已用*标注