在Yandex中记录API和SDK的新外观。 Hyperbaton讲座

我叫Andrey Polyakov,我是Yandex的API和SDK文档小组的负责人。 今天,我想与大家分享我和我的同事,高级文档开发人员Julia Pivovarova在几周前第六届Hyperbaton上阅读的报告。


文档和本地化部门主管Svetlana Kayushina:
-近年来,世界上程序代码的数量已经显着增长,并且持续增长,这影响了技术编写者的工作,他们在开发程序文档和文档代码方面面临着越来越多的任务。 我们不能忽略这个话题,我们在整个章节中专门介绍了这个话题。 这是有关软件开发统一的三份相关报告。 我邀请我们的专家来为Andrei Polyakov和Julia Pivovarova记录软件接口和库。 我请他们发言。

大家好! 今天,Julia和我将告诉您在Yandex中我们如何对文档化API和SDK有了新的认识。 该报告将包括四个部分,观察报告,我们将讨论,我们将进行谈话。

让我们谈谈API和SDK的统一,如何实现以及在那做些什么。 我们将分享使用通用生成器的经验,一种适用于所有语言的通用生成器,并告诉您为什么它不适合我们,存在哪些陷阱,为什么我们要使用本机生成器来生成文档。

最后,我们将描述流程的构建方式。

让我们从统一开始。 当团队中有两个以上的人时,每个人都会考虑统一:每个人的写法不同,每个人都有自己的方法,这是合乎逻辑的。 在开始编写文档之前,最好先讨论一下海滩上的所有规则,但并非所有人都能做到。

我们聚集了一个专家组来分析我们的文档。 我们这样做是为了使我们的方法系统化。 每个人都以不同的方式写作,我们同意以相同的风格写作。 这是我们要尝试使文档统一的第二点,以便用户在所有Yandex文档(即技术)中拥有一种用户体验。

工作分为三个阶段。 我们已经对Yandex中使用的技术进行了描述,我们试图挑选出可以以某种方式统一的技术。 并且还组成了标准文档和模板的一般结构。



让我们继续对技术的描述。 我们开始研究Yandex中使用了哪些技术。 它们太多了,以至于我们都厌倦了用某种笔记本将它们写下来,因此,我们只选择了最常使用,技术作家最常遇到的最基本的那些,并开始描述它们。

技术描述是什么意思? 我们已经确定了每种技术的要点和实质。 如果我们谈论编程语言,那么这是对诸如类,属性,接口等实体的描述。如果我们谈论协议,那么我们描述HTTP方法,我们谈论错误代码,响应代码等的格式。词汇表包含以下内容:俄语术语,英语术语,使用细微差别。 例如,我们并不是在谈论任何SDK方法,而是可以让您做一些事情。 他会做某事,如果程序员拉笔,它会给出一些答案。

除了细微差别外,描述还包含标准结构,标准语音转弯,我们在文档中使用了这些结构,以便技术作家可以采用特定的措词并进一步使用它。

此外,技术作家经常编写代码,代码段,示例,为此,我们还描述了每种技术的样式指南。 我们转向了Yandex中的开发人员指南。 我们关注设计代码,注释说明,缩进等。 我们这样做是为了当技术编写者向程序员提供一段代码或书面示例时,程序员着眼于本质而不是其设计方式,从而减少了时间。 而且当技术作家可以编写Yandex样式指南时,这很酷,也许他以后想成为一名程序员。 上一份报告是关于各种检查的。 例如,您可以进入程序员。

我们还为技术作家开发了一个快速入门:当他熟悉新技术时如何建立开发环境。 例如,如果技术作家SDK是用C#编写的,那么他来了,设置了开发环境,阅读了手册,熟悉了术语。 我们还保留了指向官方文档和RFC(如果有)的链接。 我们为技术作家提供了一个切入点,看起来像这样。



当技术作家到达时,他学习了一种新技术并开始对其进行记录。

在描述了这些技术之后,我们继续描述HTTP API的结构。

我们有许多不同的HTTP API,对它们的描述也有所不同。 让我们达成协议并做同样的事情!

我们已经确定了每个HTTP API中的主要部分:



“概述”或“简介”:为什么需要此API,它允许您做什么,必须访问哪个主机才能获得某种答案。

当一个人经过某些步骤并最终获得成功的结果以了解该API的工作原理时,便是“快速入门”。

