S1E3 开发者文档的三种内容层次:字典、概览和教程

S1E3 开发者文档的三种内容层次:字典、概览和教程
Photo by Arisa Chattasa / Unsplash

Hi,欢迎收看 APILetter,距离上一次更新,已经过去了三周。天津疫情凶猛,今天我终于又来到了街上。现在正在天津大悦城的星巴克臻选里写这封邮件。


不知道,你有没有关注过开发者文档的信息结构。下图是 Google Docs 的 API 文档:

Google Docs Developer Portal 截图

在菜单中 Google Docs 提供了 Home、Guides、Reference、Samples、Support。你有没有想过,这些内容为什么如何设计?在我看来,这是开发者文档内容的三种层次。

第一层:解决有没有的问题

典型代表:API Reference

绝大多数开放平台也好,To Developer 产品也罢,首先要解决的问题是让开发者知道我有什么样的能力。而最简单、最直接最高效的方式,便是 API Reference。

各大产品在进行对外开放时,首先准备的便是一套 API Reference。在 API Reference 当中,你可以看到开发者应该如何调用一个 API;某个 API 的入参是什么、出参是什么;如果出现了失败,应该如何处理这些错误。

当一个 API Reference 为开发者提供了简洁、明确、易懂的文档内容之后,开发者基本就可以准备开始进入开发流程了。

Opinionated Notes:RESTFul API 的 API Reference 理论上不应该存在多层级的资源关系。

优秀的 API Reference 参考:

第二层:解决怎么用的问题

典型代表:API Overview、单个业务领域的 API Guides & API Tutorial

作为开放平台,当完成了 API Reference 之后,便算是及格了。但及格不应该是目标,目标应当是卓越。抵达卓越,则需要更多内容的帮助。

API Reference 回答了「能用什么」的问题,但没有解决「如何使用 API」的问题,特别是复杂的业务场景下,同一个业务内可能会需要多个不同的资源来进行 API 的操作,这个时候,如何使用这些资源,并将这些资源包装、关联起来,就成为极具业务属性的 Know How 知识。

举个例子来说,以服务端 OpenAPI 为例,日历的资源就涉及到用户、日历、日程、会议室、参会人、权限管控等多个不同的资源,如何串联这些 API 才能达成你的业务目标,就成为一个非常重要的说明。对于日历的能力熟悉的开发者可能很快就可以找到调通的方式,但对于不够熟悉的,这些 API 之间的串联,可能需要他花费一天,甚至一周的时间才能真正理解背后的含义。如果想要降低开发者调通过个 API 的时间,那么介绍这些不同 API 之间的关系,其在业务系统之中的含义就尤为重要。

如果你对于服务端的 API 感触不深,那么客户端的 API 可能会让你感受更加深刻,以微信小程序的中的蓝牙设备开发为例,如果你作为一个从未开发过蓝牙能力的开发者,看到了蓝牙提供的这一系列 API,只怕马上头皮发麻,需要每一个都看一遍才能理解其含义和价值;在蓝牙这件事上阻塞个半周一周也是常态。

微信小程序中的蓝牙 BLE API 文档

一个好的 API Guide / Tutorial 可以有效的降低开发者在调试这些 API 过程中所耗费的时间。当然,微信也意识到了这个问题,提供了一套非常好的 API 说明

优秀的 Tutorials 参考

第三层:解决场景化使用的问题

典型案例:Code Sample,Demo App,场景化的使用教程

API Tutorials 可以解决的是面向场景化的单个领域的内容。它帮助开发者很好的解决了一个领域内的产品能力的串联。但在实际的业务场景当中,开发者面对的不是已经拆解到 API 粒度的任务,而是面向场景设计的不同问题。对于开发者来说,把场景拆分成 X 个 API 并没那么容易(特别是如果经验不足的时候),因此,一套标准的 Code Sample ,甚至是 Demo App ,都可以帮助开发者快速解决面向场景化的问题。它可能涉及到了客户端、服务端,或者是面向了多个不同的领域。这些内容帮助开发者可以快速 landing。

以飞书开放平台为例,飞书开放平台在开发教程里提供了多个领域、不同方向的场景化教程(虽然还不够多,远远不够),帮助开发者快速完成某个特定领域的功能的开发。

飞书开放平台的教程文档

这些内容可能未必能完全满足开发者的需求,但确实可以给开发者一定的借鉴意义,帮助开发者理解整个业务流程和对应场景下的具体的实现,帮助开发者快速完成业务需求。

第三层之后,应该是什么?

前面三层解决了有什么、怎么用的问题,而在整个应用的生命周期当中,怎么用并不是终极问题。下一步需要解决的是如何用好的问题。不过这个问题不在本次阐述的内容当中,所以我们留一个悬念,下次再说。

如果你对于这个话题感兴趣,欢迎回信聊聊。

