Understanding additionalProperties

In a standard JSON schema, the additionalProperties (opens in a new tab) keyword controls whether objects can include properties beyond those explicitly defined. By default, if additionalProperties is not specified, it’s considered to be true, allowing objects to carry arbitrary additional data.

The Speakeasy approach

At Speakeasy, we diverge from the standard approach by setting additionalProperties to false unless explicitly defined otherwise. This approach encourages defining fully-typed objects, promoting clear and comprehensive documentation of their structure. This method aligns with the common developer expectation of creating APIs with precise and predictable data models.

API developers generally prefer closed objects as the default, rather than open ones, and setting additionalProperties: false in the spec would be tedious. Most backend frameworks that generate OpenAPI schemas rarely add additionalProperties: false, even when that behavior is intended.

Using additionalProperties: true

Setting additionalProperties to true is beneficial for schemas that need flexibility to dynamically accommodate unknown fields. This setting is ideal for scenarios where the data model may extend beyond the initially defined properties, allowing for future growth without requiring schema revisions.

Imagine a scenario where an API endpoint accepts user-generated content with a set of core properties but also needs to be open to future extensions. By setting additionalProperties to true, the API can accept and store these extensions without needing schema updates for each new property.

openapi.yaml
components:
schemas:
FlexibleObject:
type: object
properties:
title:
type: string
description:
type: string
additionalProperties: true

This schema allows for the inclusion of any additional user-provided properties alongside the defined title and description.

Typescript
export type FlexibleObject = {
title: string;
description: string;
additionalProperties: Record<string, any>; // πŸ‘ˆ
}

Using typed additionalProperties

For use cases that need to accommodate arbitrary additional data within a constrained type, Speakeasy allows additionalProperties to be defined with a specific type or schema, enabling the creation of flexible yet type-safe objects.

openapi.yaml
components:
schemas:
StringOnlyObject:
type: object
properties:
title:
type: string
description:
type: string
additionalProperties:
type: string

In this schema, alongside the explicitly defined name, any additional properties must be strings, ensuring a consistent data type across all properties.

Typescript
export type StringOnlyObject = {
title: string;
description: string;
additionalProperties: Record<string, string>;
};