“连接/授权”。 许多API需要授权令牌或API密钥。 这一点很重要,因此我们决定这是所有API的必需部分。

当我们谈论请求数量或请求主体大小的限制时,称为“限制/限制”。

“参考”,参考。 很大一部分,包含用户可以拉出并获得某种结果的所有HTTP处理。



结果,我们有许多不同的API,它们的描述也有所不同,现在我们尝试以相同的方式编写所有内容。 这样的利润。

深入目录,我们意识到HTTP句柄几乎总是相同的。 您将其拉出,即发出请求,服务器将返回答案-瞧。 让我们尝试统一它。 我们编写了一个模板,试图涵盖所有情况。 技术作者采用模板,如果他有PUT请求,则将必要的部分留在模板中。 如果他有GET请求,则仅使用GET请求所需的那些部分。 可重复使用的所有请求的通用模板。 现在,您无需从头开始创建文档结构,而只需采用现成的模板。



每支笔都描述了它的用途,作用。 有一个“请求格式”部分,其中包含路径参数,查询参数以及请求正文(如果已发送)中包含的所有内容。 我们还突出显示了“响应格式”部分:如果有响应正文,则将其编写。 作为单独的部分,我们突出显示了“响应代码”,因为来自服务器的响应独立于主体。 并保留了“示例”部分。 如果我们通过此API提供某种SDK,那么我们就说要像这样使用此SDK,拉这样的句柄,调用这样的方法。 通常,我们会留下某种cURL示例,其中用户只需插入其令牌即可。 如果我们有一个测试平台,它只会接受请求并执行它。 并得到某种结果。



事实证明,有很多笔,它们以不同的方式描述,现在我们希望将它们全部归为一种形式。

在完成HTTP API之后,我们继续使用移动SDK。

有一个通用的文档结构,大致相同:

-“简介”,在这里我们说此SDK用于此类目的,可以为此目的自行集成,适用于此类OS,我们具有此类版本,等等。

-“连接”。 与HTTP API不同,我们不仅在讨论如何获取使用SDK的密钥,如果需要,我们还在讨论如何将库集成到我们的项目中。

-《使用举例》。 体积最大的部分。 通常,开发人员希望查阅文档而不是阅读大量信息,他们想要复制一段内容并将其粘贴到自己身上,然后一切都会对他们有用。 因此,我们认为这部分非常重要,并将其分配给强制性部分。



-“目录”,参考,但与HTTP API参考不同,我们无法在此处统一所有内容,因为我们主要生成目录,我们将在报告的后面部分进行讨论。

-“发布”或更改历史记录,更改日志。 移动SDK通常具有较短的发布周期,每两周发布一个新版本。 用户最好谈论更改的内容,是否值得进行更新。

同时,API包含我们看到的必需部分和建议使用的部分。 如果API经常更新,那么我们说您也要自己插入更改历史记录,该历史记录已在API中进行了更改。 而且我们的API通常很少更新,因此将其指示为必填部分毫无意义。



因此,我们有很多以不同方式描述的SDK,我们试图将它们转变为大致相同的样式。 自然地,仅此SDK或HTTP API固有存在其他差异。 在这里,我们有选择的自由。 我们并不是说除了这些部分之外,没有人可以做。 当然,有可能,我们只需尝试遍历所有地方列出的部分,以便清楚地知道,如果用户切换到文档中的另一个SDK,他知道“连接”部分将进行什么描述。

那么,我们想出了模板,指导手册,现在我们的行动计划是什么? 我们决定,如果我们扩展API,更换笔或更改SDK,我们将采用新模板,采用新结构并开始进行开发。

如果我们从头开始编写文档,那么,当然,我们将再次采用新的结构,采用新的模板并对其进行处理。

而且,如果该API已过时,很少更新或没有人支持它,但是它存在,则需要大量资源重做。 我们只是决定将其保留到现在为止,但是当资源出现时,我们一定会返回给他们,我们会做得很好并且很漂亮。

统一有什么好处? 它们对所有人都应该是显而易见的:

“ UX”,我们正在考虑在文档中使用户感到宾至如归。 他来了,并且知道他可以找到授权的部分中的内容,使用示例,笔的描述。 太好了

对于技术作家来说,对技术的描述使您可以确定他进入的某个切入点,并开始熟悉这项技术,如果他不知道,则开始理解术语,并深入其中。

