AIP-200

Precedent

Many times, APIs are written in ways that do not match new guidance that is added to these standards after those APIs have already been released. Additionally, sometimes it can make sense to intentionally violate standards for particular reasons, such as maintaining consistency with established systems, meeting stringent performance requirements, or other practical concerns. Finally, as carefully as everyone reviews APIs before they are released, sometimes mistakes can slip through.

Since it often is not feasible to fix past mistakes or make the standards serve every use case, APIs may be stuck with these exceptions for quite some time. Further, since new APIs often base their designs (names, types, structures, etc) on existing APIs, it is possible that a standards violation in one API could spill over into other APIs, even if original reason for the exception is not applicable to the other APIs.

As a result of this problem, it is important to "stop the bleeding" of these standards exceptions into new APIs, and additionally document the reasons for each exception so that historical wisdom is not lost.

Guidance

If an API violates the AIP standards for any reason, there must be an internal comment linking to this document using its descriptive link (aip.dev/not-precedent) to ensure others do not copy the violations or cite the errors as precedent of a "previously approved API".

The comment should also include an explanation of what violates standards and why it is necessary. For example:

message DailyMaintenanceWindow {
  // Time within the maintenance window to start the maintenance operations.
  // It must use the format "HH MM", where HH : [00-23] and MM : [00-59] GMT.
  // (-- aip.dev/not-precedent: This was designed for consistency with crontab,
  //     and preceded the AIP standards.
  //     Ordinarily, this type should be `google.type.TimeOfDay`. --)
  string start_time = 2;

  // Output only. Duration of the time window, automatically chosen to be
  // smallest possible in the given scenario.
  // (-- aip.dev/not-precedent: This preceded the AIP standards.
  //     Ordinarily, this type should be `google.protobuf.Duration`. --)
  string duration = 3;
}

Important: APIs should only be considered to be precedent-setting if they are in beta or GA.

Local consistency

If an API violates a standard throughout, it would be jarring and frustrating to users to break the existing pattern only for the sake of adhering to the global standard.

For example, if all of an API's resources use creation_time (instead of the standard field create_time described in AIP-142), a new resource in that API should continue to follow the local pattern.

However, others who might otherwise copy that API should be made aware that this is contra-standard and not something to cite as precedent when launching new APIs.

// ...
message Book {
  // (-- aip.dev/not-precedent: This field was present before there was a
  //     standard field.
  //     Ordinarily, it should be spelled `create_time`. --)
  google.protobuf.Timestamp creation_time = 1;
}

// ...
message Author {
  // (-- aip.dev/not-precedent: `Book` had `creation_time` before there was