Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC for automatically generated typescript API documentation for every plugins public services, types, and functionality #86704

Merged
merged 11 commits into from
Feb 4, 2021

Conversation

stacey-gammon
Copy link
Contributor

RFC

@stacey-gammon stacey-gammon changed the title WIP RFC for automatically generated typescript API documentation for every plugins public services, types, and functionality Dec 22, 2020
[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:

- Risks of relying on a package maintained by a single developer
- Less re-usability across repositories. What if EUI wanted to use the same system?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My biggest concern is that we end up in a situation where we cannot upgrade typescript because our custom docs system breaks and we don't have the capacity to test pre-releases and fix the docs system ahead of time. Typescript performance is currently a huge bottleneck for (almost) all developers across Kibana, not being able to upgrade to a newer version that brings performance optimisations could be very expensive in terms of developer productivity. (In my opinion more expensive than not having docs, but this is hard to quantify).

So on top of the risk of relying on the ts-morph package, there is a risk that maintaining our custom docs system requires more effort than we imagine. ts-morph increases this risk because it's a more low-level and more general-purpose library than api-extractor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll note your concern in the RFC, I agree it's an important one.

The author does seem to regularly keep up with typescript upgrades, but there is still risk that he will slow down, or certain upgrades will require a large effort on our part.

In my opinion more expensive than not having docs, but this is hard to quantify

We always have the option of making this call in the future. Each time we prepare for a typescript upgrade, we'll need to decide between:

  1. Support the new version in our ts-morph implementation
  2. Switch to an api-extractor implementation
  3. Remove our API docs

If it's easy to upgrade ts-morph, we make the changes and move on. If it's not, we assess how useful we think the docs are compared to the effort it would take to keep them. If the effort outweighs their usefulness, we can remove them, perhaps temporarily, until there is more bandwidth to fix the issues and bring back support.

If you're worried about devs starting to rely on docs that we might need to stop supporting in order to move faster with typescript, I think that would indicate a high level of importance, and mean it's worth investing the effort into keeping them around.

rfcs/text/0014_api_documentation.md Show resolved Hide resolved
rfcs/text/0014_api_documentation.md Outdated Show resolved Hide resolved

The plan is to make @link comments work like links, which means this is unneccessary information.

I propose we avoid this kind of pattern.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 This is to workaround limitations in the default api-documenter implementation.

rfcs/text/0014_api_documentation.md Outdated Show resolved Hide resolved
rfcs/text/0014_api_documentation.md Outdated Show resolved Hide resolved
@pgayvallet
Copy link
Contributor

pgayvallet commented Jan 26, 2021

Implementing our own typedef parser using AST (even if using ts-morph which is a great library) is monumental work, and, imho, we should be very cautious before deciding to do so.

This is why I think that the first section of this RFC should be an inventory of the limitations of the current api-extractor lib we are using, and the upsides that our own custom tool could provide, both on output format, and features.

I'm not sure how generics will look. I suggest an iterative approach

For development, definitely. For the initial specification, we may want to have a more precise initial vision of what we want inmho.

Generics and complex / composite types are massively used in Kibana's codebase, and I think that we should at least have a specification of how we expect to represent them in the documentation. Ideally, some examples of generated doc (not necessarily using the POC, I'm not asking for working code here, but a spec of what we want) would be useful for the RFC.

Some examples coming to mind (there must be a lot more):

composition

type Foo = Bar | Dolly;

extension

interface Bar extends Foo {
  hello: string;
}

implementation

export class Foo implements Bar

generics + extension generics

