Так уж вышло, что в течение своей деятельности мне немало доводилось работать с публичными API, причем как в со стороны, которая их предоставляет, так и со стороны, которая интегрируется. И здесь я хочу рассказать не только про один из кейсов, который решал ранее, но и поделиться результатами проводимого анализа, полученным опытом, а также набитыми шишками.
Материала вышло многовато, поэтому разбил его на 2 части. В части 1 (этой статье) рассмотрим, почему и зачем вообще публичным API нужна документация, есть ли у нее какие‑то отличия от документации внутренних API, а также проанализируем и детально разберем различные подходы к ведению такой документации, попутно познакомившись поближе с полезными инструментами.
В следующей части затронем уже непосредственно написание документации, подумаем, кто же должен ее писать, какие инструменты могут в этом помочь, как это встроить в реальный процесс разработки и что во всем этом может пойти не так.
Часть 1 — текущая статья
Часть 2 — TBD
Статьями надеюсь помочь созданию удобных и полезных документаций публичных API продуктов упростив всем нам возможные будущие интеграции с ними.
Сразу скажу, что оставляю за рамками темы:
Чем именно наполнять документацию публичных API и что в ней должно быть.
AsyncAPI, GraphQL и прочие стандарты и протоколы, имеющие свои особенности. В статье речь пойдет про REST‑подобные API преимущественно.
Кому может быть интересен материал? Тем, кто страдает от плохой документации публичных API в своем продукте, хочет улучшить онбординг клиентов или сделать процесс документирования API удобнее, а также всем, кого так или иначе касается тема документирования API, ведь многие вещи на самом деле применимы и по‑отдельности, причем не только к публичным API.
И, перед тем как начать, определимся с одним понятием:
Публичный API (Public, External API) — это API‑интерфейс, предназначенный для использования сторонними сервисами, с помощью которого осуществляется доступ к ресурсам вашего продукта.
Иными словами API, с помощью которого выполняют интеграции с вашим приложением.
Вводная часть
Почему про это важно поговорить? Вижу несколько причин.
Вспомните свой опыт интеграции со сторонними продуктами: каково это было? По каким документациям вам приходилось разбираться с чьми‑то API? Насколько часто вы получали актуальную и подробную документацию API продукта? По своему опыту скажу, что далеко не вся документация API, в том числе и крупных сервисов, является таковой, а порой документация представляет вообще Word`овский файл, который писали 5 лет назад (и это не шутка).
Также посмотрим на ситуацию со стороны самих продуктов. Здесь определить актуальность проще, потому что ее можно измерить. Измерить деньгами. Так вот, сколько продуктов сейчас теряют деньги из‑за отсутствия адекватной документации публичных API?
Это может быть упущенная выгода от клиентов, которые отказались от использования продукта, потому что не смогли понять ваши реальные возможности для интеграции, или человеко‑часы вашей команды, которые вы тратите, отвечая на вопросы по работе ваших же методов API: как от клиентов, так и от своих же коллег.
Также часто видим использование для отображения документации одного только бедного Swagger UI. Причем, это касается продуктов самого разного размера. Swagger UI остается самым распространенным инструментом для отображения документации, однако он далеко не единственный в своем роде. И существуют качественные альтернативы, которые так же просты в использовании, но в то же время делают документацию удобнее, и про которые хочется упомянуть и напомнить, что это всего лишь инструменты и, как и для любого инструмента, здесь есть выбор.
Почему важна документация для публичных API
Не стоит говорить о том, что продукт создается для пользователей. И часто мы думаем о том, как сделать так, чтобы продукт решал задачу пользователей, делал их работу (привет, Jobs to Be Done).
Но важно не забывать, какие категории пользователей у вашего продукта есть. И часто это могут быть не только пользователи‑пользователи, но пользователи‑разработчики. А в чем между ними разница? На самом деле, она не такая принципиальная. И те и те взаимодействуют с продуктом через какие‑то интерфейсы. И если для первых это пользовательские интерфейсы, которые вы развиваете и стараетесь делать более дружественными, то для вторых — это скорее программные интерфейсы, ваши API и SDK. Именно поэтому, как есть термин UX, так есть и термин DX или DevX, который как раз направлен на опыт разработчика при работе с чем‑либо.
И логично, что здесь важно, как выглядит ваше публичное API, насколько качественно и успешно оно может решить задачу приходящего к нему пользователя. А пользователь обычно приходит с простой задачей — для обретения некоей своей бизнес‑ценности выполнить интеграцию с продуктом.
И первое, что он встречает на своем клиентском пути — наша документация API. А теперь сравните, какое впечатление произведет неполное или неоднозначное описание API, которое ему после запроса вышлют в файле или читабельная и структурированная документация, по которой можно вести разработку, не прибегая к необходимости задавать вопросы. Это, конечно, две крайности, однако они наглядно демонстрируют разницу.
Удобство работы с вашими публичными API напрямую зависит в том числе и от качества их документации. Публичные API — такое же лицо нашего продукта, просто повернутое к другой категории пользователей.
Да, можно говорить про то, что идеальное API не нуждается в документации и должно быть самоописывающим, есть даже целые книги, где продвигается такая идея, однако в реальности документация все же помогает разработчикам узнать нюансы и детали, которые влияют тем больше, чем больше требования к надежности данной интеграции.
Поэтому в ряде случаев имеет смысл учитывать и такую категорию ваших пользователей. Про это, к слову, говорит концепция API as Product.
Документация публичных и внутренних API: есть отличия?
Про подходы к документированию API в интернете написано много. Но часто в сообществах разработки явно не разделяется документация внутренних и внешних API. Чтобы понять, есть ли между ним разница, рассмотрим три примера.
Кто есть пользователь, что он знает и умеет?
Если говорить про внутренние API, то это обычно наш коллега, и он скорее всего будет хоть как‑то знаком с предметной областью и хоть что‑то будет знать про сам продукт (но все равно сильно надеяться на это не стоит).
В случае внешних API пользователь — довольно абстрактное лицо, и он вполне может не знать ничего про особенности нашей предметной области и специфику работы продукта, для него информация должна быть понятна практически без контекста.
Получение ответа на свой вопрос
Когда у нас возникает вопрос по работе внутреннего API и мы не можем сами найти на него ответ, какое будет наше самое первое действие? Вероятно, пойти и написать в чат тому, кто это API делал, либо посмотреть самостоятельно его реализацию в коде.
В случае внешних API таких опций мы зачастую лишены. И вопрос нам придется задавать в поддержку или в клиентского менеджера при его наличии. Если в самой документации ответа на вопрос нет, первые линии поддержки помочь нам вряд ли смогут, и получение ответа легко может растянуться на несколько дней.
Цена имиджа
Когда мы говорим про внутреннюю документацию, то даже если разработчик допустит в описании какие‑то ошибки естественного языка (грамматические, орфографические, синтаксические и пр.), при этом сохранив однозначность трактовки, это не буде являться большой проблемой, и от этого в большинстве случаев никто не помрет.
Публичная документация же — лицо нашего продукта, и здесь имидж нам важен. Никакому продукту не хочется предоставлять клиентам описания, в которых есть явные ошибки или несоответствия стилю продукта, например.
Кроме того, для внутренней документации как хорошую практику имеет смысл рассмотреть генерацию документации из кода, потому что здесь банально важнее именно актуальность документации и схемы, чем ее грамотные и выверенные описания. Причем это можно спокойно совмещать с Design‑first подходом: сначала upfront накидывается спецификация, по ней ведется разработка, а в результате в документацию уходит уже железно та реализация, которая была выполнена, с ее деталями.
Пару слов про Code-first и Design-first подходы
Также чтобы дальше нам правильно понимать некоторые вещи, вкратце упомяну про два известных подхода.
Code‑first подход предполагает, что разработчики сперва делают имплементацию API, а затем на ее основе создают документацию. Часто это делается автоматизировано с использованием комментариев или аннотаций.
Design‑first, иногда называемый API‑first полагается на то, что сначала мы планируем и описываем контракт API таким, каким он должен быть, и уже затем, когда он определен, делаем имплементацию на его основе (иногда также автоматизируя этот процесс).
Справедливо заметить, что оба этих подхода в общем случае — крайности, и часто в реальности мы видим нечто между ними, смещенное в ту или иную сторону.
Design-first и аналитики, а еще причем тут Style Guide
При всем этом, если у вас есть аналитики, бизнес‑ или системные, то при Design‑first подходе совершенно не обязательно они должны проектировать API самостоятельно. Наоборот, вполне хорошей практикой считаю проектировать их вместе с разработчиками на основе выявленных аналитиками требований к API. Или, по крайней мере, валидировать свои предложения.
Ведь никто не говорит, что разработчик может и должен подключаться только на некоем волшебном этапе «разработки». Напротив, при ранней совместной работе и коллаборации шансы на успех куда выше. И куда лучше будет результат, нежели чем если спецификацию сам написал какой‑то аналитик, чего‑то не учел, и потом эту задачу молча «распределили» на какого‑то разработчика.
Также есть простой вариант, когда аналитик приносит именно требования, а не полный дизайн API. При наличии Style Guide для вашего API не обязательно сразу упираться в имплементацию, а вполне достаточно сперва ограничиться требованиями. Если разработчики следуют Style Guide, то результат будет вполне предсказуемый и обладающий необходимыми атрибутами качества. На мой взгляд, польза от того, чтобы задизайнить API аналитиками сразу вместо требований к нему, обычно сводится к двум вещам:
получить заранее до начала разработки контракт, чтобы другие стороны могли начать по нему вести разработку;
обеспечить нужное качество методов API, если разработчики об этом не думают и пишут каждый по своему.
Кажется, и первое и второе решается далеко не только перекладыванием вопроса проектирования контракта на аналитиков полностью.
Какие проблемы хотим решить и какие есть?
Здесь начать хочу с того, что нет смысла делать документацию «просто так» или «потому что у всех есть». Как и везде, документация публичного API должна решать какие‑то конкретные задачи и давать определенную пользу. Поэтому перед тем как думать, а какой она должна быть и как ее делать, стоит понять, а какие наши проблемы она должна решать, причем полезно бывает их также проскорить и приоритизировать, чтобы понять их важность.
Вот примеры типовых проблем, которые встречал чаще всего:
Актуальность документации плохо поддерживается, описания устаревают и не обновляются;
Клиенты не могут самостоятельно выполнить интеграцию с продуктом, задают схожие вопросы, ответы на которые тратят время сотрудников;
Затрудняются типовые клиентские интеграции, для них требуется участие аналитиков (или других сотрудников), которые описывают одни и те же API в разных местах;
Новым сотрудникам трудно и долго изучать текущие возможности, потому что информация не консолидирована;
Нет единого источника правды, информация может разниться между ресурсами и людьми;
За информацией люди ходят не в документацию, а к «хранителям знаний»;
Клиентам непонятно, чем API им могут быть полезны и какие задачи с помощью них можно решить;
Есть задачи, которые изменяют API, при этом не изменяя его документацию;
Документация не включает в себя нюансы и ограничения (аутентификация, rate limits, ошибки, обязательность параметров и их точные описания и пр.).
Список таких проблема для вашего продукта будет наверняка другой, но важно четко понимать, для чего вы делаете себе документацию API, это поможет в том числе сделать акцент на верные ее разделы для решения конкретных задач, которые болят именно у вас.
Некоторые проблемы, скажу заранее, будут решаться не только документацией публичного API, а уже следующими шагами — Developer portal и улучшением онбординга ваших клиентов в целом, но здесь пока это не будем останавливаться на этом подробно.
Обзор подходов к ведению документации API
Итак, давайте наконец попробуем рассмотреть различные подходы к документированию API. Чтобы это было проще понять, разобьём их по категориям - примерно такими же уровнями я двигался сам, когда анализировал тему.
Далее пройдемся по всем уровням, рассмотрим широкую картину, а затем поделюсь для примера мотивами выбора для решения моего кейса.
Первый уровень: по подходу к описанию
Здесь классификацию ведем на основе того, в каком виде вообще будем подходить к документированию. Рассмотрим 3 основные группы:
1. IDL - Interface Definition (Description) Language
IDL в данном случае является разновидностью DSL — Domain Specific Language. Тема использования IDL не нова и вполне успешно применяется для формализации контрактов различных интерфейсов в разработке. Применительно к веб‑API подход предполагает использование IDL как дополнительного уровня абстракции над конечной спецификацией. То есть сначала мы описываем наш API с использованием IDL, а затем на основе него при необходимости генерируем, например, OpenAPI‑спецификацию. Примерами известных IDL можно называть Smithy от Amazon и TypeSpec (бывший Cadl) от Microsoft.
Если вы захотите копнуть глубже в эту тему, вероятно, рано или поздно наткнетесь на книжку «The Language‑Oriented Approach to API Development» by Stephen Mizell. При том, что новое из нее узнать можно, хочу предупредить, что подача автора там сильно однобокая в сторону преимуществ IDL, поэтому не забывайте держать ваше критическое мышление включенным.
2. Стандартизированные спецификации
Здесь немного хитрим: фактически указанные здесь "стандарты" by definition являются теми же IDL. Однако ввиду факта, что IDL мы назвали еще одним дополнительным уровнем абстракции, а также широкой распространенности этих стандартов, их мы вынесем в отдельную группу.
Для RESTful и не только API существуют различные стандарты спецификаций, которые имеют свою четкую структуру и формат и за счет этого дают возможность работать со спецификацией на различных стадиях различными инструментами, такими как редакторы, валидаторы и линтеры, mock-серверы, средства для просмотра и прочие. Наиболее известными стандартами можно назвать OpenAPI, Blueprint и RAML.
А как же JSON Schema?
Очень часто можно услышать, что «мы описываем API в JSON Schema». И на самом деле, здесь нет никакого противоречия: JSON Schema хорошо ложится на описание данных (например, запроса и ответа метода).
В то же самое время OpenAPI позволяет описать API целиком, который представляет из себя больше, чем просто описание данных для методов. Более того, начиная с версии 3.1 OpenAPI Specification является совместимой с JSON Schema. Поэтому предлагаю разделять эти два понятия не как нечто противоположное, а скорее как идущие рядом вещи, которые вполне могут использоваться сообща, беря лучшее от обоих форматов.
3. Произвольные текстовые форматы
Под произвольными текстовыми форматами будем понимать любые сколь‑нибудь rich text‑подобные редакторы, которые позволяют записывать форматированный текст и имеют встроенные средства его отображения. В данном случае мы создаем «условный» шаблон для нашей спецификации и визуально проверяем описание на соответствие ему. Это можно делать, например, с использованием публичного раздела в Confluence, на основе Google Docs, используя Github wiki или же просто Github‑репозиторий с markdown‑файлами.
Также можно использовать static site generators на основе markdown‑файлов, такие как MkDocs или Docusaurus. Главное отличие в том, что наше описание не имеет под собой «жесткой» структуры, формат будет достаточно произвольным и непростым для автоматизированной обработки, но зато начать писать документацию можно гораздо быстрее. В качестве примеров можно посмотреть на документацию gRPC Tinkoff Invest API (использующих как раз MkDocs) или на документацию HeadHunter API на основе markdown‑файлов на GitHub.
Второй уровень: по стандарту описания
Здесь выделим трех основных кандидатов: OpenAPI, RAML и API Blueprint. Сравнительно их особенности можно представить так:
Для лучшего понимания можно посмотреть на примеры их синтаксиса, слева-направо: OpenAPI, RAML, API Blueprint
Еще важно упомянуть про распространенность данных форматов и тенденцию их развития — ведь нам дальше еще жить с нашим решением. Здесь можно посмотреть статью от Postman RAML and API Blueprint: where are they now?, а также результаты проведенного ими же исследования за 2022 год:
Помечу, что Swagger 2.0 – это также OpenAPI стандарт, просто название идет от прошлой его версии.
О версиях OpenAPI
Здесь можно отметить, что по популярности и своему развитию OpenAPI действительно опережает соседей и, кажется, что такой тренд будет только продолжаться.
Третий уровень: в каком виде отображаем (предоставляем)
В этом разрезе вижу следующие варианты:
Self-hosted Open Source tools: Redoc, RapiDoc, Swagger UI, etc.
SaaS-решения: Redocly, ReadMe, DeveloperHub, Stoplight, etc.
Сравним их снова в табличном виде:
Использование Static site generators для отображения документации API — довольно популярный подход. Здесь мы имеем наибольшую гибкость и ограничены только нашими возможностями и воображением, но в то же время создание подобных вещей — не самая дешевая процедура и часто на старте бывает логичнее посмотреть на более простые варианты.
Open Source инструменты здесь как раз могут быть помощниками в таком подходе. Подобрав верный под свои нужды, мы можем иметь достаточную функциональность «из коробки», потратив сначала минимальные усилия на тюнинг, и уже затем по появлении потребностей дорабатывать инструмент под себя.
Использование Software as a Service в своих продуктах является достаточно холиварной темой. С одной стороны, есть мнения про наличие тренда в корпоративном управлении финансами по переводу CAPEX в OPEX в связи в том числе с желанием повысить мобильность средств и меньше хоронить их в капитальных расходах (хотя в этом случае расходы довольно небольшие). Да и вообще звучит красиво ведь: мы платим и скидываем с себя часть работы. С другой стороны, лишний SaaS — это всегда выбор стратегии «risk transfer» — передачи риска, известной техники в risk management. И мы в таком случае должны думать, что будет, если со сторонним сервисом что‑то пойдет не так. Ну и не стоит забывать про особенности работы иностранных сервисов с компаниями в РФ, что в последние годы стало наиболее актуальным.
Принятие решения
Выше постарался сделать классификацию, которая показывает общую картину, а также альтернативные варианты для каждой категории.
Выбор подходящего варианта всегда будет зависеть от ваших возможностей и потребностей.
Для себя же, когда решали описываемый кейс, сделали выбор сначала в пользу стандартизированных подходов, желая иметь "единый источник правды" и в то же время не брать дополнительный overhead в виде IDL. Как стандарт взяли OpenAPI, его широкая распространенность, долгая история и функциональность (с v3.1 завезли даже полноценные вебхуки, кроме callbacks) сыграли роль в этом. Проблему сложности написания "machine-readable" спецификации намеревался все же решить путями, про которые поговорим далее. С точки зрения отображения спецификации выбор был между Open Source инструментами и Stoplight, как наиболее приглянувшимся тогда SaaS. Но предвидя риски и не желая ради достаточно простой задачи добавлять зависимость в виде SaaS, выбрали все же поставить инструмент у себя сами, что на деле действительно совсем не сложно.
Не Swagger’ом единым
Теперь рассмотрим ближе тему отображения документации. Начнем с того, что напомню, что сердце вашей OpenAPI‑спецификации — это сам OpenAPI‑файл. А как его отображать — это вообще отдельный вопрос. Сформированный файл можно отобразить с помощью любого инструмента, и им совершенно не обязательно должен быть Swagger UI.
Сначала, чтобы устранить все недопонимания, разберемся с определениями.
Swagger сейчас — это набор инструментов для разработки API, которые поддерживает компания SmartBear Software. Ранее также слово служило названием одноименного стандарта, который с версии 3.0 называется OpenAPI.
Swagger UI — один из инструментов Swagger, используемый для отображения документации на основе OpenAPI‑файла спецификации. Иными словами это лишь один из инструментов, который никак не «прибит» к самому файлу спецификации.
Как мы отмечали выше, популярность инструмента Swagger UI превосходит все ожидания, и большинство OpenAPI‑спецификаций, которые вы видите, отображаются в нем. Однако является ли это следствием того, что он лучший и самый удобный? По моему опыту взаимодействия с этим инструментом с разных сторон я так сказать не могу.
Для тех, кто имел счастье забыть, как же это выглядит, напомним:
Из особенностей Swagger UI могу выделить следующее:
Сфокусирован на отображении описания методов, а не API в целом
Используется one‑panel компоновка, на странице только один блок со всей информацией
Не так удобно отображать дополнительную информацию, страница становится длинной
Методы идут списком, поиск не предусмотрен
«Своеобразное» представление описания параметров тела методов
Кастомизация не самая простая и часто вызывает боль
Какие есть альтернативы? Рассмотрев различные Open Source варианты, я могу выделить RapiDoc и Redoc, из достойных это, увы, все. Есть еще, конечно, форки или менее используемые инструменты, однако все они проигрывают или в использовании, или в функциональности.
Пример того, что RapiDoc и Redoc из себя представляют:
Больше примеров можно увидеть вживую:
RapiDoc |
Redoc |
Кратко посмотрим на основные сравнительные характеристики:
И добавлю свое резюме по обоим инструментам,
RapiDoc. Хороший вариант, удобное представление формата тела запроса/ответа, очень богатая кастомизация, можно вызывать запросы со страницы. Можно обновлять спецификацию и страницу отдельно (может быть и плюсом, и минусом). Репозиторий живой, обновления есть, на issues отвечают, есть даже чат в Discord (после спонсирования от Zuplo).
Redoc. Неплохой вариант для быстрого старта, если не критично отсутствие «Try it» функциональности, можно сочетать с их CLI‑утилитой для проверки и быстро сделать свой воркфлоу. Из коробки есть Server‑side rendering (SSR), что может быть полезно для больших спецификаций. Поговаривают, что поддержка и развитие не очень, авторы сосредоточились на платной версии (Redocly).
Здесь для себя сделал выбор в пользу RapiDoc, из‑за его «true Open Source» натуры и уж совсем богатого набора фичей, включая встроенные API (не http‑API, а свои программные интерфейсы) для еще большей кастомизации.
Также прилагаю ссылку на полную таблицу‑сравнение инструментов, где присутствуют и SaaS‑варианты, которые сравнивал для себя. Сравнение делал еще в 2021 году, но постарался актуализировать для текущего дня.
Под катом скриншот этой таблицы
Дополнительно можно почитать про сравнения от различных пользователей в одном из issues на GitHub RapiDoc - Pros and cons between Swagger UI, Redoc, RapiDoc.
Таким образом мы разобрались с тем, зачем нам в принципе может быть нужна документация, чем она может отличаться для внутренних и публичных API, посмотрели на примеры типовых проблем и обратили внимание, что проблемы у каждого бывают свои.
А также разобрали некоторую классификацию подходов к созданию документации API на трех уровнях: по подходу к описанию, по стандарту и по способу отображения.
Далее - сам процесс написания документации
Эту тему продолжим разбирать уже во 2 части статьи.
Комментарии (3)
vagon333
26.07.2023 16:22Хорошо бы добавить опрос - кто чем пользуется (Swagger UI, RapiDoc, Redoc, other).
Пробовали Redoc - откатились обратно на Swagger UI.
Причина тривиальна - пользователям проще.
gluck59
26.07.2023 16:22+2В 2016 я получил свой первый оффер в качестве программиста, в одну финтех-компанию в клиентскую поддержку. Директор рассказала, что на разрабов сыпется вал вопросов по интеграции и что "ребятам надо бы код пилить, а у них полный швах с вопросами от клиентов, и вот мы решили взять специального человека для этого".
Вникнув в проблему, я обнаружил что документация API представляет собой docx-файл, в котором намешаны разрозненные данные об услугах организации, об ее конкурентных преимуществах (!), чуть ли не в строку перечислены точки входа в API, и иногда пропущены объяснения за какой функционал какая точка отвечает. Вплоть до разных шрифтов (которые конечно ни на что не влияют, но лопни мои глаза)...
Я был новеньким в компании, над программистами висел полугодовой бэклог и мои вопросы чаще всего оставались без ответа. Тогда я взял Postman, перелопатил весь API с начала до конца, попутно пофиксил пару багов и добавил недостающие как мне казалось методы к нему (спросив, конечно, у тимлида).
Действительно: если хочешь в чем-то досконально разобраться — напиши об этом туториал...
Этот подход сработал и через пару месяцев я выкатил новую доку (на сей раз в html, и оформленную как ожидают программмисты), запихал ее в подходящий пункт меню на сайте, а вордовский файл упразднил. Придумал включать в доку эндпоинты только для тех услуг, на которые был подписан текущий клиент, благодаря чему показываемая на экране дока сухднула раз в 5 — каждый конкретный клиент пользовался отнюдь не всеми услугами компании.
Результат не заставил себя долго ждать: изо всего вала вопросов новых клиентов остался... один. Его задавали практически 100% новых клиентов и звучал он "а как в 1С сделать POST запрос?", на который я загуглил ответ (сорри, я не 1Сник) и вывесил его на видное место в желтом диве :)
"Мавр сделал свое дело, мавр может уходить". Я был готов к тому что мненя уволят за ненадобностью, но мне неожиданно повысили зарплату и перевели в одтел разработки, сохранив обязанность отвечать на вопросы клиентов. Я выкатил тикет-систему (запилив прозрачную авторизацию в ней при переходе из клиентской части) и с ней стало легко систематизировать вопросы и отвечать уже заранее заготовленными (простите если кого этим оскорбил) ответами.
Вся эта конструкция из новой доки и тикет-трекера проработала примерно с год, пока второе лицо в организации (о, у него была прикольная должность "муж директора") не обнаружило, что когда-то написанный им docx-файл упразднен и заставил меня... убить мою доку и восстановить его файл.
Но это уже совсем другая история, в которой "второе лицо" прилюдно получило от директора, люто возненавидело меня и в конце концов мне из-за этого пришлось уйти...
amateur80lvl
Самая адовая документация по API с которой приходилось работать - это RKD от рейтерс. Хорошее почему-то не запоминается