Read more

加更: 聊聊 APILetter 的新计划

加更: 聊聊 APILetter 的新计划

Hi,你好, APILetter 从创刊号,到 S1E6,经历了一年的时间。 虽然在定更新节奏时,我就考虑到自己拖更的可能性,但确实没想到我拖更这么严重,在 2022 年,一口气更新了 3 篇,然后就是长达半年的拖更。不过,总算是把第六篇写完,算是给 Season 1 做个了结。 过去 APILetter 的出现,是源自我在研究 RESTFul 架构时发现的问题:国内有太多解释什么是 RESTFul 规范的文章,但你点进去看,篇篇都是复制粘贴。 而 API 是开发者生态中非常重要的一环,它不应该被草率的对待,开发者们值得用上更好的 API。既然没有人写关于 API 的严肃内容,那就从我开始吧。刚好我在研究相关的内容,那就写一些 API 到底应该是什么样的。 也正是抱着这个想法,我开始了一篇篇的创作,

By 白宦成
S1E6 为什么 OpenAPI 的设计如此重要?

S1E6 为什么 OpenAPI 的设计如此重要?

在 APILetter 的 S1E6,我想和你聊聊 OpenAPI 设计的重要性。 在整个 S1 的文章中,我用了接近 4 篇的篇幅来介绍 OpenAPI 的设计,从一开始介绍为什么要使用 RESTFul ,到 API 的错误码设计理念,辅以批量接口设计的实例,再加上最后这篇重要性的强调,三分之二的比重,意在让你深刻认识到,OpenAPI 的设计至关重要。 为什么 OpenAPI 的设计如此重要? 在企业内部工作时,常常需要找到平衡质量和速度之间的折衷方案。当项目时间非常紧迫时,往往会牺牲一些质量。但如果项目有足够的时间,就有更高的概率能够设计出一个质量更好、开发者体验更佳的 OpenAPI。 然而,OpenAPI 是一项非常重要的任务,不能马马虎虎。一个坏的设计会让团队持续在 OpenAPI 开发上投入更多的精力。 沟通难度高带来的维护成本增高问题 和企业团队内部使用的 API 不同,OpenAPI 的用户是外部团队,

By 白宦成
S1E5 如何设计一个符合 RESTFul 风格的批量操作的 OpenAPI 接口?

S1E5 如何设计一个符合 RESTFul 风格的批量操作的 OpenAPI 接口?

许久不见,甚是想念,最近做了不少 RESTFul  API 的设计实践,分享一下最新的经验。 在遵循 RESTFul 风格设计 OpenAPI 时,简单的创建、更新、查询、删除是比较好做的,大家也大多能够想到如何设计对应的接口,无非是用 POST 做创建、GET 做查询、DELETE 做删除、PUT、PATCH 做更新,但设计到批量的操作时,大家往往会有一些困惑,今天我们就来聊聊 RESTFul 下的批量操作。在给出我自己具体的实践之前,先来看看业界的实践。 业界的两种实践 由于 RESTFul 风格定义当中并没有明确说明如何设计批量接口,所以业界上也有不同的批量接口设计的思路,大体可以分为两种: 1. 在网关层面设计批量接口的能力,实现异步转同步:这部分主要是会提供一个单独的请求路径,由开发者将自己的请求打包并发送到这个新的路径,由这个路径上的服务将请求结果发送给具体的服务,并将结果收回,返回给开发者。Google 和

By 白宦成
S1E4 到底多少个错误码才是合理的?

S1E4 到底多少个错误码才是合理的?

在对外开放 OpenAPI 的时候,错误的设计也是一个极为影响开发者开发体验的设计点。今天我们简单聊聊关于错误码和错误处理 为什么需要错误码? 由于我们不能保证系统可以完全处理用户的请求,因此我们需要通过错误码来告诉开发者发生了不符合预期的情况。不符合预期的情况可能由用户输入错误导致,也可能由内部微服务故障导致。为了建设一个健壮(Robust)的系统,我们需要通过对外暴露一批错误码,帮助开发者更好地处理各种异常情况。 避免错误码数量过少 既然我们的目的是帮助开发者解决异常情况,那么一个合理的答案是:和异常情况匹配的错误码数量是一个好的错误码数量。 如果在某个 API 接口上提供了一个错误码,则意味着我们认为这个接口只会出现一种情况导致的错误。而实际上,很可能会有多种情况导致错误发生。这种情况经常在 OpenAPI 评审过程中被提出来,也是用户在使用 OpenAPI 时常遇到的问题:为什么我找不到这个错误码?对于开发者来说,无论输入何种错误,都会得到相同的错误码,难以定位和解决问题。同一个错误码也意味着你无法提供足够的错误信息来进行排查。例如,常见的 “400 Bad Re

By 白宦成