Skip to content

Breaking vs Non breaking Changes

Helio Liu edited this page Mar 16, 2022 · 18 revisions

What are breaking and compatible changes?

There are three types of changes which are also reflected in the three semver version parts:

  1. Breaking (major): These changes break compatibility in some way with previous major versions. This could be through API, runtime, or persisted data compatibility.
  2. Incremental (minor): These changes are incremental over previous minor versions of the same major version. They affect the API, runtime, or persisted data but in a compatible way.
  3. Implementation only/bug fixes (patch): These changes may affect functionality or behavior, but do not have any compatibility considerations for API, runtime, or persisted data compatibility.

Types of breaking changes

API

API breaking changes involve changing the public API of the framework in a way that may produce compile time errors for a consumer upgrading to the newer version. For example, adding a required function parameter would be a breaking change because the consumer would need to change any API calls:

-export function DoAThing(withAParameter: string): string;
+export function DoAThing(withAParameter: string, andAnotherOne: string): string;

Not all API breaks are as obvious as the previous example. For example, transitive breaks can be difficult to identify, especially as type usages become more scattered:

// @questionable/activities File1.ts
    export interface IEatCrayons {
-       eatCrayon(color: string): void;
+       eatCrayon(crayon: Crayon): void;
    }

// @questionable/people File2.ts
    import { IEatCrayons } from "@questionable/activities";
    export class ArtisticMediaConnoisseurFactory {
        public createCrayonConnoisseur(): IEatCrayons { ... }
    }

In this case, a caller of createCrayonConnoisseur that makes a call to eatCrayon on the returned IEatCrayons object would experience an API break even if there was no explicit dependency on IEatCrayons. ArtisticMediaConnoisseurFactory has received a transitive break from the IEatCrayons break.

There are more obscure API breaks that are possible with Typescript as well, but as a heuristic FluidFramework does not consider all such cases in order to balance impact and version changes.

Runtime

Persisted data

Also referred to as data-at-rest.

Types of compatible changes

API

Runtime

Persisted data

How to know if a change is breaking

Manual validation

Automated validation

How to make a change

Breaking

Non-breaking

Clone this wiki locally