APIReferences¶
APIReferences Preprocessor for Foliant¶
APIReferences is a successor of APILinks preprocessor with slightly changed configuration syntax and completely rewritten insides. APILinks is now deprecated, please use APIReferences instead.
Preprocessor replaces API references in markdown files with links to the corresponding method description on the API documentation web-page.
What is it for?¶
Say, you have API or DB documentation hosted at the url http://example.com/api-docs
It may be a Swagger UI website or just some static one-page site (like Slate).
If you have a site with API docs, you probably reference them from time in your other documents:
To authenticate user use API method `POST /user/authenticate`.
We thought, how cool it'd be if this fragment: `POST /user/authenticate` automatically transformed into a URL of this method's description on your API docs website:
To authenticate user use API method [POST user/authenticate](http://example.com/api-docs/#post-user-authenticate).
That's exactly what APIReferences does.
How does it work?¶
The purpose of APIReferences is to convert references into links. In the example above `POST /user/authenticate
` is a reference, and [POST user/authenticate](http://example.com/api-docs/#post-user-authenticate)
is a Markdown link, the result of APIReferences' work.
The resulting link URL (http://example.com/api-docs/#get-user-authenticate) always consists of two parts: {url}{anchor}
. url
is static and is set in config, but anchor
differs for each method. Open your API documentation website and look for HTML elements with id
attribute near method description sections. When you add this id
to the website's URL with number sign # (we call this combination an anchor), your browser scrolls the page to this exact element.
The tricky part is to determine which anchor should be added to the website's URL for each method. APIReferences offers several ways to do that, we call these ways modes (which are supplied in the mode
parameter). It's up to you to choose the most suitable mode for your API website.
Here are available modes with their short descriptions. Detailed descriptions and examples are in the User Guide below.
1. Generating anchors
Mode option: generate_anchor
Convert reference into an anchor without checking the website.
2. Find anchor
Mode option: find_by_anchor
Parse API website and collect all ids from specific tags. Then convert reference into an anchor and check whether the converted anchor is present among these ids.
3. Find tag content
Mode option: find_by_tag_content
This mode searches not by tag ids but by tag content (<tag id="id">content</tag>
) Parse API website and collect all tags from the specified list, which have ids and text content. The content to search is constructed from the reference. If the tag is found, return a link to its id.
4. Find method in swagger spec for SwaggerUI
Mode option: find_for_swagger
Parse the swagger spec file and find the referenced method. The anchor is then constructed by a template. This mode will work for SwaggerUI websites.
5. Find method in swagger spec for Redoc
Mode option: find_for_redoc
Parse the swagger spec file and find the referenced method. The anchor is then constructed by a template. This mode will work for Redoc websites.
APIReferences is a highly customizable preprocessor. You can tune almost anything about reference conversion.
For details look through the following sections.
Glossary:
- reference — reference to an API method in the source file. The one to be replaced with the link, e.g.
GET user/config
- verb — HTTP method, e.g.
GET
,POST
, etc. - command — resource used to represent method on the API documentation webpage, e.g.
/service/healthcheck
. - endpoint prefix — A prefix from server root to the command. If the command is
/user/status
and full resource is/api/v0/user/status
then the endpoint prefix should be stated/api/v0
. In references, you can use either full resource ({endpoint_prefix}/{command}
) or just the command. APIReferences will sort it out for you. - output — string, which will replace the reference.
- tag content — plain text between the tags, for example
<tag>Tag content</tag>
. - anchor — web-element id with leading number sign, for example
#get-user-config
. Adding the anchor to the end of the web URL will make a browser scroll to the specified web element. - mode — the way APIReferences will determine correct anchors to add to website URLs.
Quick Recipes¶
Recipe 1: find by tag content¶
We want reference `GET /user/status
` to be pointed at this element on our API website:
<h2 id="get-user-status">Operation GET /user/status</h2>
Minimal sufficient foliant.yml:
preprocessors:
apireferences:
API:
My-API:
mode: find_by_tag_content
url: http://example.com/api # path to your API website
content_template: 'Operation {verb} {command}'
`GET /user/status
` -> GET /user/status
Recipe 2: find by tag id¶
The task is the same as in Recipe 1. We want reference `GET /user/status
` to be pointed at this element on our API website:
<h2 id="get-user-status">Operation GET /user/status</h2>
Minimal sufficient foliant.yml:
preprocessors:
apireferences:
API:
My-API:
mode: find_by_anchor
url: http://example.com/api # path to your API website
anchor_template: '{verb} {command}'
anchor_converter: slate
`GET /user/status
` -> GET /user/status
Recipe 3: generate tag id¶
The task is the same as in Recipes 1 and 2, but this time you don't have access to API website at the time of building foliant project. We want reference `GET /user/status
` to be pointed at this element on our API website:
<h2 id="get-user-status">Operation GET /user/status</h2>
Minimal sufficient foliant.yml:
preprocessors:
apireferences:
API:
My-API:
mode: generate_anchor
url: http://example.com/api # path to your API website
anchor_template: '{verb} {command}'
anchor_converter: slate
`GET /user/status
` -> GET /user/status
Recipe 4: find link for SwaggerUI¶
We have a SwaggerUI website, and we need to find the link to the method by reference `GET /user/status
``.
Method anchors on SwaggerUI consist of tag and operationId, both of which are not present in our reference. APIReferences can find them for you in the spec file. Let's assume that correct tag and operationId are usertag
and getStatus
.
Minimal sufficient foliant.yml:
preprocessors:
apireferences:
API:
My-API:
mode: generate_for_swagger
url: http://example.com/swagger_ui # path to your API website
spec: !path swagger.json # path or direct url to OpenAPI spec
`GET /user/status
` -> GET /user/status
Installation¶
$ pip install foliantcontrib.apireferences
Config¶
To enable the preprocessor, add apireferences
to preprocessors
section in the project config:
preprocessors:
- apireferences
The preprocessor has a lot of options. For your convenience, the required options are marked (required); and those options which are used in customization are marked (optional). Most likely you will need just one or two of the latter.
preprocessors:
- apireferences:
targets: # optional. default: []
- site
trim_if_targets: # optional. default: []
- pdf
prefix_to_ignore: Ignore # optional
warning_level: 2 # optional
reference: # optional
- regex: *ref_pattern
only_with_prefixes: false
only_defined_prefixes: false
output_template: '[{verb} {command}](https://github.com/foliant-docs/foliantcontrib.apireferences/-/blob/master/{url})'
trim_template: '`{verb} {command}`'
- regex: *another_ref_pattern # second reference config. Unlisted options are default
output_template: '**{verb} {command}**'
API: # below are examples for each mode
Client-API: # reference prefix
mode: generate_anchor
url: http://example.com/api/client
anchor_template: '{verb} {command}'
anchor_converter: pandoc # optional
endpoint_prefix: /api/v1 # optional
endpoint_prefix_list: [/api/v1/,/api/v2/,/api/v3/]
Admin-API:
mode: find_by_anchor
url: http://example.com/api/admin
anchor_template: '{verb} {command}'
anchor_converter: pandoc # optional
endpoint_prefix: /api/v1 # optional
tags: ['h1', 'h2', 'h3', 'h4'] # optional
login: login # optional
password: password # optional
External-API:
mode: find_by_tag_content
url: http://example.com/api/external
content_template: '{verb} {command}'
endpoint_prefix: /api/v1 # optional
tags: ['h1', 'h2', 'h3', 'h4'] # optional
login: login # optional
password: password # optional
Inernal-API:
mode: find_for_swagger
url: http://example.com/api/swagger-ui
anchor_template: '/{tag}/{operation_id}'
anchor_converter: no-transform
endpoint_prefix: /api/v1 # optional
login: login # optional
password: password # optional
targets
- (optional) List of supported targets for
foliant make
command. If target is not listed here — preprocessor won't be applied. If the list is an empty — preprocessor will be applied for any target. Default:[]
trim_if_targets
- (optional) List of targets for
foliant make
command for which the prefixes from all references in the text will be cut out. Default:[]
Only those references whose prefixes are defined in the
API
section (described below) are affected by this option. All references with unlisted prefixes will not be trimmed.
prefix_to_ignore
- (optional) A default prefix for ignoring references. If APIReferences meets a reference with this prefix, it leaves it unchanged. Default:
Ignore
warning_level
- (optional)
2
— show all warnings for not found references;1
— show only warnings for not found prefixed references;0
— don't show warnings about not found references. Default:2
use_multiproject_mode
- (optional) - Use cached API registries in case of multiproject. Default:
True
reference
- (optional) List of dictionaries. A subsection for listing all the types of references you are going to catch in the text, and their properties. Options for this section are listed below.
All reference properties have defaults. If any of them are missing in the config, the defaults will be used. If
reference
section is omitted, APIReferences will use default values.
Reference options
regex
- (optional) regular expression used to catch references in the source. Look for details in the Capturing References section. Default:
`\s*((?P<prefix>[\w-]+):\s*)?(?P<verb>OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT|PATCH|LINK|UNLINK)\s+(?P<command>[^`]+)\s*`
only_with_prefixes
- (optional) if this is
true
, only references with prefix will be transformed. Ordinary links likeGET user/info
will be ignored. Default:false
only_defined_prefixes
- (optional) if this is
true
all references whose prefix is not listed in theAPI
section (described below) will be ignored. References without prefixes are not affected by this option. Default:false
. output_template
- (optional) A template string describing the output which will replace the reference. More info in the Customizing Output section. Default:
'[{verb} {command}](https://github.com/foliant-docs/foliantcontrib.apireferences/-/blob/master/{url})'
trim_template
- (optional) Only for targets listed in
trim_if_targets
option. Tune this template if you want to customize how APIReferences cuts out prefixes. The reference will be replaced with a text based on this template. Default:'
{verb} {command}'
API
- (required) A subsection for listing APIs and their properties. Define a separate subsection for each API here. The section name represents the API name and, at the same time, the prefix used in the references. You need to add at least one API subsection for the preprocessor to work.
API properties
The list of options and some default values differ for each mode.
mode
- (required) API mode, which determines how references are collected. Available modes:
generate_anchor
,find_by_anchor
,find_by_tag_content
,find_for_swagger
,find_for_redoc
.
generate_anchor
mode
url
- (required) An API documentation web-page URL. It will be used to construct the full link to the method.
anchor_template
- (required) A template string describing the format of the anchors in the API documentation web-page. You can use placeholders in {curly braces}, with names of the groups from the reference regex. Example:
'user-content {verb} {command}'
. anchor_converter
- (optional) anchor converter from this list. Determines how string
GET /user/status
is converted intoget-userstatus
orget-user-status
etc. List of available converters. Default:pandoc
endpoint_prefix
- (optional) The endpoint prefix from the server root to API methods. If is stated — APIReferences can divide the command into the reference and search for it more accurately. Also, you could use it in templates. More info in the Commands and Endpoint Prefixes section. Default:
''
endpoint_prefix_list
- (optional) The list of available endpoint prefixes which could be added to output. Default:
[]
trim_query
- (optional) Cut a query part after
?
character from command while searching for an API link. Default:True
find_by_anchor
mode
url
- (required) An API documentation web-page URL. It will be used to construct the full link to the method. In this mode, it is also being parsed to check whether the generated anchor is present on the page.
anchor_template
- (required) A template string describing the format of the anchors in the API documentation web-page. You can use placeholders in {curly braces}, with names of the groups in the reference regex. Example:
'user-content {verb} {command}'
. anchor_converter
- (optional) anchor converter from this list. Determines how string
GET /user/status
is converted intoget-userstatus
orget-user-status
etc. Default:pandoc
endpoint_prefix
- (optional) The endpoint prefix from the server root to API methods. If is stated — APIReferences can divide the command into the reference and search for it more accurately. Also, you could use it in templates. More info in the Commands and Endpoint Prefixes section. Default:
''
endpoint_prefix_list
- (optional) The list of available endpoint prefixes which could be added to output. Default:
[]
tags
- (optional) list of HTML tags which will be parsed out from the page and searched for ids. Default:
['h1', 'h2', 'h3', 'h4']
login
- (optional) Login for basic authentication if present on your API site.
password
- (optional) Password for basic authentication if present on your API site.
trim_query
- (optional) Cut a query part after
?
character from command while searching for an API link. Default:True
find_by_tag_content
mode
url
- (required) An API documentation web-page URL. It will be used to construct the full link to the method. In this mode, it is also being parsed to check whether the generated anchor is present on the page.
content_template
- (required) A template string describing the format of the tag content in the API documentation web-page. You can use placeholders in {curly braces}, with names of the groups in the reference regex. Example:
'{verb} {command}'
. endpoint_prefix
- (optional) The endpoint prefix from the server root to API methods. If is stated — APIReferences can divide the command into the reference and search for it more accurately. Also, you could use it in templates. More info in the Commands and Endpoint Prefixes section. Default:
''
endpoint_prefix_list
- (optional) The list of available endpoint prefixes which could be added to output. Default:
[]
tags
- (optional) list of HTML tags which will be parsed out from the page and searched for ids. Default:
['h1', 'h2', 'h3', 'h4']
login
- (optional) Login for basic authentication if present on your API site.
password
- (optional) Password for basic authentication if present on your API site.
trim_query
- (optional) Cut a query part after
?
character from command while searching for an API link. Default:True
find_for_swagger
mode
url
- (required) An API documentation web-page URL. It will be used to construct the full link to the method.
spec
- (required) URL or local path to OpenAPI specification file.
anchor_template
- (optional) A template string describing the format of the anchors in the API documentation web-page. You can use placeholders in {curly braces}, with names of the groups in the reference regex. In this mode, you can also use two additional placeholders:
{tag}
and{operation_id}
. Default:'/{tag}/{operation_id}'
. endpoint_prefix
- (optional) The endpoint prefix from the server root to API methods. You may use it in output template. Default:
''
endpoint_prefix_list
- (optional) The list of available endpoint prefixes which could be added to output. Default:
[]
login
- (optional) Login for basic authentication if present on your API site.
password
- (optional) Password for basic authentication if present on your API site.
trim_query
- (optional) Cut a query part after
?
character from command while searching for an API link. Default:True
find_for_redoc
mode
url
- (required) An API documentation web-page URL. It will be used to construct the full link to the method.
spec
- (required) URL or local path to OpenAPI specification file.
anchor_template
- (optional) A template string describing the format of the anchors in the API documentation web-page. You can use placeholders in {curly braces}, with names of the groups in the reference regex. In this mode, you can also use two additional placeholders:
{tag}
and{operation_id}
. Default:'operation/{operation_id}'
. endpoint_prefix
- (optional) The endpoint prefix from the server root to API methods. You may use it in output template. Default:
''
endpoint_prefix_list
- (optional) The list of available endpoint prefixes which could be added to output. Default:
[]
login
- (optional) Login for basic authentication if present on your API site.
password
- (optional) Password for basic authentication if present on your API site.
trim_query
- (optional) Cut a query part after
?
character from command while searching for an API link. Default:True
User guide¶
The purpose of APIReferences is to convert references into Markdown links.
Reference is a chunk of text in your Markdown source which will be parsed by APIReferences, separated into groups, and converted into a link. An example of a reference is `GET /user/authenticate
`. APIReferences uses Regular Expressions to find the reference and split into groups. You can supply your own regular expression in reference -> regex
param (details in Capturing References section below). If you are using the default one, the reference from the example above will be split into two groups:
- verb:
GET
, - command:
/user/authenticate
.
These groups then will be used to find the referenced method on the API website and also to construct an output string.
For example, with find_by_tag_content
mode (see the detailed description of all modes below) APIReferences will use content_template
from API configuration to construct a tag content and search for it on the API website. If the content template is '{verb} {command}'
, then the constructed content, for the example above, will be GET /user/authenticate
. APIReferences will search for a tag with such content on the page and get its id.
The found tag may be <h2 id="get-userauthenticate">GET /user/authenticate</h2>
. APIReferences will take the id from this tag and use it as an anchor to the link: #get-userauthenticate
. Then it will add the API website path and here's your url: http://example.com/api/#get-userauthenticate
.
Now, when APILink has the url of the method description, it can construct an output string. The output string is formed by a template, stated in reference output_template
param. This template contains placeholders, which correspond to the reference groups with an addition of {url}
placeholder, which contains the url formed above.
If the output template is '[{verb} {command}](https://github.com/foliant-docs/foliantcontrib.apireferences/-/blob/master/{url})'
, then the output string, for our example, will be:
[GET /user/authenticate](http://example.com/api/#get-userauthenticate)
.
That's it, we've turned our reference into a Markdown link:
`GET /user/authenticate
` -> [GET /user/authenticate](http://example.com/api/#get-userauthenticate)
.
That's the big picture. Now let's start with exploring different modes by means of which APIReferences captures references on API websites and transforms them into links.
API Modes¶
As mentioned above, APIReferences takes a reference from your markdown source and splits it into groups. It then uses these groups to find the correct id on the API website. How this search is performed is determined by API Mode. It can search for a specific tag on the page by tag content or by its id; it can also search for the operation in an OpenAPI specification file or just construct an id without any checks, depending on the mode you've chosen. The mode is specified in API -> <api name> -> mode
config option.
generate_anchor
mode¶
generate_anchor
is the simplest mode. It just generates the anchor basing on the anchor_template
parameter. It doesn't perform any checks on the API website and doesn't even require the website to be reachable at the time of building your Foliant project.
Let's assume that your API website code looks like this:
...
<h2 id="user-content-get-userlogin">GET /user/status</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<h2 id="user-content-get-apiv2adminstatus">GET /api/v2/admin/status</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
...
APIReferences config in your foliant.yml
in this case may look like this:
preprocessors:
apireferences:
API:
My-API:
mode: generate_anchor
url: http://example.com/api
anchor_template: 'user content {verb} {command}'
anchor_converter: pandoc
As you may have noticed, there's no reference
section in the example above. That's because we will be using default values for the reference.
Now let's reference a GET /user/status method in our Markdown source:
To find out user's status use `My-API: GET /user/status` method.
Note that for
generate_anchor
mode, the API prefix (My-API
in our case) is required in the reference. More info about prefixes in Handling Multiple APIs section.
APIReferences will notice a reference mentioned in our markdown: `My-API: GET /user/status
`. It will capture it and split into three groups:
- prefix:
My-API
, - verb:
GET
, - command:
/user/status
.
Then it will pass it to the anchor template 'user content {verb} {command}'
which we've stated in our config, and this will result in a string:
'user content GET /user/status'
After that, APIReferences will convert this string into an id with an anchor converter. We've chosen pandoc
converter in our config, which will turn the string into this: user-content-getuserstatus
. That's exactly the id we needed, look at the webpage source:
<h2 id="user-content-get-userstatus">GET /user/status</h2>
APIReferences will add this id to our API url (which we've stated in config) to form a link: http://example.com/api#user-content-get-userstatus
.
Finally, it's time to construct a Markdown link. APIReferences takes an output_template
from the reference config (which is omitted in our example foliant.yml because we are using defaults): '[{verb} {command}](https://github.com/foliant-docs/foliantcontrib.apireferences/-/blob/master/{url})'
.
Placeholders in the output template are replaced by groups from our reference, except {url}
placeholder which is replaced with the url constructed above:
[GET /user/status](http://example.com/api#user-content-get-userstatus)
The conversion is done. Our Markdown content will now look like this:
To find out user's status use [GET /user/status](http://example.com/api#user-content-get-userstatus) method.
find_by_anchor
mode¶
find_by_anchor
generates the id by anchor_template
parameter and searches for this id on the API web page. If an element with such id is found, the reference is converted into a Markdown link. If not — the reference is skipped.
Let's assume that your API website code looks like this:
...
<h2 id="api-method-get-userstatus">GET /user/status</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<h2 id="api-method-get-apiv2adminstatus">GET /api/v2/admin/status</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
...
APIReferences config in your foliant.yml
in this case may look like this:
preprocessors:
apireferences:
reference:
output_template: '**[{verb} {command}](https://github.com/foliant-docs/foliantcontrib.apireferences/-/blob/master/{url})**'
# other reference properties are default
API:
My-API:
mode: find_by_anchor
url: http://example.com/api
tags: ['h1', 'h2']
anchor_template: 'api-method {verb} {command}'
anchor_converter: pandoc
Now let's reference a GET /user/status method in our Markdown source:
To find out user's status use `GET /user/status` method.
APIReferences will notice a reference mentioned in our markdown: `GET /user/status
`. It will capture it and split into two groups:
- verb:
GET
, - command:
/user/status
.
Then it will pass it to the anchor template 'api-method {verb} {command}'
which we've stated in our config, and this will result in a string:
'user content GET /user/status'
After that, APIReferences will convert this string into an id with an anchor converter. We've used pandoc
converter in our config, which will turn the string into this: api-method-getuserstatus
.
Now APIReferences will parse the web page and look for all h1
and h2
tags (as specified in tags
parameter) that have ids and compare these ids to our generated id.
One of the elements satisfies the requirement:
<h2 id="api-method-get-userstatus">GET /user/status</h2>
It means that referenced method is present on API web page, so APIReferences will add this id to our API url (which we've stated in config) to form a link: http://example.com/api#api-method-get-userstatus
.
Finally, it's time to construct a Markdown link. APIReferences takes an output_template
from the reference config: '**[{verb} {command}](https://github.com/foliant-docs/foliantcontrib.apireferences/-/blob/master/{url})**'
.
Placeholders in the output template are replaced by groups from our reference, except {url}
placeholder which is replaced with the url constructed above:
**[GET /user/status](http://example.com/api#api-method-get-userstatus)**
The conversion is done. Our Markdown content will now look like this:
To find out user's status use **[GET /user/status](http://example.com/api#api-method-get-userstatus)** method.
find_by_tag_content
mode¶
find_by_tag_content
generates tag content by the content_template
and searches for an HTML element with such content on the API web page. If an element is found, the reference is converted into a Markdown link. If not — the reference is skipped.
This mode is convenient when there's no way to determine tag ID based on the reference, for example, when ids are random strings.
Let's assume that your API website code looks like this:
...
<h2 id="o1egwb7agw">GET /user/status</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<h2 id="y3yn8ewg32">GET /api/v2/admin/status</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
...
APIReferences config in your foliant.yml
in this case may look like this:
preprocessors:
apireferences:
reference:
output_template: '[{prefix}: {verb} {command}](https://github.com/foliant-docs/foliantcontrib.apireferences/-/blob/master/{url})'
# other reference properties are default
API:
My-API:
mode: find_by_tag_content
url: http://example.com/api
tags: ['h1', 'h2']
content_template: '{verb} {command}'
Now let's reference a GET /user/status method in our Markdown source:
To find out user's status use `My-API: GET /user/status` method.
APIReferences will notice a reference mentioned in our markdown: `My-API: GET /user/status
`. The reference has the prefix My-API
, which means that My-API
from the API
section should be used. It will capture it and split into three groups:
- prefix:
My-API
, - verb:
GET
, - command:
/user/status
.
Then it will pass it to the header template '{verb} {command}'
which we've stated in our config, and this will result in a string:
'GET /user/status'
Now APIReferences will parse the web page and look for all h1
and h2
tags (as specified in the tags
parameter) whose content equals to our generated content.
One of the elements satisfies the requirement:
<h2 id="o1egwb7agw">GET /user/status</h2>
It means that referenced method is present on the API web page, so APIReferences will take an id o1egwb7agw
from it and add it to our API url (which we've stated in config) to form a link: http://example.com/api#o1egwb7agw
.
Finally, it's time to construct a Markdown link. APIReferences takes an output_template
from the reference config: '[{prefix}: {verb} {command}](https://github.com/foliant-docs/foliantcontrib.apireferences/-/blob/master/{url})'
.
Placeholders in the output template are replaced by groups from our reference, except {url}
placeholder which is replaced with the url constructed above:
[My-API: GET /user/status](http://example.com/api#api-method-get-userstatus)
The conversion is done. Our Markdown content will now look like this:
To find out user's status use [My-API: GET /user/status](http://example.com/api#api-method-get-userstatus) method.
find_for_swagger
mode¶
find_for_swagger
mode parses the OpenAPI spec file and looks for the referenced method in it. It then generates an anchor for SwaggerUI website based on data from the reference and the operation properties in the spec.
Let's assume that your OpenAPI specification looks like this:
{
"swagger": "2.0",
...
"paths": {
"/user/status": {
"GET": {
"tags": ["userauth"],
"summary": "Returns user auth status",
"operationId": "checkStatus",
...
},
}
...
On the default SwaggerUI website the anchor to this method will be #/userauth/checkStatus
. It consists of the first tag from the operation properties and the operationId. So to generate the proper anchor APIReferences, will need to get those parts from the spec.
APIReferences config in your foliant.yml
in this case may look like this:
preprocessors:
apireferences:
# reference options are default in this example
API:
My-API:
mode: find_for_swagger
url: http://example.com/api
spec: !path swagger.json
anchor_template: '/{tag}/{operation_id}' # you can omit this line because it's the default value
Now let's reference a GET /user/status method in our Markdown source:
To find out user's status use `GET /user/login` method.
APIReferences will notice a reference mentioned in our markdown: `GET /user/login
`. It will capture it and split into two groups:
- verb:
GET
, - command:
/user/login
.
Note that
verb
andcommand
groups are required for this mode if you are to redefine default reference regex.
Now, when we have a verb and a command, we can search for it in the OpenAPI spec. APIReferences parses the spec and searches the paths
section for our operation. From the operation properties APIReferences takes two values:
- tag: first element from the
tags
list, - operationId.
These values are then passed to the anchor template '/{tag}/{operation_id}'
, along with groups from our reference, this will result in a string:
'/userauth/checkStatus'
That's the ID we were looking for. APIReferences will add it to our API url (which we've stated in config) to form a link: http://example.com/api#/userauth/checkStatus
.
Finally, it's time to construct a Markdown link. APIReferences takes an output_template
from the reference config, which is default: '[{verb} {command}](https://github.com/foliant-docs/foliantcontrib.apireferences/-/blob/master/{url})'
.
Placeholders in the output template are replaced by groups from our reference, except {url}
placeholder which is replaced with the url constructed above:
[GET /user/login](http://example.com/api#/userauth/checkStatus)
The conversion is done. Our Markdown content will now look like this:
To find out user's status use [GET /user/login](http://example.com/api#/userauth/checkStatus) method.
find_for_redoc
mode¶
find_for_redoc
is similar to find_for_swagger
mode, except that default anchor template is 'operation/{operation_id}'
.
Handling Multiple APIs¶
APIReferences can work with several APIs at once, and honestly, it's very good at this.
Let's consider an example foliant.yml:
preprocessors:
apireferences:
API:
Client-API:
mode: find_by_tag_content
url: http://example.com/api/client
content_template: '{verb} {command}'
Admin-API:
mode: find_by_anchor
url: http://example.com/api/admin
content_template: '{verb} {command}'
In this example we've defined two APIs: Client-API
and Admin-API
, these are just names, they may be anything you want. Now we can reference both APIs:
When user clicks "LOGIN" button, the app sends a request `POST /user/login`.
To restrict user from logging in run `PUT /admin/ban_user/{id}`.
After applying the preprocessor, this source will turn into:
When user clicks "LOGIN" button, the app sends a request [POST /user/login](http://example.com/api/client#post-userlogin).
To restrict user from logging in run [PUT /admin/ban_user/{id}](](http://example.com/api/admin#put-adminbanuser-id).
As you see, APIReferences determined, which reference corresponds to which API. That is possible because when APIReferences meets a non-prefixed reference, it goes through each defined API and searches for the mentioned method.
But what happens if we reference a method which is present in both APIs?
Run `GET /system/healthcheck` for debug information.
You have to understand that, even though APIReferences is very powerful, it doesn't understand the concept of free will. It can't make the choice for you, so instead, it will show a warning and skip this reference:
WARNING: [index.md] Failed to process reference. Skipping. `GET /system/healthcheck` is present in several APIs (Client-API, Admin-API). Please, use prefix.
In the warning text, there's a suggestion to use a prefix. A prefix is a way to make your reference more specific and point APIReferences to the correct API. The value of the prefix is the API name as defined in the config. So for Client API, the prefix would be Client-API
, for Admin — Admin-API
. Let's fix our example:
Run `Admin-API: GET /system/healthcheck` to get debug information about the Admin API service.
Run `Client-API: GET /system/healthcheck` to get debug information about the Client API service.
If you don't like the format in which we supply prefix (
<prefix>: <verb> <command>
), you can change it by tweaking reference regex. More info in Capturing References section.
It's recommended to always use prefixes for unambiguity. The generate_anchor
mode won't work at all for references without prefixes, because it doesn't perform any checks and almost always returns a link.
Handling Multiple Reference Configuration¶
You can not only make APIReferences work with different APIs but also with different reference configurations. reference
parameter is a list for a reason. And because output_template
is part of reference configuration, you can make different references transform into different values.
Here's an example config:
preprocessors:
apireferences:
reference:
- only_with_prefixes: true
output_template: '**[{verb} {command}](https://github.com/foliant-docs/foliantcontrib.apireferences/-/blob/master/{url})**'
- only_with_prefixes: false
output_template: '[{verb} {command}](https://github.com/foliant-docs/foliantcontrib.apireferences/-/blob/master/{url})'
API:
...
With such config references with prefixes will be transformed into bold links, while non-prefixed references will remain regular links.
Commands and Endpoint Prefixes¶
APIReferences treats the command
part of your reference in a special way. While searching for it on the API website, it will try to substitute the command placeholder:
- with and without leading slash (
/user/login
anduser/login
), - with and without endpoint prefix, if one is defined (
/api/v1/user/login
and/user/login
).
Here's an example config to illustrate this feature:
preprocessors:
apireferences:
reference:
- only_with_prefixes: true
output_template: '**[{verb} {command}](https://github.com/foliant-docs/foliantcontrib.apireferences/-/blob/master/{url})**'
- only_with_prefixes: false
output_template: '[{verb} {command}](https://github.com/foliant-docs/foliantcontrib.apireferences/-/blob/master/{url})'
API:
My-API:
mode: find_by_tag_content
url: http://example.com/api
content_template: '{verb} {command}'
endpoint_prefix: /api/v1
Considering that the API website source looks like this:
<h2 id="asoi17uo">GET /api/v1/user/status</h2>
Which of these references, do you think, will give us the desired result?
`GET /user/status`
`GET user/status`
`GET /api/v2/user/status`
If you were reading carefully, you already know the answer — all of these references will result in the same link:
[GET /user/status](http://example.com/api#asoi17uo)
[GET /user/status](http://example.com/api#asoi17uo)
[GET /user/status](http://example.com/api#asoi17uo)
Capturing References¶
APIReferences uses regular expressions to capture references to API methods in Markdown files.
The default reg-ex is:
`\s*((?P<prefix>[\w-]+):\s*)?(?P<verb>OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT|PATCH|LINK|UNLINK)\s+(?P<command>[^`]+)\s*`
This expression accepts references like these:
Client-API: GET user/info
UPDATE user/details
Notice that the default expression uses Named Capturing Groups. You have to use them too, if you are to redefine the expression. You can name these groups as you like and have as many or as few as you wish, but it's recommended to include the prefix
group for API prefix logic to work. It is also required for all groups which are in the output_template
also to be present in the regex.
To redefine the regular expression, add an option regex
to the reference config.
For example, if you want to capture ONLY references with prefixes, you may use the following:
preprocessors:
- apireferences:
reference:
- regex: '\s*((?P<prefix>[\w-]+):\s*)(?P<verb>POST|GET|PUT|UPDATE|DELETE)\s+(?P<command>[^`]+)`\s*'
This example is for illustrative purposes only. You can achieve the same goal by just switching on the
only_with_prefixes
option.
Now the references without prefix (UPDATE user/details
) will be ignored.
Customizing Output¶
You can customize the output-string which will replace the reference string. To do that add a template into your reference configuration.
A template is a string that may contain placeholders, surrounded by curly braces. These placeholders will be replaced with the values, and all the rest will remain unchanged.
For example, look at the default template:
preprocessors:
- apireferences:
reference:
- output_template: '[{verb} {command}](https://github.com/foliant-docs/foliantcontrib.apireferences/-/blob/master/{url})',
Don't forget the single quotes around the template. These braces and parenthesis easily make YAML think that it is an embedded dictionary or list.
With the default template, the reference string will be replaced by something like that:
[GET user/info](http://example.com/api/#get-user-info)
If you want references to be transformed into something else, create your own template. You can use placeholders from the reference regular expression along with some additional:
placeholder | description | example |
---|---|---|
source | Full original reference string | `Client-API: GET user/info ` |
url | Full url to the method description | http://example.com/api/#get-user-info |
endpoint_prefix | API endpoint prefix from API configuration | /api/v2 |
Placeholders from the default regex are:
placeholder | description | example |
---|---|---|
prefix | API Prefix used in the reference | Client-API |
verb | HTTP verb used in the reference | GET |
command | API command being referenced with endpoint prefix removed | /user/info |