Features

Forward compatibility

SDKs that are fault-tolerant as your API evolves

Fern SDKs are designed so that you can evolve your API without breaking users on legacy SDKs. You can safely add additional response properties, enum values, and union variants. The legacy SDKs will safely handle deserializing extra information.

Additional Response Properties

As you make new response properties available, the legacy SDKs will continue to work. For example, let’s say you generated an SDK that had the following Movie object:

1export interface Movie {
2 name: string;
3 id: string;
4}

If you decided to add a new genre property on your server, the SDK will simply pass the extra property back. Users would also be able to access the property by doing

1const genre = movie['genre'];

Additional Enum values

As you add additional enum properties on your server, the legacy SDKs will continue to work. For example, let’s say your generated SDK had the following Genre type:

1export type Genre =
2 | "horror"
3 | "action"
4 | "thriller"
5 | "drama";

If you decided to add a new enum value comedy, the SDK will simply pass the string value back to the user. The consumer can then handle this case in the default case of a switch statement.

1switch(genre) {
2 case "horror":
3 case "action":
4 case "thriller":
5 case "drama":
6 default:
7 console.log(genre); // prints out comedy
8}

Additional Union variants

Similar to additional enum properties, if you add additional union types on your server, the legacy SDKs will continue to work. For example, let’s say your generated SDK had the following Shape type:

1export type Shape = Square | Circle;
2
3export interface Circle {
4 type: "circle",
5 radius: number
6}
7
8export interface Square {
9 type: "square",
10 side: number
11}

If you decided to add an additional union type called Triangle

1+ export type Shape = Square | Circle | Triangle;
2
3+ export interface Triangle {
4+ type: "triangle",
5+ a: number
6+ b: number
7+ c: number
8+ }

then the user could simply handle the unknown case in their legacy SDK.

1switch (type) {
2 case "circle":
3 ...
4 case "square":
5 ...
6 default:
7 console.log(type); // prints out triangle
8}