| # API Documentation Readability Rubric | |
| ## Overview | |
| This section contains guidance on writing documentation for Fuchsia's APIs. It | |
| applies both to public-facing APIs (those surfaced via an SDK) and | |
| Fuchsia-internal ones. Public facing API documentation will be reviewed by the | |
| [API Council](council.md) for adherence to this rubric. | |
| ## Overall commenting rules | |
| In most cases, documentation should follow the language's style guide for | |
| comments. If there is a rule in this document that contradicts the | |
| language-specific rules, follow this document's guidance. In some cases, the | |
| language-specific rules take precedence; these special cases are identified | |
| below. | |
| Here are the links to language-specific guidelines for languages likely to be | |
| used in the Fuchsia repository: [C and | |
| C++](/docs/development/languages/c-cpp/cpp-style.md), | |
| [Dart](/docs/development/languages/dart/style.md) | |
| [Rust](https://github.com/rust-lang-nursery/fmt-rfcs/blob/master/guide/guide.md), | |
| [Java](https://google.github.io/styleguide/javaguide.html), | |
| [Kotlin](https://kotlinlang.org/docs/reference/coding-conventions.html#documentation-comments). | |
| We also recommend reading [Google's guidelines on API | |
| documentation](https://developers.google.com/style/api-reference-comments). | |
| ## Communicating with care | |
| Documentation is intended to be consumed by the general public, and should be | |
| written in a technical and neutral tone. There are some explicit restrictions | |
| on what you can write below, but they aren't intended to be comprehensive - use | |
| good judgment! | |
| * Do not include any reference to anyone's proprietary information. Do not use | |
| sensitive information (personally identifiable information, authentication | |
| keys, etc). | |
| * Do not use swear words or other potentially aggressive language (words like, | |
| e.g., "stupid") | |
| ## General style | |
| * Spelling, punctuation, and grammar matter. Use US English spelling. Use the | |
| serial comma. | |
| * Do not list authors explicitly. Author information goes out of date quickly, | |
| as developers move to different projects. Consider providing a maintainers | |
| file, although be wary that this goes out of date, too. | |
| * Optimize your code for the intended display (e.g., use markdown or Javadoc as | |
| intended). | |
| <!-- * Do not write TODO(username), write TODO(reference-to-bug). Bug ownership | |
| goes out of date quickly, as developers move to different projects. This | |
| includes documentation on unimplemented APIs and implementation notes. --> | |
| Only apply the following rules in the absence of language-specific practices and | |
| guidance: | |
| * Documentation should immediately precede the element it is documenting. | |
| * Use markdown for comments. The style of markdown is the style understood by | |
| the tool most likely to consume the API. | |
| * Use backticks for code blocks instead of 4-space indents. | |
| * All comments should use complete sentences. | |
| ## API elements | |
| * A **public facing API element** is one that is made available to developers | |
| via an SDK. All public facing API elements (including, but not limited to | |
| methods, classes, fields, types) must have a description. Internal libraries | |
| should be documented; there should be a good reason if they are not. | |
| * All parameters must have a description, unless that description would be | |
| redundant with the type and name. | |
| * If it is not obvious from the type what a parameter's legal values are, | |
| consider changing the type. For example, {-1, 0, 1} is less useful than an | |
| enum with {LESS\_THAN, EQUAL\_TO, GREATER\_THAN}. | |
| * Otherwise, document the behavior of the API for all possible input values. | |
| We discourage undocumented values. | |
| * All return values must have a description, unless that description would be | |
| redundant with the type and name. | |
| * If a method or function returns a subset of its return type, document the | |
| subset. | |
| * Document all returned errors and the circumstances under which they can be | |
| produced. | |
| * For example, if the method's return type is zx\_status\_t, and it only | |
| returns ZX\_OK and ZX\_ERR\_INVALID\_ARGS, your documentation must state | |
| that explicitly. | |
| * If it is not immediately obvious what a particular return value means, it | |
| must be documented. For example, if a method returns ZX\_OK, you don't | |
| need to document it. If a method returns the length of a string, it | |
| should be documented. | |
| * All possible thrown exceptions must have a description, which must include | |
| the conditions under which they are thrown, unless obvious from the type and | |
| name. | |
| * Some third party code does not document exceptions consistently. It may | |
| be hard (or impossible) to document the behavior of code that depends such | |
| APIs. Best effort is acceptable; we can resolve resulting issues as they | |
| arise. | |
| * Document whether exceptions are recoverable and, if so, how to recover | |
| from them. | |
| * For any API elements that are extensible, indicate whether they are intended | |
| to be extended, and requirements for those who might want to extend them. | |
| * If an API is extensible for internal reasons (e.g., testing), document | |
| that. For example, you should document if you have allowed a class to be | |
| extended in order to make it easy to create test doubles. | |
| * Document deprecated API elements. | |
| * Documentation on deprecated API elements must state what a user is expected | |
| to do instead of using the API. | |
| * Plans to eliminate the API should be clearly documented (if they exist). | |
| * If an explanation of the deprecation status of an API element would reduce | |
| the quality of the API documentation, consider providing a pointer to | |
| further information, including URLs and bug identifiers. | |
| ## API behavior | |
| Document user-facing invariants, as well as pre- and post-conditions. | |
| * As a rule, ensure that there are assertions / tests to enforce these | |
| conditions. | |
| * Preconditions and postconditions that require explicit user action should | |
| be documented. For example, provide documentation if an `Init()` method | |
| needs to be called before anything else happens. | |
| * Correlations between parameters or return values (e.g., one has to be less | |
| than another) should be documented. | |
| ### Concurrency | |
| Document the concurrency properties of APIs that have internal state. | |
| * FIDL servers may execute requests in an unpredictable order. Documentation | |
| should account for situations where this might affect the behavior the caller | |
| observes. | |
| * Every API with internal state falls into one of the following categories. | |
| Document which one, using the following terms: | |
| * **Thread-safe**: This means invocations of individual elements of the API | |
| (e.g., methods in a class) are atomic with respect to other concurrent | |
| processes. There is no need for a caller to use any external | |
| synchronization (e.g., a caller should not have to acquire a lock for the | |
| duration of the method invocation). You may still describe your API as | |
| thread-safe if a caller needs to use external synchronization to make | |
| references to instances of the API visible to other threads (e.g., by | |
| setting and getting a global pointer to an instance of a class with atomic | |
| operations). | |
| * **Thread-unsafe**: This means that all methods must use external | |
| synchronization to ensure invariants are maintained (e.g., mutual | |
| exclusion enforced by a lock). | |
| * **Thread-hostile**: This means that the API element should not be accessed | |
| from multiple threads (e.g., it has implementation details that rely on | |
| unsynchronized access to static data behind the scenes, like strtok()). | |
| This should include documentation about thread affinity (e.g., it uses | |
| TLS). It is only allowed in Fuchsia APIs by exception. | |
| * **Special**: This means that the correct concurrent use of this API | |
| requires thought, please read the docs. This is especially relevant when | |
| entities need to be initialized and references to them published in a | |
| specific way. | |
| * **Immutable**: The other four classes assume that internal state is | |
| mutable and thread safety is guaranteed by synchronization. Immutable | |
| classes appear constant without any additional synchronization, but you | |
| have to maintain strict rules about serialization / deserialization and | |
| how references to the object are shared between threads. | |
| * An API is **blocking** if it is not guaranteed to make progress. Document | |
| the blocking properties of your APIs. | |
| * If an API is blocking, the documentation must state what is required for | |
| the code to make progress, unless blocking is a low probability event that | |
| requires implementation understanding. | |
| * An example of when you must document a method's blocking behavior is when | |
| it blocks waiting for a response on a channel. | |
| * An example of when you do not have to document a method's blocking | |
| behavior is when it may block if lock starvation is a theoretical | |
| possibility under high load. | |
| * An API is not considered blocking only because it takes a long time to | |
| finish. A slow algorithm should not be documented to be blocking. | |
| * Documentation should only state that an API is non-blocking when the | |
| non-blocking behavior is critical to its use (for example, if an API | |
| returns a future). | |
| * An API is **reentrant** if it may be safely interrupted in the middle of its | |
| execution and then called again. Document the reentrance properties of your | |
| APIs. | |
| * APIs may be assumed to be reentrant. Documentation must state if an API | |
| is not reentrant. | |
| * Document whether a function relies on **thread-local storage (TLS)** to | |
| maintain its invariants, and any preconditions and postconditions related to | |
| that TLS (e.g., if it needs to call an initializer once per thread). | |
| ### Ownership | |
| Document ownership and liveness properties. | |
| * For parameters or return values that are stored beyond the life of a | |
| function, or resources allocated by the function and passed back to the | |
| caller, or resources with particular ownership constraints that must be | |
| observed by a set of APIs (i.e., shared resources), ownership and liveness | |
| must be documented. | |
| * Document who is responsible for releasing any associated resources. | |
| * Where appropriate, documentation should state the protocol for releasing | |
| those resources. This can be a special issue when memory allocation | |
| routines differ between the caller of an API and the API. | |
| * Languages should call out default ownership behavior in their style | |
| guides. | |
| ### Nullness | |
| All parameters and return values must have their nullness properties defined (if | |
| they are of a nullable type). | |
| * Even in Dart! | |
| * Where appropriate, refer to parameters and return values as **nullable** (may | |
| contain null) or **non-null** (may not contain null). | |
| ### Units | |
| For all parameters and return types, units must be well defined (whether by | |
| documentation or by type). | |
| ## Best Practices | |
| This section contains guidance that should be taken into consideration when | |
| writing comments. It contains opinions, rather than the unambiguous rules given | |
| above. | |
| * A reader should not have to look at an API's implementation to figure out what | |
| it does. Consider writing documentation that would allow a reader to | |
| implement your API independently based on the documentation. If, to do this, | |
| a comment needs to provide a level of detail that is not useful to most | |
| programmers, consider putting that detail in a separate document and providing | |
| a link to that document. | |
| * Avoid jargon that may not be obvious to the reader (think: "if I am | |
| interested in this API, will I definitely know what this word means?"). | |
| * Avoid abbreviations and acronyms. When you need to use them, explain them. | |
| If the abbreviation is widely used in the industry (e.g., "Transmission | |
| Control Protocol / Internet Protocol" (TCP/IP)), you do not need to explain | |
| it, but you should consider giving a link for more context. | |
| * Code samples should be considered whenever they might be useful. Providing | |
| an example can often make patterns clearer. We recommend an example of API | |
| for every top level API element (e.g., class). | |
| * It should be clear how to use your API from the comments. | |
| * Consider writing examples as separate programs and linking to them, but be | |
| careful about stale links in docs. | |
| * Examples should all compile and run. | |
| * When someone who has read the docs asks a question that should be answered by | |
| the docs, improve the docs. | |
| * If the documentation is very obvious from context, then err on the side of | |
| brevity. The Don't Repeat Yourself (DRY) principle applies. The following is | |
| not useful, because it repeats the same information twice: | |
| ``` java | |
| /** | |
| * Returns an instance of Foo. | |
| * @return an instance of Foo. | |
| */ | |
| public Foo getFoo() { ... } | |
| ``` | |
| * Similarly, if the comment is very obvious, avoid making it. If, for example, | |
| a property is guaranteed by the type system, you do not need to document it | |
| separately. However, bear in mind that your API description should be enough | |
| to enable an independent implementation. | |
| * Consider documenting performance considerations and resource consumption | |
| issues, but also remember that such issues are often implementation dependent | |
| and change over time, whereas the contract for your method will probably | |
| remain the same. Consider including this information in implementation notes | |
| / release notes instead. | |
| * Similarly, consider avoiding documenting features that may change over time, | |
| unless you specifically call out that feature may change over time. The more | |
| you prescribe, the less flexibility you give to future maintainers. However, | |
| recognize that it might not matter, since your users will depend on every | |
| behavior. See also [Hyrum's Law](http://www.hyrumslaw.com/). | |