下一点是可互换性。 如果技术作家休假或只是停止写作,那么另一名技术作家在输入文档时便知道其内部工作方式。 现在可以很清楚地看到连接中的描述,以及在哪里可以找到有关SDK集成的信息。 了解文档并对其进行小的修订变得更加容易。 很明显,每个项目都有自己的详细信息,您不能不完全了解某个项目就对它进行记录。 但是同时,其结构(即文件导航)将大致相同。

当然,还有通用术语。 我们为语言编译的术语,我们与开发人员和翻译人员达成了一致。 我们说我们有C#,有一个术语,我们用这种方式。 我们问开发人员他们使用了什么术语,并希望在这个地方实现同步。 我们已经达成协议,下次我们收到文档时,开发人员知道我们已经与他们达成了条款和指南,我们使用这些模板,并考虑到它们使用的细微差别。 译者又知道我们用C#或Objective-C描述了SDK,因此该术语将与指南中描述的相对应。

这些指南是用Wiki页面编写的,因此,如果语言,技术,协议得到更新,则可以轻松地将其全部添加到现有文档中。 田园诗

您越早开始统一和达成共识,那就越好。 最好不要再使用其他样式的文档,这会破坏用户在文档中的工作流程。 最好早点做。

吸引开发者。 这些是您要为其编写文档的人员。 如果您自己写了一些指南,也许他们会不喜欢它。 最好与他们达成一致,以便您对术语有一个共同的理解:您在文档中编写的内容,编写方式。

并且还要与翻译商协商,他们都必须翻译。 如果它们的翻译方式不同于开发人员习惯的翻译方式,那么将会再次出现冲突。 ( 这是带有问题和答案的视频片段的链接 -大约是Ed。)我们继续。

朱莉娅:
-嗨,我叫朱莉娅,我已经在Yandex中工作了五年,并且正在Andrey小组中记录API和SDK。 通常每个人都在谈论一个很好的经验,它是多么伟大。 我将告诉您我们如何选择并非完全成功的策略。 那时,它看起来很成功,但是随后出现了一个残酷的现实,我们有些倒霉。

我们最初有几个移动SDK,它们主要用两种语言编写:Objective-C和Java。 我们手动向他们写了文件。 随着时间的流逝,类,协议和接口不断增长。 它们越来越多,我们意识到我们需要使这项业务自动化,我们研究了什么是技术。



当时,我们喜欢Doxygen,它满足了我们的需求,在我们看来,我们选择了它作为一台发电机。 我们画了一个我们期望得到的方案,我们想以某种方式进行研究。

我们有什么? 技术作家开始工作,从开发人员那里获取源代码,开始编写他的注释,编辑,之后将文档发送到我们的devserver,在那里我们运行Doxygen,接收XML格式,但是它不符合我们的DITA XML标准。 我们事先知道这一点,写了一个转换器。

从Doxygen获得输出后,我们将其全部通过转换器,并且已经获得了格式。 然后,文档收集器被连接起来,我们将所有这些都发布到了外部域中。 我们甚至幸运地进行了几次迭代,一切都为我们解决了,我们很高兴。 但是后来出了点问题。 技术作家还开始工作,从开发人员那里接收任务和源代码,并在那里进行了更正。 之后,他去了开发服务器,启动了Doxygen,然后发生了火灾。

我们决定找出问题所在。 然后我们意识到Doxygen并不完全适合所有语言。 我们不得不分析代码,结果发现它被绊倒了,我们发现Doxygen不支持也不打算支持的构造。

我们决定,因为我们正在采用这种方案,所以我们将编写一个预处理脚本,并以某种方式用Doxygen接受的结构替换这些结构,或者以某种方式忽略它们。



我们的周期开始像这样。 我们收到了源并将其包含在devserver中,然后连接了预处理脚本,将所有多余的代码切掉,然后Doxygen进入了业务,我们收到了Doxygen输出格式,还启动了转换器,接收了最终的DITA XML文件,然后连接了文档收集器,以及我们在外部域上发布了我们的文档。 看来一切看起来都不错。 添加了脚本,那里有什么? 最初,什么都没有。 脚本中有三行,然后是五行,十行,并且全部增长到了数百行。 我们意识到,我们开始将大部分时间都花在编写文档上,而不是在分析代码上,寻找哪些内容不会爬到哪里,然后简单地将脚本添加到无数的常客中,坐下来疯狂地思考问题所在。

我们意识到,我们需要更改某些东西,以某种方式停止,直到为时已晚,直到发布周期结束。

