Skip to main content

预处理器,用于将 API 方法的引用替换为其描述的链接。

项目描述

用于 Foliant 的 APILinks 预处理器

APILinks 预处理器现已弃用。它不会更新,将来可能会被删除。请改用 APIReferences。

预处理器,用于将 Markdown 文件中的 API引用替换为 API 文档网页上实际方法描述的链接。

安装

$ pip install foliantcontrib.apilinks

快速开始

假设您有一个 API 文档托管在 url http://example.com/api-docs

它可能是一个Swagger UI网站或只是一些静态的单页网站(如Slate)。

因此,如果您有一个包含 API 文档的站点,您可能会在其他文档中不时引用它们:

To authenticate user use API method `GET /user/authenticate`.

我们想,如果这个片段:`GET /user/authenticate`自动转换为您的 API 文档网站上的此方法描述的链接,那该有多酷。这就是 APILinks 的用途。

如果您的 API 文档是类似 Slate 的静态网站,请将其添加到您的预处理器列表中:

preprocessors:
    - apilinks:
        API:
            My-API:
                url: http://example.com/api-docs

如果您的 API 文档是 Swagger UI 网站,或者像这样:

preprocessors:
    - apilinks:
        API:
            My-API:
                url: http://example.com/api-docs
                规格http ://example.com/api-docs/swagger.json 

这里:

  • API是必填部分;
  • My-API是您的 API 的本地名称。现在它不是很重要,但在下一个例子中会派上用场;
  • url是一个包含 API 文档网页的完整 URL 的字符串。它将用于验证引用并构造方法的链接;
  • spec是一个包含 OpenAPI 规范文件的完整 URL 的字符串,它将用于为该方法构造正确的锚点。如果您不想每次都下载它,它也可能是本地规范文件的路径。

foliant 应用预处理器后,您的文档将转换为:

