Organizing Large Projects
Real-world APIs consist of many resources (users, posts, comments). Firestone is designed to handle this complexity through a modular file structure.
Best Practice: One File Per Resource Avoid monolithic files. Create a dedicated directory:
project/
├── resources/
│ ├── users.yaml
│ ├── posts.yaml
│ ├── comments.yaml
│ └── common/
│ └── definitions.yaml
Generating from a Directory:
Firestone's CLI natively supports directory inputs. Pass the folder path to --resources:
firestone generate \
--title "My Platform API" \
--resources ./resources/ \
openapi > openapi.yaml
Firestone will parse all valid resource files in the directory and merge them into a single, unified specification. This allows independent development of resources while maintaining a cohesive API surface.
Best Practice: Structure and Manage Multi-Resource APIs
While a single resource schema is great for simple APIs, most real-world applications consist of multiple, interrelated resources (e.g., users, posts, and comments). Firestone is designed to handle this complexity, and following best practices for structuring your multi-resource project is crucial for maintainability and scalability.
The "One Resource, One File" Principle
The most fundamental best practice for multi-resource APIs is to define each resource in its own separate YAML file.
- DO have
users.yaml,posts.yaml, andcomments.yaml. - DON'T define all your resources in a single, monolithic
api.yaml.
This approach provides several advantages:
- Clarity and Focus: Each file has a single, clear purpose, making it easier to understand and edit.
- Reduced Cognitive Load: Developers can focus on one resource at a time without being overwhelmed.
- Parallel Development: Different teams or developers can work on different resource files simultaneously with a lower risk of merge conflicts.
Project Structure Recommendation
We recommend organizing your resource schemas in a dedicated directory, such as resources/ or schemas/, at the root of your project.
your-project/
├── resources/
│ ├── users.yaml
│ ├── posts.yaml
│ ├── comments.yaml
│ └── common.json # Shared schema definitions
├── .firestone.yaml # Project configuration (optional)
└── ...
Generating from Multiple Files
When you're ready to generate your API specifications, you simply pass the directory containing your resource files to the firestone generate command using the --resources flag.
# Generate a single OpenAPI spec from all resource files
firestone generate \
--title "My Multi-Resource API" \
--resources ./resources/ \
openapi > openapi.yaml
Firestone will intelligently combine all the schemas into a single, cohesive OpenAPI specification, complete with all the necessary paths, components, and relationships.
Reusing Schemas with $ref
To avoid duplication and ensure consistency across your resources, you should define common or shared data structures in a separate file (e.g., common.json) and reference them using the standard JSON Schema $ref keyword.
For example, you might have a standard Timestamp or UUID format that you want to use in multiple resources.
resources/common.json:
{
"schemas": {
"Timestamp": {
"type": "string",
"format": "date-time",
"description": "An ISO 8601 compliant timestamp."
},
"UUID": {
"type": "string",
"format": "uuid",
"description": "A universally unique identifier."
}
}
}
resources/posts.yaml:
kind: posts
apiVersion: v1
schema:
type: array
key:
name: post_id
schema:
$ref: 'common.json#/schemas/UUID'
items:
type: object
properties:
created_at:
$ref: 'common.json#/schemas/Timestamp'
# ... other properties
By following these structuring practices, you can build large, complex, and maintainable APIs with Firestone while keeping your project organized and easy to navigate.