Extensions
Extensions add database and protocol support through lightweight binaries — keeping the core CLI small and focused.
What Are Extensions?#
Extensions are out-of-process binaries that handle protocols beyond HTTP REST. They communicate with the Braids gateway via JSON-over-stdin/stdout IPC. This keeps the core binary small while allowing support for PostgreSQL, MySQL, MongoDB, and gRPC.
Available Extensions#
| Protocol | Description | Package |
|---|---|---|
postgres |
PostgreSQL database queries | braids-ext-postgres |
mysql |
MySQL database queries | braids-ext-mysql |
mongodb |
MongoDB document queries | braids-ext-mongodb |
grpc |
gRPC service calls | braids-ext-grpc |
Installing Extensions#
There are three ways to install extensions:
1. CLI install
Use the braids extensions install command:
$ braids extensions install postgres
Downloading braids-ext-postgres v0.2.0...
Verifying checksum... ok
Installed to ~/.braids/extensions/braids-ext-postgres
2. Auto-download
When the gateway receives its first request that uses an extension connector, Braids automatically downloads the required extension binary if it is not already installed.
3. Manual
Download the binary from GitHub releases and place it in ~/.braids/extensions/.
List and update
$ braids extensions list
EXTENSIONS:
grpc not installed
mongodb not installed
mysql v0.1.0 installed 2025-03-10
postgres v0.1.0 installed 2025-03-10
4 extensions available, 2 installed
Install with: braids extensions install <protocol>
$ braids extensions update
Updating postgres... v0.1.0 → v0.1.1
Updating mysql... already up to date
2 extensions checked
PostgreSQL#
The postgres extension lets you use PostgreSQL queries as a connector source. Define a connection string and SQL queries in your resources.
connectors:
db:
type: postgres
config:
connection_string: ${DATABASE_URL}
resources:
users:
query: "SELECT id, email, name, created_at FROM users"
user_by_id:
query: "SELECT id, email, name, created_at FROM users WHERE id = $1"
schemas:
users:
fields:
id:
type: int
email:
type: string
name:
type: string
created_at:
type: datetime
endpoints:
/db/users:
schema: users
sources:
- connector: db
resource: users
mapping:
id: id
email: email
name: name
created_at: created_at
/db/users/{id}:
schema: users
sources:
- connector: db
resource: user_by_id
mapping:
id: id
email: email
name: name
created_at: created_at
Path parameters from the URL (like {id}) are passed as positional parameters to the SQL query ($1, $2, etc.) in the order they appear in the endpoint path.
MySQL#
The mysql extension works similarly to PostgreSQL. The connection string uses the Go DSN format, and SQL placeholders use ? instead of $1.
connectors:
mysql_db:
type: mysql
config:
connection_string: ${MYSQL_DSN}
resources:
products:
query: "SELECT id, name, price FROM products"
product_by_id:
query: "SELECT id, name, price FROM products WHERE id = ?"
The DSN format is user:pass@tcp(host:3306)/dbname. Path parameters are substituted into ? placeholders in the same positional order.
MongoDB#
The mongodb extension uses collection names and JSON filter strings instead of SQL queries.
connectors:
mongo:
type: mongodb
config:
connection_string: ${MONGO_URI}
resources:
orders:
collection: orders
filter: "{}"
order_by_id:
collection: orders
filter: "{\"_id\": \"{id}\"}"
Path parameters are substituted into the filter JSON string. {id} in the filter is replaced with the path parameter value from the endpoint URL.
gRPC#
The grpc extension calls gRPC services using reflection for service discovery.
connectors:
payments:
type: grpc
config:
target: localhost:50051
resources:
list_payments:
service: payments.PaymentService
method: ListPayments
The target is the gRPC server address. service and method identify the RPC to call. The extension uses gRPC reflection for service discovery, so no proto files are needed at configuration time.
Extension IPC Protocol#
For those building custom extensions, Braids communicates with extension binaries over a JSON-over-stdin/stdout protocol. Each message is a single JSON object followed by a newline.
Request format
The gateway sends a JSON request to the extension's stdin:
{
"action": "ping | fetch | shutdown",
"resource": "resource_name",
"params": {},
"path_params": {},
"config": {},
"conn_def": { ... }
}
Response format
The extension writes a JSON response to stdout:
{
"ok": true,
"records": [...],
"error": "message",
"version": "0.2.0"
}
Actions
| Action | Description |
|---|---|
ping |
Handshake. Extension responds with its version. Sent on process startup. |
fetch |
Retrieve records. Extension sends back an array of record objects. |
shutdown |
Graceful shutdown signal. Extension should clean up connections and exit. |
Process lifecycle
- Extensions are started on-demand when first needed
- A single process is reused for all requests to that protocol
- 5-second timeout for the
pinghandshake - On gateway shutdown: a
shutdownaction is sent, thenSIGKILLafter 5 seconds if the process is still running - Extension stderr is logged with the
[ext:<protocol>]prefix