To authenticate user use API method [GET user/authenticate](http://example.com/api-docs/#get-user-authenticate).

请注意,预处理器自己找出了正确的锚点#get-user-authenticate。现在,您获得了指向方法描述的链接,而不是方法的简单名称!

好的,如果我有两个不同的 API:客户端 API 和管理 API,该怎么办?

没问题,将它们都放入您的配置中:

preprocessors:
    - apilinks:
        API:
            Client-API:
                url: http://example.com/client/api-docs
            Admin-API:
                url: http://example.com/admin/api-docs
                spec: http://example.com/admin/api-docs/swagger.yml

现在这个来源:

To authenticate user use API method `GET user/authenticate`.
To ban user from the website use admin API method `POST admin/ban_user/{user_id}`

将由 apilinks 转换为:

To authenticate user use API method [GET user/authenticate](http://example.com/client/api-docs/#get-user-authenticate).
To ban user from the website use admin API method [POST admin/ban_user/{user_id}](http://example.com/admin/api-docs/#/user/banUser)

请注意,apilinks 确定第一个引用来自 Client API,第二个引用来自 Admin API。这怎么可能?预处理器从配置中解析每个 API url,并在查找引用之前存储它们的方法。当需要处理引用时,它已经有一个所有方法的列表来验证您的引用并确定应该插入哪个 API 链接。

但是,如果我们在两个 API 中都有同名的方法怎么办?在这种情况下,您将看到一条警告:

WARNING: GET /service/healthcheck is present in several APIs (Client-API, Admin-API). Please, use prefix. Skipping

它建议我们使用前缀,这意味着在 config.xml 中使用 API 的本地名称为引用添加前缀。像那样:

Check status of the server through Client API: `Client-API: GET /service/healthcheck`
Do the same through Admin API: `Admin-API: GET /service/healthcheck`

这里Client-API: Admin-API: 是前缀。它们应该与配置中的 API 名称相同。

现在每个引用都将替换为相应 API 网页的链接。


apilinks 是一个高度可定制的预处理器。你可以调:

  • 参考文献的格式;
  • 将替换引用的输出字符串;
  • API 网页中标题的格式;
  • 和更多!

有关详细信息,请查看以下部分。

词汇表:

  • reference — 对源文件中的 API 方法的引用。要替换为链接的那个,例如GET user/config
  • 动词— HTTP 方法,例如GET,POST等。
  • command — 用于表示 API 文档网页上的方法的资源,例如/service/healthcheck.
  • 端点前缀——从服务器根到命令的前缀。如果命令是/user/status且完整资源是/api/v0/user/satus,则应说明端点前缀/api/v0。在引用中,您可以使用完整资源 ( {endpoint_prefix}/{command}) 或仅使用命令。apilinks 会为你整理出来。
  • output — 字符串,它将替换引用
  • header — 方法描述的 API 文档网页上的 HTML 标头,例如<h2 id="get-user-config">GET user/config</h2>
  • anchor — 指向API 文档网页上特定标头的web-anchor ,例如#get-user-config

它是如何工作的?

预处理器可以在在线离线模式下工作。

在离线模式下,它只是将API 方法的引用替换为指向其描述的链接。引用由正则表达式捕获。链接 url 取自配置,链接锚点自动从参考生成。

您可以在配置中声明几个不同的 API。您可以使用前缀来指出正在引用哪个 API d。可以在配置中自定义前缀格式,但默认情况下您会这样做:Client-API: GET user/name. 这里' Client-API '是一个前缀。

如果您在参考预处理器中不使用前缀,则会假设您的意思是默认 API,它由 config.xml 中的default选项标记。如果它们都没有被标记 - 去列表中的第一个。

请注意,Swagger UI API 网站根本无法在离线模式下工作,因为我们需要下载规范文件 (swagger.json) 以找出方法描述的正确锚点。

在在线模式下,事情变得越来越有趣。预处理器实际上会访问每个 API 网页,并收集所有方法标头。然后它会检查您的文档的来源:当它遇到一个引用时,它会查看所有收集的方法并将引用替换为指向它的正确链接。如果未找到方法 - 预处理器将显示警告并保持引用不变。如果在不同的 API 中有多个具有此名称的方法,也会发生同样的情况。

前面解释过的前缀也受支持。

配置

要启用预处理器,请添加apilinkspreprocessors项目配置中的部分:

preprocessors:
  - apilinks

预处理器有很多选择。为方便起见,所需选项已标记(必需);并且那些在定制中使用的选项被标记为(可选)。您很可能只需要后者中的一两个。

preprocessors:
- apilinks:
    targets:
        - site
    offline: False
    trim_if_targets:
        - pdf
    prefix_to_ignore: Ignore
    reference:
        - regex: *ref_pattern
          only_with_prefixes: false
          only_defined_prefixes: true
          output_template: '[{verb} {command}]({url})'
          trim_template: '`{verb} {command}`'
    API:
        Client-API:
            url: http://example.com/api/client
            default: true
            header_template: '{verb} {command}'
            site_backend: slate
            login: mylogin
            password: mypass
        Admin-API:
            url: http://example.com/api/client
            header_template: '{command}'
            endpoint_prefix: /api/v0
            site_backend: aglio
        Internal-API:
            url: http://example.com/swagger-ui
            spec: http://example.com/swagger-ui/swagger.json
            site_backend: swagger

prefix_to_ignore : (可选)忽略引用的默认前缀。如果 apilinks 遇到带有此前缀的引用,它将保持不变。默认:Ignore

targets :( 可选)foliant make命令支持的目标列表。如果目标未在此处列出 - 将不会应用预处理器。如果列表为空 - 预处理器将应用于任何目标。默认:[]

offline :( 可选)确定预处理器是在线还是离线模式工作的选项。它是如何工作的?在线和离线模式比较部分。默认:False

trim_if_targets :( 可选)将删除文本中所有引用foliant make的前缀的命令目标列表。默认:[]

只有那些前缀在本API节中定义的引用(如下所述)受此选项影响。所有带有未列出前缀的引用都不会被修剪。

reference :( 可选)列出您将在文本中捕获的所有引用类型及其属性的小节。下面列出了此部分的选项。


引用选项 regex :( 可选)用于捕获源中引用的正则表达式。在捕获参考部分中查找详细信息。默认:

(?P<source>`((?P<prefix>[\w-]+):\s*)?(?P<verb>OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT|PATCH|LINK|UNLINK)\s+(?P<command>\S+)`)

only_with_prefixes : (可选)如果是true,则只会转换带有前缀的引用。普通链接之类的GET user/info会被忽略。默认:false

only_defined_prefixes :( 可选)如果这是true所有前缀未在API部分(如下所述)中列出的引用,则将被忽略,保持不变。没有前缀的引用不受此选项的影响。默认值:false

output_template : (可选)描述将替换引用的输出的模板字符串。自定义输出部分中的更多信息。默认:'[{verb} {command}]({url})'

trim_template :( 可选)trim_if_targets仅适用于选项中列出的目标。如果您想自定义 apilinks 如何删除前缀,请调整此模板。引用将替换为基于此模板的文本。默认:'`{verb} {command}`'


API :( 必需)列出所有 API 及其属性的小节。在本节下,每个 API 都应该有一个单独的小节。部分名称代表 API 名称,同时代表引用中使用的前缀。您需要添加至少一个 API 小节才能使预处理器工作。


API 属性

url :( 必需) API 文档网页 URL。它将用于构建该方法的完整链接。在在线模式下,它也将被预处理器解析以进行验证。

spec :( 站点后端需要)URLswaggerredocOpenAPI 规范文件的本地路径。

default :( 可选)仅适用于离线模式。用于定义默认 API 的标记。如果几个 API 被标记为默认,预处理器将选择其中的第一个。如果没有标记为默认 - 将选择列表中的第一个 API。这个项目的价值应该是true

header_template :( 可选)描述 API 文档网页中标题格式的模板字符串。需要从网页中解析方法标题。解析 API 网页部分的详细信息。默认:'{verb} {command}'

endpoint_prefix :( 可选)从服务器根到 API 方法的端点前缀。如果有说明——apilinks 可以将参考中的命令进行划分,更准确地搜索。您也可以在模板中使用它。更多信息即将推出。默认:''

site_backend :( 可选)静态站点生成器的名称,它构建了您的 API 文档网站。这会影响标头如何转换为锚点。默认值:slate。可用选项:aglio, mkdocs, redoc, slate, swagger.

login :( 可选)登录以进行基本身份验证(如果您的 API 站点上存在)。

password :( 可选)基本身份验证的密码(如果存在于您的 API 站点上)。

如果您的 API 文档网站是由另一个静态站点生成器构建的,那么您仍然有机会使其与 APILinks 一起使用,因为它们中的许多使用类似的模式来生成锚点。只需尝试 aglio, mkdocs,之一slate(但不是redocand swagger,这些是特殊的)。如果它不起作用,请给我们发送消息,我们将为您的工具添加支持。

在线和离线模式比较

请注意,Swagger 和 Redoc 站点无法在离线模式下工作

让我们研究一个例子,看看预处理器的行为在在线和离线模式下会如何变化。

我们在配置中描述了三个 API:

preprocessors:
  - apilinks:
      API:
        Admin-API:
            url: http://example.com/api/client
        Client-API:
            url: http://example.com/api/client
            default: true
            header_template: '{verb} {command}'
        Remote-API:
            url: https://remote.net/api-ref/
            header_template: '{command}'

现在让我们看看 Markdown 源代码中使用的文本的不同示例,以及它将如何在离线和在线模式下进行转换

示例 1 来源:

Unprefixed link which only exists in Remote API: `GET system/info`.

离线模式下,预处理器不会进行任何检查,只需将引用替换为配置中指向默认 API 的链接:

Unprefixed link which only exists in Remote API: [GET system/info](http://example.com/api/client/#get-system-info).

这当然是一个错误的决定,但这是我们的错,我们应该在引用中添加前缀。

但是让我们看看在线模式会发生什么:

Unprefixed link which only exists in Remote API: [GET system/info](https://remote.net/api-ref/#system-info).

在没有任何前缀的情况下,预处理器决定它应该选择远程 API 来替换这个引用,因为这个方法只存在于它的页面上。在此模式下,该default选项将被忽略。

顺便说一下,请注意两个示例中的锚点有何不同。对于远程 API 预处理器使用其标头模板来重建锚点,从中删除动词。

示例 2 来源:

Unprefixed link with misprint: `GET user/sttus`.
The link is incorrect, there's no such method in any of the APIs.

离线模式下,预处理器不会再做任何检查。没有魔法,引用将替换为配置中默认 API 的链接:

Unprefixed link with misprint: [GET user/sttus](http://example.com/api/client/#get-user-sttus).
The link is incorrect, there's no such method in any of the APIs.

在线模式下,预处理器将无法在验证期间找到方法,并且根本不会替换引用:

Unprefixed link with misprint: `GET user/sttus`.
The link is incorrect, there's no such method in any of the APIs.

在 Foliant 项目组装期间,您将看到一条警告消息:

WARNING: Cannot find method GET user/sttus. Skipping

示例 3 来源:

Prefixed link to the Admin API: `Admin-API: POST user/ban_forever`.

离线模式下,预处理器会注意到前缀并且能够用适当的链接替换引用:

Prefixed link to the Admin API: [POST user/ban_forever](http://example.com/api/client/#post-user-ban_forever).

请注意,前缀从文本中消失了。如果您希望它留在那里 - 将output_template选项编辑为以下内容:'{prefix}: {verb} {command}'.

在线模式下,结果将完全相同。预处理器将检查 Admin-API 方法,在那里找到引用的方法并在文本中替换它:

Prefixed link to the Admin API: [POST user/ban_forever](http://example.com/api/client/#post-user-ban_forever).

示例 4

Prefixed link to the Remote API with a misprint: `Remote-API: GET billling/info`.
Oh no, the method is incorrect again.

离线模式下,预处理器将不执行任何检查,只需将引用替换为远程 API 的链接:

Prefixed link to the Remote API with a misprint: [GET billling/info](https://remote.net/api-ref/#get-billling-info).
Oh no, the method is incorrect again.

另一方面,在线模式将做功课。它将检查远程 API 是否真的有方法GET billing/info。发现它没有它将保持参考不变:

Prefixed link to the Remote API with a misprint: `Remote-API: GET billling/info`.
Oh no, the method is incorrect again.

...并用以下信息警告我们:

WARNING: Cannot find method GET billling/info in Remote-API. Skipping

示例 5

Now let's reference a method which is present in both Client and Admin APIs: `GET service/healthcheck`.

离线模式下,预处理器只会将引用替换为默认 API 的链接:

Now let's reference a method which is present in both Client and Admin APIs: [GET service/healthcheck](http://example.com/api/client/#get-service-healthcheck).

但在在线模式下,预处理器将遍历所有 API 方法列表。它会发现多次提到这种确切的方法,并且很困惑,根本不会取代参考:

Now let's reference a method which is present in both Client and Admin APIs: `GET service/healthcheck`.

您还将看到一个警告:

WARNING: GET /service/healthcheck is present in several APIs (Admin-API, Client-API). Please, use prefix. Skipping

捕获引用

APILinks 使用正则表达式来捕获对Markdown 文件中 API 方法的引用。

默认的正则表达式如下:

(?P<source>`((?P<prefix>[\w-]+):\s*)?(?P<verb>OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT|PATCH|LINK|UNLINK)\s+(?P<command>\S+)`)

此表达式接受如下引用:

  • Client-API: GET user/info
  • UPDATE user/details

请注意,默认表达式使用命名捕获组。如果要重新定义表达式,您可能也想使用所有这些。尽管并非所有这些都是必需的,但请参见下表。

团体 必需的 描述
资源 是的 完整的原始参考字符串
字首 指向 config 中 API 名称的前缀
动词 HTTP 动词 as GET, POST, 等
命令 是的 API 标头中声明的完整方法资源(可能包括端点前缀)

要重新定义正则表达式reg-regex,请在预处理器配置中添加一个选项。

例如,如果您只想捕获带有前缀的引用,您可以使用以下命令:

preprocessors:
  - apilinks:
      reference:
      - regex: '(?P<source>`((?P<prefix>[\w-]+):\s*)(?P<verb>POST|GET|PUT|UPDATE|DELETE)\s+(?P<command>\S+)`)'

此示例仅用于说明目的。您只需打开该only_with_prefixes选项即可实现相同的目标。

现在,没有前缀 ( UPDATE user/details) 的引用将被忽略。

自定义输出

您可以自定义将替换参考字符串的输出字符串。为此,将模板添加到您的配置文件中。

模板是一个可能包含属性的字符串,用花括号括起来。这些属性将被替换为值,其余的将保持不变。

例如,查看默认模板:

preprocessors:
  - apilinks:
    reference:
      - output_template: '[{verb} {command}]({url})',

不要忘记模板周围的单引号。通过这种方式,我们对 yaml 引擎说这是一个字符串,因为它不会与花括号混淆。

使用默认模板,引用字符串将被替换为:

[GET user/info](http://example.com/api/#get-user-info)

如果您不想将引用转换为链接,请使用您自己的模板。您可以在模板中使用的属性:

财产 描述 例子
网址 方法描述的完整网址 http://example.com/api/#get-user-info
资源 完整的原始参考字符串 ` Client-API: GET user/info`
字首 参考中使用的前缀 Client-API
动词 参考中使用的 HTTP 动词 GET
命令 删除端点前缀引用的 API 命令 user/info
端点前缀 API 的端点前缀(如果endpoint_prefix填写了选项) /api/v0

解析 API 网页

aglio, mkdocs,slate网站后端

在在线模式下,APILinks 会遍历 API 网页内容并收集那里描述的所有方法。

为此,预处理器扫描每个 HTML h1h2h3h4标签并存储其id属性(这是要构造的链接的锚点)和标签的内容(标题本身)。

例如在这个链接中:

<h2 id="get-user-info">GET user/info</h2>

锚点是get-user-info,标题是GET user/info

要构建指向方法描述的链接,我们必须为其创建正确的锚点。要创建锚点,我们需要先重建标题。但是标题格式可能是任意的,这就是我们需要header_template配置选项的原因。

Theheader_template是一个可能包含属性的字符串,用花括号括起来。当预处理器尝试重建航向时,这些属性将被替换为值。其余的将保持不变。

例如,如果您的 API 标题如下所示:

<h2 id="method-user-info-get">Method user/info (GET)</h2>

您应该使用以下选项:

...
API:
    Client-API:
        header_template: 'Method {command} ({verb})'
...

不要忘记模板周围的单引号。这样我们就对 yaml 引擎说这是一个字符串。

如果您的标题根本没有动词:

<h2 id="user-info">user/info</h2>

您应该使用以下选项:

...
API:
    Client-API:
        header_template: '{command}'
...

您可以在模板中使用的属性:

财产 描述 例子
动词 参考中使用的 HTTP 动词 GET
命令 引用的 API 命令 user/info
端点前缀 API 的端点前缀(如果endpoint_prefix填写了选项) /api/v0

swaggerredoc网站后端

对于 Swagger 和 Redoc,它有点不同。为了找出方法描述的正确锚点,我们需要知道operation_id方法。为此,我们需要swagger.json用于生成网站的规范文件 ( )。

这就是为什么 Swagger 和 Redoc 站点 APILinks 解析的不是网站本身,而是规范文件。现在你不能自定义锚格式,对于 Swagger 来说是这样的:

#\{tag}\{operationId}

就像 Redoc 一样:

operation\{operationId}

项目详情