美文网首页System Design
系统设计基础9:API的设计

系统设计基础9:API的设计

作者: MeazZa | 来源:发表于2019-03-23 17:54 被阅读0次

本文讨论一下什么是API,以及如何进行设计出好的API。

API的概念

API:Application Programmable Interface,我们通常理解的接口。

它是一个方法,可以提供给使用方进行远程访问。它与系统内部的具体实现无关,只定义了和外部使用方的交互方式,他们需要提供什么,方法可以返回什么,因此API描述的可以通过这个接口做什么事情。

public List<Admin> getAdmins(String groupId);

上面是一个API的定义,API接收一个groupId并返回所有的管理员,这里getAdmin为API的名字,groupId为传入参数,List<Admin>为返回值。

API设计的Checklist

  • Where:API应该在哪里定义。在微服务中,存在一个和Group相关的服务,那么上面通过GroupID获取所有管理员的API应该在Group服务中实现。
  • What:API的功能是什么。API的名字要可以明确的表述出API能够实现的功能。
  • How:API如何调用。API的参数设计,定义了在调用API时需要传入的参数。
  • Result:API返回什么。API在执行结束后,返回给客户端的结果。

API设计的常见错误

  • 命名问题:例如上面的API,返回的是属于某组的管理员,那它的名字就不应该是getAdmins,而应该是类似于getAdminsBelongToGroup,能够准确表达它的含义。
  • 参数定义问题:假如请求方想判断一个用户列表是否全部为该组的管理员,那应该再设计一个API类似:
public boolean checkAdmins(String groupId, List<String> userId);

这里要强调的是,要根据API的功能进行参数的设计,不要传入额外不必要的参数。

  • 参数类型的定义:定义准确的参数数据类型,如果调用者传入了错误的参数类型,直接返回调用失败。
  • 尽可能多携带有用信息:假设getAdmins操作需要对传入的groupId进行额外的,比如鉴权或者之类的判断,而这些判断在调用getAdmins之前已经获得。那么是可以将这部分信息通过参数传给getAdmins,以减少重复的调用。
  • 返回内容定义问题:有种设计方式是将所有信息全部提供给调用者,可以不关心调用者使用哪些信息,从安全和网络性能的角度考虑,这种方式是不推荐的,应该按照调用者的需求设计返回内容的格式。

POST和GET请求

仍然以获取某个组的所有管理员为例,如果设计成POST请求,那么API为:

* POST:https://www.meazza.tk/chat_messaging/getAdmins,
* Request: 
{
    "groupId": "123"
}
* Response:
{
    "admins": [
        {
            "id": 11111,
            "name": "meazza"
        }
    ]
}

该POST请求也可以修改为将action放在Request中:

* POST:https://www.meazza.tk/chat_messaging,
* Request: 
{
    "groupId": "123",
    "action": "getAdmins"
}
* Response:
{
    "admins": [
        {
            "id": 11111,
            "name": "meazza"
        }
    ]
}

如果设计成GET请求,不需要发送payload,设计的API如下:

* GET:https://www.meazza.tk/chat_messaging/admins?groupId=123
* Response:
{
    "admins": [
        {
            "id": 11111,
            "name": "meazza"
        }
    ]
}

避免副作用

假设有一个API,是将一组用户设置为该组的管理员,方法定义如下:

public void setAdmins(List<Admin> admins, String groupId);

现在的问题是,如果admins中包含了非该组的成员,该如何处理?一种方式是API的方法逻辑中进行判断,如果发生这种情况返回请求失败;另一种方式是将admins中不是该组成员的,添加到该组中,并设置成管理员。因此这个API的行为是不确定的,可能并不是一个好的API设计。

如果采用第二种处理方式,那么这个API的带有副作用的,也就是将一些用户添加到了该组中。因此这里有两个API的设计原则:

  • 独立性:比如在API中完成了多种操作,并通过一些flag决定执行哪些操作的话,这个API是很奇怪的,此时应该拆成多个API。
  • 原子性:比如setAdmins的实现,每次都要先清除group的管理员,如果某次请求失败,可能导致后续的请求无法执行,因此要确保每次API的操作都是相同的,不能存在中间状态。

解决返回数据量过大

如果一个API返回的数据量比较多,有两种方式可以进行优化:

  • 分页(Pagination):比如一个返回200个用户的API,可以每次返回10个,并标记当前页数和总页数等信息。
  • 分段(Fragment):分拆这个API的返回信息,并使用多个API实现,某个API返回其中的一部分信息,客户端可以按顺序进行依次请求。

数据一致性和可用性

最后讨论一些API在实际使用中的一些问题:

  • 数据一致性:假如API是从数据库中查询数据,如果在API查询后,数据库中添加了新的数据,可能会导致出现数据不一致的情况,如果要解决不一致的问题,就会导致API的性能下降。因此要结合应用场景考虑,如果是不需要保证数据严格一致的场景,比如查询一个帖子的所有评论,是可以接受不一致的情况的。
  • API的降级:如果API的返回内容过大导致有可能崩溃,此时应该保证API可以返回最重要的信息,而丢弃一部分信息,使得系统不会彻底崩溃。

小结

本节介绍了关于API设计的方方面面,在保证API设计的基本规范的前提下,在设计时还要考虑实际的应用场景,结合实际情况设计出最合适系统的API。

欢迎大家订阅专题,其中包含了系统设计基础系列的全部文章:System Design

相关文章

  • 系统设计基础9:API的设计

    本文讨论一下什么是API,以及如何进行设计出好的API。 API的概念 API:Application Progr...

  • 设计系统的进化-设计API

    设计系统(design system)是提升设计研发效率、确保产品一致性的重要工具。 大型企业由于人员和团队众多、...

  • 系统的API设计

    javax扩展api是可以参考的典范,spring security就是一个反例,这个框架没有将定义与实现做合适的...

  • 【平面设计教程】中国平面设计收费参考标准

    ​​一、品牌形象类 标志设计 3000元 - 10000元 不含基础系统设计,两套选一 VI视觉基础系统设计 50...

  • 云服务OpenAPI的7大挑战,架构师如何应对?

    阿里妹导读:API 是模块或者子系统之间交互的接口定义。好的系统架构离不开好的 API 设计,而一个设计不够完善的...

  • 深度 | API 设计最佳实践的思考

    阿里妹导读:API 是模块或者子系统之间交互的接口定义。好的系统架构离不开好的 API 设计,而一个设计不够完善的...

  • 汽车电子硬件开发规范

    1 原理图设计流程 原理图设计是从系统设计到硬件细节设计的基础,细节设计是“系统框图-原理图-电路版图”不断设计的...

  • HTTP Methods 和 RESTful Service A

    API 可以说是软件开发者的用户界面,API 设计也是系统架构的重要环节。尤其对复杂和分布式系统而言,其设计的好坏...

  • RESTful 接口设计开发规范

    API 接口可以说是软件开发人员的用户界面,API 设计也是系统架构的重要环节。尤其对复杂和分布式系统而言,其设计...

  • API设计

    API设计 Google API 设计思想 1、设计 API设计原则简单可用一致 HTTP 常用方法get 获...

网友评论

    本文标题:系统设计基础9:API的设计

    本文链接:https://www.haomeiwen.com/subject/boxzmqtx.html