docs: Update "How it works" section in Documenting REST API endpoints.

Updates this section to use the shared `api-doc-template.md` as a
guide, as well as the current documentation for the `render-message`
endpoint. Previously, this section referred to a file that had been
removed with the transition to a shared template file.

Fixes #24485.
This commit is contained in:
Lauryn Menard 2023-03-13 17:49:59 +01:00 committed by Tim Abbott
parent 4d55192e21
commit 41ac95fe52
1 changed files with 84 additions and 57 deletions

View File

@ -65,73 +65,94 @@ want to also read the [Step by step guide](#step-by-step-guide).
## How it works ## How it works
To understand how this documentation system works, start by reading an Let's use the existing documentation for one of our REST API endpoints
existing doc file (`api_docs/render-message.md` is a good to show how the documentation system works:
example; accessible live [POST /messages/render](https://zulip.com/api/render-message).
[here](https://zulip.com/api/render-message) or in the development We highly recommend looking at these resources while reading the above
environment at `http://localhost:9991/api/render-message`). documentation page:
We highly recommend looking at those resources while reading this page. - `api_docs/api-doc-template.md`
- `zerver/openapi/zulip.yaml`, specifically the section with
`operationId: render-message`
- `zerver/openapi/python_examples.py`
If you look at the documentation for existing endpoints, you'll notice If you look at the documentation for existing endpoints, you'll notice
that a typical endpoint's documentation is divided into four sections: that a typical endpoint's documentation is divided into four sections:
- The top-level **Title and description** - **Title and description**
- **Usage examples** - **Usage examples**
- **Arguments** - **Parameters**
- **Responses** - **Response with examples**
The rest of this guide describes how each of these sections works. The rest of this guide describes how each of these sections works.
### Title and description ### Title and description
Displayed at the top of any REST endpoint documentation page, the The first line of `api-doc-template.md` generates a lot of key
title comes from the `summary` parameter in OpenAPI data. The information for our API endpoint documentation:
description should explain what the endpoint does in clear
English. Include details on how to use it correctly or what it's good
or bad for, with links to any alternative endpoints the user might
want to consider.
These sections should often contain a link to the documentation of the ```
relevant feature in `/help/`. {generate_api_header(API_ENDPOINT_NAME)}
```
At the top of the endpoint documentation page is the title, and it
comes from the `summary` parameter in the OpenAPI data,
`zerver/openapi/zulip.yaml`.
The endpoint `description` in the OpenAPI data explains what the
endpoint does in clear English. It should include details on how to
use the endpoint correctly or what it's good or bad for, with links
to any alternative endpoints the user might want to consider.
The description should often contain a link to the documentation of
the relevant feature in the [help center](helpcenter.md), and should
include **Changes** notes for all feature level updates documented
in the [API changelog](https://zulip.com/api/changelog), see
`api_docs/changelog.md`, that reference the endpoint.
Endpoints that only administrators can use should be tagged with the
custom `x-requires-administrator` field in the OpenAPI definition.
All of this information is rendered via a Markdown preprocessor,
specifically the `APIHeaderPreprocessor` class defined in
`zerver/openapi/markdown_extension.py`.
### Usage examples ### Usage examples
We display usage examples in three languages: Python, JavaScript and We display usage examples in three languages: Python, JavaScript and
`curl`; we may add more in the future. Every endpoint should have curl; we may add more in the future. Every endpoint should have
Python and `curl` documentation; `JavaScript` is optional as we don't Python and curl documentation; JavaScript is optional as we don't
consider that API library to be fully supported. The examples are consider that API library to be fully supported.
defined using a special Markdown extension
(`zerver/openapi/markdown_extension.py`). To use this extension, one The examples are defined using a special Markdown extension, see
writes a Markdown file block that looks something like this: `zerver/openapi/markdown_extension.py`. Here's the Markdown file
block that uses this in `api-doc-template.md`:
```md ```md
{start_tabs} {start_tabs}
{tab|python}
{generate_code_example(python)|/messages/render:post|example} {generate_code_example(python)|API_ENDPOINT_NAME|example}
{tab|js} {generate_code_example(javascript)|API_ENDPOINT_NAME|example}
...
{tab|curl} {tab|curl}
{generate_code_example(curl)|/messages/render:post|example} {generate_code_example(curl)|API_ENDPOINT_NAME|example}
{end_tabs} {end_tabs}
``` ```
In some cases, one wants to configure specific parameters to be In some cases, one wants to configure specific parameters to be
included or excluded from the example `curl` requests for readability included or excluded from the example curl requests for readability
reasons. One can do that using the `x-curl-examples-parameters` reasons. One can do that using the `x-curl-examples-parameters`
parameter. parameter in the OpenAPI data.
#### Writing Python examples #### Writing Python examples
For the Python examples, you'll write the example in For the Python examples, you'll write the example in
`zerver/openapi/python_examples.py`, and it'll be run and verified `zerver/openapi/python_examples.py`, and it'll be run and verified
automatically in Zulip's automated test suite. The code there will automatically in Zulip's automated test suite. The code for our
look something like this: example API endpoint looks like this:
```python ```python
@openapi_test_function('/messages/render:post') @openapi_test_function('/messages/render:post')
@ -164,47 +185,53 @@ API client by copy-pasting from the website; it's easy to make typos
and other mistakes where variables are defined outside the tested and other mistakes where variables are defined outside the tested
block, and the tests are not foolproof. block, and the tests are not foolproof.
The code that renders `/api` pages will extract the block between the The code that renders API documentation pages will extract the block
`# {code_example|start}` and `# {code_example|end}` comments, and between the `# {code_example|start}` and `# {code_example|end}` comments,
substitute it in place of and substitute it in place of
`{generate_code_example(python)|/messages/render:post|example}` `{generate_code_example(python)|/messages/render:post|example}`. Note
wherever that string appears in the API documentation. that here the `API_ENDPOINT_NAME` has been filled in with our example
endpoint's information.
- Additional Python imports can be added using the custom Additional Python imports can be added using the custom
`x-python-examples-extra-imports` field in the OpenAPI definition. `x-python-examples-extra-imports` field in the OpenAPI definition.
- Endpoints that only administrators can use should be tagged with the
custom `x-requires-administrator` field in the OpenAPI definition.
### Parameters ### Parameters
We have a separate Markdown extension to document the parameters that We have a separate Markdown extension to document the parameters that
an API endpoint supports. You'll see this in files like an API endpoint supports. Implemented in
`api_docs/render-message.md` via the following Markdown `zerver/lib/markdown/api_arguments_table_generator.py`, you can see
directive (implemented in this in `api-doc-template.md` after the **Parameters** header:
`zerver/lib/markdown/api_arguments_table_generator.py`):
```md ```
{generate_api_arguments_table|zulip.yaml|/messages/render:post} {generate_api_arguments_table|zulip.yaml|API_ENDPOINT_NAME}
``` ```
Just as in the usage examples, the `/messages/render` key must match a This generates the information from the endpoint's parameter
URL definition in `zerver/openapi/zulip.yaml`, and that URL definition definition in the OpenAPI data.
must have a `post` HTTP method defined.
Additional content that you'd like to appear in the parameter Additional content that you'd like to appear in the parameter
description area can be declared using the custom description area can be declared using the custom
`x-parameter-description` field in the OpenAPI definition. `x-parameter-description` field in the OpenAPI definition.
### Displaying example payloads/responses ### Response with examples
If you've already followed the steps in the [Usage examples](#usage-examples) Similar to the parameters section above, there is a separate Markdown
section, this part should be fairly trivial. extension to document the endpoint's return values and generate the
example response(s) from the OpenAPI data. Implemented in
`zerver/lib/markdown/api_return_values_table_generator.py`, you can
see this in after the **Response** header in `api-doc-template.md`:
You can use the following Markdown directive to render all the fixtures ```
defined in the OpenAPI `zulip.yaml` for a given endpoint {generate_return_values_table|zulip.yaml|API_ENDPOINT_NAME}
```
```md To generate the example responses from the OpenAPI data, we again
{generate_code_example|/messages/render:post|fixture} use the special Markdown extension from the **Usage examples**
discussed above, except with the `fixture` argument instead of the
`example` argument:
```
{generate_code_example|API_ENDPOINT_NAME|fixture}
``` ```
Additional content that you'd like to appear in the responses part of Additional content that you'd like to appear in the responses part of