OpenAPI Specifications are often associated with describing RESTful APIs, but don't be fooled by the stereotype. Whether you're designing a REST API or something that leans more toward RPC-based calls, OpenAPI's data type system is robust enough to capture your API's behavior precisely. In this post, we'll dive into recommended practices for working with OpenAPI types and explore all the data types you can leverage, from strings and numbers to objects and arrays.
Why Precision Matters
Clarity is king when your API spec serves as both documentation and a blueprint for SDK generation. Overly loose definitions might be “valid” according to the spec, but they can cause headaches when tooling tries to generate SDKs, server stubs, or even API docs. Here's what you should keep front-of-mind:
- Be explicit. Define your types using the standardized formats.
- Validate ruthlessly. Use attributes like
required
,readOnly
,writeOnly
, and validations (e.g.,minItems
,pattern
) to avoid ambiguity. - Plan for tooling. Clear, explicit definitions make it easier for SDK generators and documentation tools to do their job without guesswork.
Let's walk through each data type with best practices and real-world examples.
The OpenAPI Data Types
1. String
The string type is a workhorse of the OpenAPI spec. It can represent everything from simple text to complex data like encoded binary files. But to unlock its full potential, you must use formats and patterns wisely.
Formats
Official formats for strings include:
- date: For RFC3339 dates (e.g.,
"2025-03-07"
). - date-time: For full timestamps (e.g.,
"2025-03-07T15:26:38Z"
). - password: A hint that the string holds sensitive data.
- byte: Base64 encoded data.
- binary: For raw binary data.
Outside the official list, you might see:
- uuid
- uri
- hostname
- ipv4/ipv6
- full list here
Example:
schema:
type: string
format: date-time
Patterns
When you need to constrain string content further, add a regex pattern:
schema:
type: string
pattern: '^[a-zA-Z0-9_]+$'
Best practice: Always validate input where possible. A well-defined string improves API documentation and makes client-side parsing and generation predictable.
2. Number & Integer
Numbers are more than just digits on a screen. OpenAPI distinguishes between generic numbers and integers by allowing you to specify formats that align with your target language's capabilities.
Formats for Numbers:
- number
- float: For 32-bit floating point.
- double: For 64-bit floating point.
- integer
- int32: 32-bit integer.
- int64: 64-bit integer.
Worth noting that JSON Schema defines integers mathematically, which means that both 1 and 1.0 are equivalent and considered integers.
Validation Attributes
Use attributes like minimum
, maximum
, exclusiveMinimum
, exclusiveMaximum
, and multipleOf
to enforce numeric constraints.
Example for a 32-bit float:
schema:
type: number
format: float
minimum: 0
maximum: 1
Example for an integer with step constraints:
schema:
type: integer
format: int64
multipleOf: 5
Tip: Explicitly specifying the format avoids any ambiguity that might arise from the default type handling in various languages.
3. Boolean
Simple but essential, the boolean type only accepts true
or false
. Unlike some loosely-typed systems, OpenAPI does not let you substitute 1
or 0
.
Example:
schema:
type: boolean
Best practice: Don't try to be clever. Stick to true booleans to ensure consistent behavior across all consumers.
4. Array
Arrays let you define ordered lists of items. The key is to use the items
attribute to specify the type of elements in the array.
Basic examples:
# Array of strings
schema:
type: array
items:
type: string
# Array of objects with validations
schema:
type: array
items:
type: object
properties:
id:
type: integer
format: int32
name:
type: string
minItems: 1
uniqueItems: true
Best practice: Utilize array-level validations (minItems
, maxItems
, uniqueItems
) to enforce data integrity before it reaches your business logic.
5. Object
Objects in OpenAPI can be fully typed, serve as dictionaries, or be completely free-form. The level of detail you include can dramatically affect downstream processes like code generation.
Fully Typed Object
Define explicit properties with validations:
schema:
type: object
properties:
username:
type: string
age:
type: integer
format: int32
isActive:
type: boolean
required:
- username
- isActive
Dictionary (Using additionalProperties)
Use this for flexible key/value pairs where keys are always strings:
schema:
type: object
additionalProperties:
type: string
Best practice: When possible, define all properties explicitly. Reserve free-form objects (additionalProperties: true
or {}
) for cases where the structure genuinely cannot be predetermined.
6. Null
OpenAPI 3.0 doesn't have a separate null type. Instead, you mark a schema as nullable
to indicate that it can be either a valid value or null.
Example:
schema:
type: string
nullable: true
Best practice: Overusing nullable
can lead to ambiguity. Only mark a property as nullable if null is a valid, intentional state for that property.
Bringing It All Together
The beauty of OpenAPI lies in its versatility. While it's renowned for RESTful API descriptions, its design supports the nuances of RPC-based calls and other HTTP paradigms. The secret to leveraging OpenAPI types effectively is to be explicit. By rigorously defining data types, formats, and validations, you enhance your API's documentation and empower developers with tools that generate robust code and insightful documentation.
Remember, in the world of API design:
- Clarity is non-negotiable.
- Precision saves time down the line.
- Explicit definitions lead to better tooling integration.
By following these practices, you'll create OpenAPI specs that are as versatile and reliable as the APIs they describe.
Ready to take your API specifications to the next level? Explore more tips, best practices, and tools for creating bulletproof API documentation and client libraries at liblab.
Happy spec writing!
Before you go, check out our CLI tool that can automatically generate client libraries in 6+ languages for any API.Build an SDK For Any API