Skip to content

Commit b683e3f

Browse files
author
Stacey Gammon
committed
wip RFC for API doc infra
1 parent d744eae commit b683e3f

File tree

1 file changed

+184
-0
lines changed

1 file changed

+184
-0
lines changed
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
- Start Date: 2020-12-21
2+
- RFC PR: (leave this empty)
3+
- Kibana Issue: (leave this empty)
4+
5+
# Summary
6+
7+
Automatically generate API documentation for every plugin that exposes a public API within Kibana.
8+
This does not cover REST API docs, but is targetted towards our javascript
9+
plugin APIs.
10+
11+
# Screenshots
12+
13+
TODO when I have better screenshots.
14+
15+
# Architecture design
16+
17+
## Hosting
18+
19+
In the short term, the generated docs will reside inside the kibana repo, inside a top level `api_docs` folder. In the long term, we could investigate having the docs system run a script to generated the mdx files, so we don’t need to store them inside the repo.
20+
21+
They will be hosted online wherever the new docs system ends up. This can temporarily be accessed at https://elasticdocstest.netlify.app/docs/.
22+
23+
## Overview
24+
25+
The first stage is to collect the list of plugins using the existing `findPlugins` logic, with [some new fields](#proposed-plugin-changes).
26+
27+
For every plugin, the initial list of api nodes are collected from three "scopes":
28+
- plugin/public/index.ts
29+
- plugin/server/index.ts
30+
- plugin/common/index.ts
31+
32+
Every node in each list is then recursively transformed into a json structure that represents a plugin's public API:
33+
34+
```ts
35+
36+
/**
37+
* Contains all the information neccessary to build API docs for this particular plugin.
38+
*/
39+
export interface PluginApiDef {
40+
id: string;
41+
serviceFolders?: readonly string[];
42+
public: ApiDocDef[];
43+
server: ApiDocDef[];
44+
common: ApiDocDef[];
45+
}
46+
47+
/**
48+
* Contains all the information neccessary to render a single API inside the docs system.
49+
*/
50+
export interface ApiDocDef {
51+
/**
52+
* Used to create an anchor link to this API.
53+
*/
54+
id?: string;
55+
56+
/**
57+
* The name of the api.
58+
*/
59+
label: string;
60+
61+
/**
62+
* The kind of type this API represents, e.g. string, number, Object, Interface, Class.
63+
*/
64+
type: TypeKind;
65+
66+
/**
67+
* Certain types have children. For instance classes have class members, functions will list
68+
* their parameters here, classes will list their class members here, and objects and interfaces
69+
* will list their properties. The elastic-docs system can use the `type` to potentially render
70+
* these children differently.
71+
*/
72+
children?: ApiDocDef[];
73+
74+
/**
75+
* Api node comment.
76+
*/
77+
description?: TextWithLinks;
78+
79+
/**
80+
* If the type is a function, it's signature should be displayed. Currently this overlaps with type
81+
* sometimes, and will sometimes be left empty for large types (like classes and interfaces).
82+
*/
83+
signature?: TextWithLinks;
84+
85+
// Relevant for functions with @returns comments.
86+
returnComment?: TextWithLinks;
87+
88+
// Will contain the tags on a comment, like `beta` or `deprecated`.
89+
// Won't include param or returns tags.
90+
tags?: string[];
91+
92+
// Every plugn that exposes functionality from their setup and start contract
93+
// should have a single exported type for each. These get pulled to the top because
94+
// they are accessed differently than other exported functionality and types.
95+
lifecycle?: Lifecycle;
96+
97+
/**
98+
* Used to create links to github to view the code for this API.
99+
*/
100+
source: {
101+
path: string;
102+
lineNumber: number;
103+
};
104+
}
105+
106+
enum TypeKind {
107+
ClassKind = 'Class',
108+
FunctionKind = 'Function',
109+
VariableKind = 'Variable',
110+
ObjectKind = 'Object',
111+
InterfaceKind = 'Interface',
112+
TypeKind = 'Type',
113+
Unknown = 'Unknown',
114+
Parameter = 'Parameter',
115+
Property = 'Property',
116+
String = 'string',
117+
Number = 'number',
118+
Boolean = 'boolean',
119+
Array = 'Array',
120+
}
121+
122+
/**
123+
*
124+
*/
125+
type TextWithLinks = string | Array<string | Reference>;
126+
127+
interface Reference {
128+
docId: string;
129+
section: string;
130+
text: string;
131+
}
132+
```
133+
134+
## Technology: ts-morph vs api-extractor
135+
136+
[Api-extractor](https://api-extractor.com/) is a utility built from microsoft that parses typescript code into json files that can then be used in a custom [api-documenter](https://api-extractor.com/pages/setup/generating_docs/) in order to build documentation. This is what we [have now](https://github.com/elastic/kibana/tree/master/docs/development), except we use the default api-documenter. Unfortunately, because our plugins aren’t separate packages, and the way api-extractor works, we can’t build cross plugin links this way.
137+
138+
[ts-morph](https://github.com/dsherret/ts-morph) is a utility built and maintained by a single person, which sits a layer above the raw typescript compiler. It affords greater flexibility, thus supports cross plugin links (among other things like links to source files). The downsides of using this library are:
139+
140+
- Risks of relying on a package maintained by a single developer
141+
- Less re-usability across repositories. What if EUI wanted to use the same system?
142+
143+
I recommend we move ahead with ts-morph, acknowleding the possibility of migrating to api-extractor in the future. If so, the effort shouldn’t be a large one.
144+
145+
146+
147+
# Drawbacks
148+
149+
Why should we *not* do this? Please consider:
150+
151+
- implementation cost, both in term of code size and complexity
152+
- the impact on teaching people Kibana development
153+
- integration of this feature with other existing and planned features
154+
- cost of migrating existing Kibana plugins (is it a breaking change?)
155+
156+
There are tradeoffs to choosing any path. Attempt to identify them here.
157+
158+
# Alternatives
159+
160+
What other designs have been considered? What is the impact of not doing this?
161+
162+
# Adoption strategy
163+
164+
If we implement this proposal, how will existing Kibana developers adopt it? Is
165+
this a breaking change? Can we write a codemod? Should we coordinate with
166+
other projects or libraries?
167+
168+
# How we teach this
169+
170+
What names and terminology work best for these concepts and why? How is this
171+
idea best presented? As a continuation of existing Kibana patterns?
172+
173+
Would the acceptance of this proposal mean the Kibana documentation must be
174+
re-organized or altered? Does it change how Kibana is taught to new developers
175+
at any level?
176+
177+
How should this feature be taught to existing Kibana developers?
178+
179+
# Unresolved questions
180+
181+
## REST API
182+
183+
This RFC does not cover REST API documentation, though it worth considering where
184+
REST APIs registered by plugins should go in the docs.

0 commit comments

Comments
 (0)