A Different Kind of Conversation
So far, everything we've discussed has been about a request-response conversation. The client asks a question (GET /books), and the server gives an answer. It's a predictable, one-time exchange.
But what if you need the server to send updates to the client without being asked? What if you want real-time notifications, live dashboard updates, or a chat application?
This requires a different kind of conversation: a subscription.
- Request-Response (OpenAPI): Like calling a pizza place. You call, you order, you get a pizza. The conversation is over.
- Subscription (AsyncAPI): Like subscribing to a magazine. You sign up once, and then the publisher sends you a new issue every month without you having to ask again.
The optional asyncapi block in your firestone blueprint is how you define this subscription-based, event-driven part of your API. It uses the AsyncAPI standard, which is a sister specification to OpenAPI, but designed for asynchronous communication like WebSockets.
The Two Parts of a Subscription
Setting up a subscription in firestone has two main parts, just like signing up for a magazine.
1. The Mailing Address (servers)
First, you need to tell clients where to connect to subscribe. The servers block is a dictionary of your WebSocket server addresses.
asyncapi:
servers:
# You can define multiple environments.
dev:
url: ws://localhost:8080 # The address for the dev server.
protocol: ws # Use 'ws' for local, 'wss' for secure production.
description: Development WebSocket server
2. The Topics (channels)
Next, you define what clients can subscribe to. These topics are called channels. firestone can automatically create channels that correspond to the three levels of your resource.
asyncapi:
# ... server definition from above
channels:
resources: true # A channel for events about the whole collection.
instances: true # A channel for events about a single item.
By setting these to true, you create "newsletters" that clients can subscribe to.
Visualizing a Subscription
This diagram shows how a client subscribes to the "new books" newsletter.
sequenceDiagram
participant C as Client
participant S as Server
C->>S: 1. Connect to WebSocket server (ws://localhost:8080)
S-->>C: Connection established
C->>S: 2. Subscribe to the '/books' channel
S-->>C: Subscription confirmed
Note over C,S: Later, when a new book is created...
S->>C: 3. Server pushes a "new book" event!
A Practical Example: Real-Time Alerts
Let's see how REST and AsyncAPI can work together. Imagine an alerts resource. We want to create alerts via a standard REST endpoint, but we also want other services to be notified in real-time when a new alert is created.
Resource Blueprint (alerts.yaml):
kind: alerts
apiVersion: v1
# Enable POST for creating alerts via REST.
methods:
resource: [post]
# Define the WebSocket server and channel.
asyncapi:
servers:
event_bus:
url: wss://events.example.com
protocol: wss
channels:
resources: true # Create a channel for collection-level events.
schema:
type: array
key: { name: alert_id }
items:
properties:
severity:
type: string
enum: [info, warning, critical]
message:
type: string
required: [severity, message]
How it Works:
- Service A creates a new alert by making a standard HTTP request:
POST /alertswith a body like{"severity": "critical", "message": "CPU is on fire!"}. - Service B (and C, and D...) has already connected to
wss://events.example.comand is listening to the/alertschannel. - As soon as the
POSTrequest is processed, the server internally publishes an event to the/alertschannel. - Service B, C, and D all instantly receive the new alert message (
{"severity": "critical", ...}), allowing them to react in real-time.
Congratulations!
You have now learned about all the major top-level building blocks of a firestone resource schema! You know how to:
- Name and version your resource (
kind,apiVersion). - Describe its purpose (
metadata). - Define its actions and security (
methods,security). - Define its data structure (
schema). - And now, how to add real-time capabilities (
asyncapi).
You have all the tools you need to design a robust and well-documented API.
Next Steps
With your blueprint complete, the next step is to learn how firestone uses it to generate different outputs.
- Next: Start with the most common output: OpenAPI Generation.