export class ObjectType<P extends Props = any> extends Type<ObjectResultType<P>> {

exposing 3rd party types

type Foo {
   component: React.ComponentType
}

Also, the RFC only speaks about plugins. What about packages? Do we plan to also generate documentation for packages, and be able to cross-link from plugins to packages or packages to packages? Not sure about plugins, but I know that core is using types coming from our packages in its public API.

@stacey-gammon
Copy link
Contributor Author

stacey-gammon commented Jan 27, 2021

@pgayvallet , I'll pull the ts-morph vs api-extractor to the top, make sure all the issues are listed.

For development, definitely. For the initial specification, we may want to have a more precise initial vision of what we want inmho.

Well, to be fair, we already have a rudimentary API doc system merged, and as far as I know, there is no vision written up for that, so I don't think we should block this on an exhaustive list.

Here are some examples of how the things you mentioned above appear. This is using my PR, I have tests set up so I can add in any crazy types I want and we can see how they show up. There are some issues with links rendering correctly in all situations.

Generics

new_api_docs_with_links

Compound types

Sometimes this is accurate, sometimes it's not. See dsherret/ts-morph#923.

Working:
Screen Shot 2021-01-27 at 11 38 07 AM

No links:

Screen Shot 2021-01-27 at 1 18 49 PM

generics + extension generics

There is an issue with the "extends / implements" part rendering links. No worse than what we have currently, however.

Screen Shot 2021-01-27 at 11 37 44 AM

Screen Shot 2021-01-27 at 11 37 21 AM

Third party types

No links, but no links with current system as well. I doubt this would work out of the box with api-extractor as well. Where is it going to link to? I don't think we want to host API docs for every external package we use.

Screen Shot 2021-01-27 at 11 37 59 AM

How to move forward?

The question I would like to focus on is:

Are we comfortable merging a ts-morph approach in the short term?

The answer to that does not in any way exclude exploring a more robust api-extractor implementation. It's about choosing an improved API docs implementation in the short term. We can consider the entire thing experimental, but I think there is a lot of value in having it merged.

@stacey-gammon stacey-gammon marked this pull request as ready for review January 27, 2021 19:10
@stacey-gammon stacey-gammon added release_note:skip Skip the PR/issue when compiling release notes v7.12.0 v8.0.0 labels Jan 27, 2021
rfcs/text/0014_api_documentation.md Show resolved Hide resolved
rfcs/text/0014_api_documentation.md Show resolved Hide resolved
ObjectKind = 'Object',
InterfaceKind = 'Interface',
TypeKind = 'Type', // For things like `export type Foo = ...`
Unknown = 'Unknown', // There are a lot of ts-morph types, if I encounter something not handled, I dump it in here.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this potentially cause confusion with TypeScript's unknown top-type? Would a TypeScript any fall under this TypeKind also?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh good thought. yes, any falls under here.

Screen Shot 2021-02-01 at 5 22 05 PM

Hmmm... I could add any and unknown as TypeKinds, and come up with a new name for "don't know what this is". "Uncategorized"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm... I could add any and unknown as TypeKinds, and come up with a new name for "don't know what this is". "Uncategorized"?

"Uncategorized" seems reasonable. We could also make TypeKind nullable/undefined. I think either is fine.

rfcs/text/0014_api_documentation.md Outdated Show resolved Hide resolved
rfcs/text/0014_api_documentation.md Outdated Show resolved Hide resolved
rfcs/text/0014_api_documentation.md Outdated Show resolved Hide resolved

1. Are we okay with a badge showing for `required` rather than `optional` when marking a parameter as optional is extra work for a developer, and `required` is the default?

2. Should we only mark function parameters as `required` or interface/class parameters? Essentially, should any declaration that is not nullable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, we should treat "required" as the default and "optional" as the exception. It feels a lot more common for parameters, etc. to be required rather than optional.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


![image](../images/repeat_primitive_signature.png)

2. If no, should we include signatures when the only difference is `| undefined`? For function parameters this information is captured by
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we were to show a badge for "optional" as opposed to "required", it seems like it'd solve this issue, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, I proposed that to @snide but if I remember correctly, he wanted us to use required for consistency with API docs. I believe this is something we can iterate on, not set in stone.


## Signatures on primitive types

1. Should we _always_ include a signature for variables and parameters, even if they are a repeat of the TypeKind? For example:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like overkill to me...

rfcs/text/0014_api_documentation.md Show resolved Hide resolved
@stacey-gammon
Copy link
Contributor Author

@elasticmachine merge upstream

@stacey-gammon stacey-gammon merged commit bb3ed33 into elastic:master Feb 4, 2021
stacey-gammon added a commit to stacey-gammon/kibana that referenced this pull request Feb 4, 2021
…y plugins public services, types, and functionality (elastic#86704)

* wip RFC for API doc infra

* update

* update

* rfc

* rfc

* Update RFC

* Update RFC post Arch Review

* add pr link

* Update based on review feedback

* Update 0014_api_documentation.md

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
gmmorris added a commit to gmmorris/kibana that referenced this pull request Feb 4, 2021
* master: (244 commits)
  [maps] Top hits per entity--change to title to use recent, minor edits (elastic#89254)
  [DOCS] Update installation details (elastic#90354)
  RFC for automatically generated typescript API documentation for every plugins public services, types, and functionality (elastic#86704)
  Elastic Maps Server config is `host` not `hostname` (elastic#90234)
  Use doc link services in index pattern management (elastic#89937)
  [Fleet] Managed Agent Policy (elastic#88688)
  [Workplace Search] Fix Source Settings bug  (elastic#90242)
  [Enterprise Search] Refactor MockRouter test helper to not store payload (elastic#90206)
  Use doc link service in more Stack Monitoring pages (elastic#89050)
  [App Search] Relevance Tuning logic - actions and selectors only, no listeners (elastic#89313)
  Remove UI filters from UI (elastic#89793)
  Use newfeed.service config for all newsfeeds (elastic#90252)
  skip flaky suite (elastic#85086)
  Add readme to geo containment alert covering test alert setup (elastic#89625)
  [APM] Enabling yesterday option when 24 hours is selected (elastic#90017)
  Test user for maps tests under import geoJSON tests (elastic#86015)
  [Lens] Hide column in table (elastic#88680)
  [Security Solution][Detections] Reduce detection engine reliance on _source (elastic#89371)
  [Discover] Minor cleanup (elastic#90260)
  [Search Session][Management] Rename "cancel" button and delete "Reload" button (elastic#90015)
  ...
stacey-gammon added a commit that referenced this pull request Feb 5, 2021
…y plugins public services, types, and functionality (#86704) (#90350)

* wip RFC for API doc infra

* update

* update

* rfc

* rfc

* Update RFC

* Update RFC post Arch Review

* add pr link

* Update based on review feedback

* Update 0014_api_documentation.md

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release_note:skip Skip the PR/issue when compiling release notes v7.12.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants