Defining your API
Types

Built-in types

  • string
  • integer
  • long
  • double
  • boolean
  • datetime An RFC 3339, section 5.6 datetime. For example, 2017-07-21T17:32:28Z.
  • date An RFC 3339, section 5.6 date (YYYY-MM-DD). For example, 2017-07-21.
  • uuid
  • base64
  • list e.g. list<string>
  • set e.g. set<string>
  • map e.g. map<string, integer>
  • optional e.g. optional<string>

unknown

Fern comes with a special type unknown, which signifies that the type cannot be represented in Fern. Often, this is because the value has a dynamic shape (e.g. user-supplied data).

In cases where you use unknown, Fern will assume the value is optional. There’s no difference between unknown and optional<unknown>.

Custom types

Creating your own types is easy in Fern!

Objects

The most common custom types are objects.

In Fern, you use the "properties" key to create an object:

types:
  Person:
    properties: # <---
      name: string
      address: Address

  Address:
    properties: # <---
      line1: string
      line2: optional<string>
      city: string
      state: string
      zip: string

These represent JSON objects:

{
  "name": "Alice",
  "address": {
    "line1": "123 Happy Lane",
    "city": "New York",
    "state": "NY",
    "zip": "10001"
  }
}

You can also use extends to compose objects:

types:
  Pet:
    properties:
      name: string
  Dog:
    extends: Pet
    properties:
      breed: string

Aliases

An Alias type is a renaming of an existing type. This is usually done for clarity.

types:
  # UserId is an alias of string
  UserId: string

  User:
    properties:
      id: UserId
      name: string

Enums

An enum represents a string with a set of allowed values.

In Fern, you use the "enum" key to create an enum:

types:
  WeatherReport:
    enum: # <---
      - SUNNY
      - CLOUDY
      - RAINING
      - SNOWING

Unions

Fern supports tagged unions (a.k.a. discriminated unions). Unions are useful for polymorphism. This is similar to the oneOf concept in OpenAPI.

In Fern, you use the "union" key to create an union:

types:
  Animal:
    union:
      dog: Dog
      cat: Cat
  Dog:
    properties:
      likesToWoof: boolean
  Cat:
    properties:
      likesToMeow: boolean

In JSON, unions have a discriminant property to differentiate between different members of the union. By default, Fern uses "type" as the discriminant property:

{
  "type": "dog",
  "likesToWoof": true
}

You can customize the discriminant property using the “discriminant” key:

 types:
   Animal:
+    discriminant: animalType
     union:
       dog: Dog
       cat: Cat
   Dog:
     properties:
       likesToWoof: boolean
   Cat:
     properties:
       likesToMeow: boolean

This corresponds to a JSON object like this:

{
  "animalType": "dog",
  "likesToWoof": true
}

Documentation

You can add documentation for types. These docs are passed into the compiler, and are incredibly useful in the generated outputs (e.g. docstrings in SDKs).

types:
  Person:
    docs: A person represents a human being
    properties:
      name: string
      age:
        docs: age in years
        type: integer
Generated TypeScript SDK
/**
 * A person represents a human being
 */
interface Person {
  name: string;
  // age in years
  age: number;
}

Examples

You can add examples for types. These are passed into the compiler to be used in the generated outputs (e.g. examples in the Postman Collection).

types:
  UserId:
    docs: A unique identifier for a user
    type: string
    examples:
      - value: user-id-123
Generated TypeScript SDK
/**
 * A unique identifier for a user
 *
 * @example "user-id-123"
 */
type UserId = string;

The Fern compiler validates that your examples match the expected types. For example, this won’t compile:

types:
  UserId:
    type: integer
    examples:
      - value: hello # not an integer

Referencing examples from other types

Just like types, you can compose examples. To reference an example from another type, use $.

types:
  UserId:
    type: integer
    examples:
      - name: Example1
        value: user-id-123

  User:
    properties:
      id: UserId
      name: string
    examples:
      - value:
          id: $UserId.Example1 # <---
          name: Jane Smith