例如,预处理脚本起初看起来像这样,并且没有害处。



我们为什么最初选择这条路? 他为什么看起来不错?



一台发电机很棒,拿走它,连上一次,设置好,它就可以工作。 这似乎是个好方法。 此外,您可以一次对所有语言使用一种注释语法。 您编写了某种指南,使用过一次,立即将所有这些构造插入代码中并进行工作,编写注释,并且不以某种方式固定语法。



但这是最大的缺点之一。 开发人员不支持我们的通用语法,他们习惯于使用自己的IDE,那里已经有本机生成器,并且其语法与我们的语法不匹配。 这是一个绊脚石。

Doxygen还很少支持语言的新功能。 他有选择性的方法,因为他本人是用C ++编写的,所以他主要支持类似C的语言,其余的则根据剩余原理进行支持。 而且语言也在不断改进,Doxygen并没有跟上他们的步伐,这给我们带来了极大的不便。

不幸的是发生了。 一个新的团队来找我们,说我们正在编写Swift,而Doxygen根本不是他的朋友。 我们意识到,一切都该停止,并提出一些新的东西。 然后又有几个团队来了,我们意识到我们的计划根本无法扩展。 我们不断添加一些东西,其中有一些脚本,它们生活在不同的分支中,仅此而已。 我们意识到,我们需要接受运气不好的事情,尝试新的方法和解决方案来寻找。 安德烈(Andrey)将告诉您有关它们的信息。

“我们意识到在我们的情况下,某个地方出现了通用发电机,但是在大多数情况下,当我们开始进行全部扩展时,该计划没有奏效。 他们冷静地提出来,并同意所有人的意愿,但是没有成功。

结果,我们开始提出一个新方案。 她曾在本地发电机工作。 现在电路中有什么? ( , ), , Objective-C Java, , .



, DITA XML, , , , XML. HTML, . — JavaDoc, AppleDoc, Jazzy. HTML, . HTML, , . , HTML . , , , HTML, . XML , . .

.

— . Doxygen , , . Objective-C, , Java . . , , IDE , IntelliSense, , , , SDK, , . .

, , SDK , , , , HTML, . , , , , , .

. , - , . XML , XML . Doxygen , XML . HTML, XML . . — .

, , . 1500 , : HTML, CSS, .

, , .

. ( — . .)

, , .

— . , . -, . , . ? .

? -, , , , .

- , - , . .

? -, , , , .

. , , , , , , , .

, . , , , , , , .

? — , , , , , . . Bitbucket, - . , .



, . . - , - , , , , , , . , , , , .



, , .

, SDK , - , , . -, , , , .

, . . — , , .

, . . .

, , , , , , .



, .

. - , . .



, , , , . . , , , - . , . , , .

, .

. , . , , .

, , , — . , , , .



dev , (fork-dev) , . , doc-dev-en, . , , - , , .

(fork-dev) (doc-dev-ru) . , - . . , , doc-dev-ru, . , , - , .

, . (doc-dev-en). , , (doc-dev-en), , . , (fork-dev). , , , , . , , . , dev . , , , .

(fork-dev), , . (fork-dev), , (doc-dev-en), . , , , . , .



, , . dev, (fork-dev) , (doc-dev-ru) (doc-dev-en) . (doc-dev-en), (doc-dev-ru) . , .



. dev , , (branch-dev). (branch-dev-ru), (branch-dev). , . , . — , — - , , , , .

, , . , , (branch-dev) . , , .

dev. , , , , . .

(branch-dev-ru), , (branch-dev-ru), . .

. (branch-dev), . , , , , , , , , . , , . , , .



, , , , . .

, ? , , . . . , - , . . , .

, , , , , .

, . . . . , , .

— — . — .

. . , . , , , , , , . .

, . . . . , . , . - , . — . .

过程对每个人都应该同样方便。因此,我们没有专政,我们来到开发人员那里说:让我们度过早午餐。他们说他们通过叉子工作。我们说:好吧,但让我们同意,我们也通过分叉来工作。必须达成共识,以便参与此过程的每个人(在本地化,编写代码和代码中的文档中)都具有一致的立场。当每个人都了解自己的职责范围时,这很方便-而不是这样,以便技术作者闭着眼睛工作,看不到代码或无法访问存储库。仅此而已。

Source: https://habr.com/ru/post/zh-CN428057/


All Articles