Fern Definition

Examples

You can add examples for types and endpoints. Examples are shown as comments in your SDKs, in the request & response of your documentation, and in a Postman Collection.

Validation

The Fern CLI validates that your examples match the expected types. The following won't compile:

1
2
3
4
5
types:
  UserId:
    type: integer
    examples:
      - value: hello # not an integer
1
2
[api]: example.yml -> types -> UserId -> examples[0]
       Expected example to be an integer. Example is: "hello"

Referencing examples

You can reference an example from another type, endpoint, or error.

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

Examples for types

Objects

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
types:
  ShipTo:
    properties:
      street1: string
      street2: optional<string>
      city: string
      state: string
      postalCode: string
      country: Country
      isResidential: boolean
    examples:
      - name: WhiteHouse
        value:
          street1: 1600 Pennsylvania Avenue NW
          city: Washington DC
          state: Washington DC
          postalCode: "20500"
          country: US
          isResidential: true
      - name: EmpireStateBuilding
        value:
          street1: 350 5th Ave
          street2:
          city: New York
          state: NY
          postalCode: "10118"
          country: US
          isResidential: false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
 * Represents a shipping address.
 * 
 * The White House address
 * @example {
 *  street1: "1600 Pennsylvania Avenue NW",
 *  city: "Washington DC",
 *  state: "Washington DC",
 *  postalCode: "20500",
 *  country: "US",
 *  isResidential: true
 * }
 * 
 * * The Empire State Building address
 * @example {
 *  street1: "350 5th Ave",
 *  city: "New York",
 *  state: "NY",
 *  postalCode: "10118",
 *  country: "US",
 *  isResidential: false
 * }
 */
type ShipTo = {
  street1: string;
  street2?: string;
  city: string;
  state: string;
  postalCode: string;
  country: Country;
  isResidential: boolean;
};

Lists

1
2
3
4
5
6
7
8
9
 Shipments:
    type: list<ShipmentStatus>
    examples:
      - name: Default
        value:
          - status: "InTransit"
            estimatedDeliveryDate: "2024-01-11"
          - status: "Delivered"
            estimatedDeliveryDate: "2024-01-13"

Unions

Discriminated Union

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
types:
  Animal:
    union:
      dog: Dog
      cat: Cat
    examples:
      - value:
          type: dog
          likesToWoof: true
  Dog:
    properties:
      likesToWoof: boolean
  Cat:
    properties:
      likesToMeow: boolean
1
2
3
4
5
6
7
8
9
10
/**
 * Represents an animal, which can be either a Dog or a Cat.
 *
 * Example of a Dog:
 * @example {
 *  type: "dog",
 *  likesToWoof: true
 * }
 */
type Animal = Dog | Cat;

Undiscriminated Union

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
types:
  Animal:
    discriminated: false
    union:
      - Dog
      - Cat
    examples:
      - value:
          likesToMeow: true
  Dog:
    properties:
      likesToWoof: boolean
  Cat:
    properties:
      likesToMeow: boolean
1
2
3
4
5
6
7
8
9
/**
 * Represents an Animal, which can be either a Dog or a Cat.
 *
 * Example of an Animal as a Cat:
 * @example {
 *  likesToMeow: true
 * }
 */
type Animal = Dog | Cat;

Aliases

1
2
3
4
5
6
types:
  UserId:
    docs: A unique identifier for a user
    type: string
    examples:
      - value: user-id-123
1
2
3
4
5
/** 
* A unique identifier for a user * 
* @example "user-id-123" 
*/ 
type UserId = string; 

Examples for endpoints

You can add examples of successful and error responses for your endpoints. Examples can reference the examples of types to avoid duplication.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
service:
  auth: true
  base-path: ""
  endpoints:
    CreateShippingLabel:
      docs: Create a new shipping label.
      method: POST
      path: /shipping
      request: CreateShippingLabelRequest
      response: ShippingLabel
      errors:
        - NotAuthorized
        - InsufficientFunds
      examples:
        # A successful response that doesn't reference other examples.
        - request:
            orderId: "online_789"
            weightInOunces: 5
          response:
            body:
              orderId: "online_789"
              weightInOunces: 5
              trackingNumber: "1Z26W8370303469306"
              price: 2.50

        # A successful response that uses references.
        - request: $CreateShippingLabelRequest.SuccessfulRequest
          response:
            body: $ShippingLabel.Default

        # An error response.
        - request: $CreateShippingLabelRequest.InsufficientFundsRequest
          response:
            error: InsufficientFunds
            body: $InsufficientFundsBody.Default

types:
  CreateShippingLabelRequest:
    properties:
      orderId: string
      weightInOunces: integer
    examples:
      - name: SuccessfulRequest
        value:
          orderId: "online_123"
          weightInOunces: 13
      - name: InsufficientFundsRequest
        value:
          orderId: "online_456"
          weightInOunces: 2000

  ShippingLabel:
    properties:
      orderId: string
      weightInOunces: integer
      trackingNumber: string
      price: double
    examples:
      - name: Default
        value:
          orderId: "online_123"
          weightInOunces: 13
          trackingNumber: "1Z12345E0205271688"
          price: 12.35

  InsufficientFundsBody:
    properties:
      message: string
    examples:
      - name: Default
        value:
          message: "Insufficient funds to create shipping label."

errors:
  NotAuthorized:
    status-code: 401
  InsufficientFunds:
    status-code: 422
    type: InsufficientFundsBody

Examples for path parameters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
service:
  auth: true
  base-path: ""
  endpoints:
    TrackShipment:
      docs: Track the status of a shipment.
      method: GET
      path: /shipping/{trackingNumber}
      path-parameters: 
        trackingNumber: string
      response: ShipmentStatus
      examples:
        - path-parameters: 
            trackingNumber: "1Z26W8370303469306"
          response:
            body:
              status: "InTransit"
              estimatedDeliveryDate: "2024-01-11"