Table of Contents |
---|
Overview
The goal of this document is to formalize conventions and best practices around javadocs in the CDAP code base. It is assumed that readers know how to write syntactically valid javadocs.
Content
The purpose of javadoc is to explain the intended the intended meaning or purpose of purpose of the element it's attached to. It serves as a specification for that element's behavior. This specification is what then gets fulfilled by implementation code, and verified by tests.
Without this documentation, your code is incomplete. A reader might be able to puzzle out what the code is doing, but is left in the dark as to what the code intends to do, or what it promises to continue doing in the future. The reader can't make informed decisions about how they should interact with your code.
Content
The most important part of a javadoc is the contentgets fulfilled by the implementation.
A javadoc should not assume that the reader has the code in front of them and should not assume deep familiarity with the code base. In fact, a reader should be able to implement a method based on the method javadoc.
Here are some tips to keep in mind:
- Write the doc from the reader's point of view. If the reader could not read the code, would they know how to use the class/method?
- Be specific. If there is a timestamp, document if it is a timestamp in milliseconds or seconds. Many times a concrete example is enormously helpful.
- Consider error scenarios. What can cause an exception to be thrown? Is dirty state left around if there is an error? Can the method be retried if there is an error?
- Be consistent. Use the same terminology as other methods in the class and other classes in the module. Try to keep similar style.
Requirements
In general, every class and public method in an api or spi module must have javadocs. Exceptions to this rule are getter methods that simply return the value of a private variable and methods that override another method.
...
If the method throws exceptions and modifies state, the method should document what happens to the state if an exception is thrown. Ideally, methods are implemented in a way where an exception will leave state as it was before the method call. If this is not the case, it should be documented.
At-clauses
Every at-clause should be followed by a fragment as a description. By convention, the fragment should not be capitalized and should not be a complete sentence. If the fragment is all that is needed, it should not contain a period at the end. For example:
...
This incorrectly treats 'limit' as a verb.
@return
If a method returns something, it should be documented with a @return clause. It should be described as a noun. For example:
No Format |
---|
@return the list of programs that were started |
If the method can return null, be sure to document when it will do so.
Trivial methods like getters can just use a summary fragment and omit the return clause.
@throws
Every checked exception must be documented with a @throws clause. Usually, the description begins with an 'if ...'. For example:
No Format |
---|
@throws ArtifactNotFoundException if the artifact required to create the application could not be found |
Enough information must be given so that the caller know how to respond to the exception. The caller should have enough information to know if they can retry the operation, if they should log a message and move on, or if they need to propagate the exception up.
A bad, but very common pattern is:
No Format |
---|
@throws IOException if an I/O error occurs |
Sometimes this is required because some underlying dependency throws an exception like this and does not document it any better than that. Any exception that comes from an internal class must be documented much better than that.
Unchecked exceptions do not need to be documented, though they can be documented if it is helpful to the caller. For example, NullPointerExceptions are usually not documented. An IllegalArgumentException is often documented when there is some validation method on a proto object.
@deprecated
Be sure to documented what should be used instead of the deprecated method or class.
Guidelines
This section contains guidelines for writing javadocs for common CDAP constructs.
HTTP Handlers
HTTP Handlers should ideally only be responsible for validating user input and calling an underlying service. As such, they do not need to be documented as rigorously as the service, since any actual logic should be handled by the service.
This is not the case for older HTTP Handlers in the code base. If you are adding javadocs to an older HTTP handler, you will have to treat is like a service.
Services
Services usually sit between an http handler and a dataset. Sometimes they sit between other services as well. A service usually is the one that controls the lifecycle of CDAP entities and state about those entities. It usually is in charge of what stateful operations happen transactionally. Services should be carefully documented, as control much of the actual behavior in CDAP. State change and exception handling in particular should be carefully documented. Services are also greatly under-documented in the code base.
Datasets
Datasets or Stores in the CDAP code base are generally responsible for writing data to files or tables. The data schema should be documented for every dataset. Row keys, column names, and column values should all be documented with example data. Some examples of this are the MetadataDataset and ArtifactStore.