JSON-LD Connection Configuration (Rust)
This page documents the JSON-LD connection config supported by the Rust implementation.
This config uses the same @context + @graph model as other Fluree JSON-LD config surfaces.
Using with the Fluree server
The server accepts a connection config file via --connection-config:
fluree server run --connection-config /path/to/connection.jsonld
This replaces --storage-path for S3, DynamoDB, and other non-filesystem backends. The server builds its storage and nameservice from the config file at startup. Server-level settings (--cache-max-mb, --indexing-enabled, etc.) override connection config defaults. See Configuration for full details and examples.
Entry points (Rust API)
All construction flows through FlureeBuilder:
FlureeBuilder::from_json_ld(&json)?— parses JSON-LD config into builder settings- Then call
.build_client().awaitfor a type-erasedFlureeClient - Or use typed terminal methods (
.build(),.build_memory(),.build_s3()) for compile-time type safety
- Then call
JSON-LD shape
At minimum, your document contains:
@contextwith@baseand@vocab@graphwith:- one
Connectionnode - one or more
Storagenodes - optional
Publishernodes (nameservice backends)
- one
{
"@context": {
"@base": "https://ns.flur.ee/config/connection/",
"@vocab": "https://ns.flur.ee/system#"
},
"@graph": [
{ "@id": "storage1", "@type": "Storage", "filePath": "./data" },
{
"@id": "connection",
"@type": "Connection",
"indexStorage": { "@id": "storage1" }
}
]
}
ConfigurationValue (env var indirection)
Many fields can be provided as direct literals or as a ConfigurationValue object:
{
"s3Bucket": { "envVar": "FLUREE_S3_BUCKET", "defaultVal": "my-bucket" },
"cacheMaxMb": { "envVar": "FLUREE_CACHE_MAX_MB", "defaultVal": "1024" }
}
Notes:
envVar: reads from environment (non-wasm targets)defaultVal: fallback string valuejavaProp: accepted for compatibility; Rust treats it like another env var key (best-effort)
Connection node fields
Supported:
parallelism(default 4)cacheMaxMb(supportsConfigurationValue)indexStorage(required): reference to aStoragenodecommitStorage(optional): reference to aStoragenodeprimaryPublisher(optional): reference to aPublishernodeaddressIdentifiers(read routing): map of identifier → storage referencedefaults(partial):defaults.indexing.reindexMinBytes/reindexMaxBytesare applied as the defaultIndexConfigfor writesdefaults.indexing.indexingEnabled=falsesuppresses background index triggersdefaults.indexing.maxOldIndexessets the maximum number of old index versions to retain before GC (default: 5)defaults.indexing.gcMinTimeMinssets the minimum age in minutes before an index can be garbage collected (default: 30)
addressIdentifiers (read routing)
The addressIdentifiers field maps identifier strings to storage backends, enabling read routing based on the identifier segment in Fluree addresses.
{
"@id": "connection",
"@type": "Connection",
"indexStorage": {"@id": "indexS3"},
"commitStorage": {"@id": "commitS3"},
"addressIdentifiers": {
"commit-storage": {"@id": "commitS3"},
"index-storage": {"@id": "indexS3"}
}
}
Routing behavior:
fluree:commit-storage:s3://db/commit/abc.fcv2→ routes tocommitS3fluree:index-storage:s3://db/index/xyz.json→ routes toindexS3fluree:s3://db/index/xyz.json(no identifier) → routes to default storagefluree:unknown-id:s3://db/file.json(unknown identifier) → fallback to default storage
Notes:
- Writes always go to the default storage (TieredStorage or indexStorage), regardless of identifier
- This is a read-only routing mechanism for addresses that already contain identifiers
- Use
addressIdentifier(singular) on storage nodes to write addresses with identifier segments
Not yet supported (parsed/ignored or absent):
remoteSystems— not supported
Storage node fields
Memory storage
{ "@id": "mem", "@type": "Storage" }
File storage (requires native)
Supported:
filePathAES256Key(supportsConfigurationValue)durability—"wal"(default),"sync"or"page-cache"
Notes:
- Rust expects
AES256Keyto be base64-encoded and decode to exactly 32 bytes. - This encrypts the index/commit blobs written via the storage layer. The file-based nameservice remains plaintext, matching the existing builder behavior.
{
"@id": "fileStorage",
"@type": "Storage",
"filePath": "/var/lib/fluree",
"AES256Key": { "envVar": "FLUREE_ENCRYPTION_KEY" },
"durability": "sync"
}
durability
Filesystem syncing (FSYNC) is on by default. Leave this property unset for the
default behavior, or use "page-cache" to turn syncing off in a storage config.
| Value | Meaning |
|---|---|
wal (default) | FSYNC on. Acknowledged commits survive process crashes and power loss. |
sync | FSYNC on, flushing each file individually. Acknowledged commits survive process crashes and power loss. |
page-cache | FSYNC off. Writes reach the OS page cache, but a power loss or kernel panic can lose acknowledged commits. |
Writes remain atomic with every setting. An unrecognized value is rejected at config load.
To turn FSYNC off without editing the config, set FLUREE_STORAGE_FSYNC=0 before
starting Fluree. Set FLUREE_STORAGE_FSYNC=1 to turn it back on. This environment
variable overrides the durability property. See
Storage durability.
S3 storage (requires aws)
Supported fields (parsed and applied by Rust):
s3Buckets3Prefixs3Endpoint(optional; recommended only for LocalStack/MinIO/custom endpoints)s3ForcePathStyle(optional;truefor MinIO-class endpoints without bucket-subdomain DNS)s3ReadTimeoutMs,s3WriteTimeoutMs,s3ListTimeoutMs- Rust applies a single operation timeout of
max(read, write, list)
- Rust applies a single operation timeout of
s3MaxRetries,s3RetryBaseDelayMs,s3RetryMaxDelayMs- Rust maps
s3MaxRetriesto AWS SDKmax_attempts = max_retries + 1
- Rust maps
s3MaxConcurrentRequests- Optional per-storage-instance cap on concurrent S3 SDK operations
Standard S3 (AWS)
{
"@id": "s3",
"@type": "Storage",
"s3Bucket": "fluree-prod-data",
"s3Prefix": "fluree/"
}
LocalStack (custom endpoint)
{
"@id": "s3",
"@type": "Storage",
"s3Bucket": "fluree-test",
"s3Endpoint": "http://localhost:4566",
"s3Prefix": "fluree/"
}
MinIO (custom endpoint + path-style)
{
"@id": "s3",
"@type": "Storage",
"s3Bucket": "fluree",
"s3Endpoint": "http://minio:9000",
"s3ForcePathStyle": true
}
s3ForcePathStyle addresses the bucket in the URL path
(http://minio:9000/fluree/key) instead of as a virtual host
(http://fluree.minio:9000/key). An endpoint override alone is not enough: the
SDK still emits virtual-hosted URLs, and a plain MinIO — anything without
wildcard DNS for bucket subdomains in front of it — rejects them. LocalStack
resolves both forms. Leave it unset for real AWS. The builder equivalent is
FlureeBuilder::s3(bucket, endpoint).s3_force_path_style(true).
S3 Express One Zone
Rust relies on the AWS SDK’s native support for directory buckets. We also provide bucket-name
detection (--x-s3 + -azN) for diagnostics.
{
"@id": "s3Express",
"@type": "Storage",
"s3Bucket": "my-index--use1-az1--x-s3",
"s3Prefix": "indexes/"
}
Note: omit s3Endpoint for Express directory buckets and let the AWS SDK handle endpoint
resolution. FlureeBuilder::s3() is designed for standard and LocalStack
endpoints; for Express buckets, use FlureeBuilder::from_json_ld() with a config that omits
s3Endpoint.
Guidance:
- Standard S3 in AWS: omit
s3Endpoint(let the SDK pick defaults) - Express One Zone: omit
s3Endpoint - LocalStack/custom: set
s3Endpoint - MinIO: set
s3Endpointands3ForcePathStyle: true
For serverless index-storage tradeoffs, including Standard S3 vs S3 Express One Zone benchmark ranges, see Serverless Storage Choices.
addressIdentifier
Rust parses addressIdentifier on storage nodes and uses it to rewrite published
commit/index ContentIds so they include the identifier segment, e.g.:
fluree:{addressIdentifier}:s3://....
This is mainly useful when you have multiple storage backends and want addresses to carry an explicit storage identifier.
Split commit vs index storage (tiered S3)
Rust supports the tiered commitStorage + indexStorage format via FlureeBuilder::from_json_ld() / build_client().
Internally, Rust routes:
.../commit/...and.../txn/...→ commit storage- everything else → index storage
S3 only today. The routing itself (TieredStorage) is backend-agnostic, but
it is constructed only on the S3 path. A file-storage connection builds a single
backend from indexStorage and ignores commitStorage, so on file storage the
commit/index split is expressed by durability within one backend
rather than by two storage nodes.
{
"@context": {"@base": "https://ns.flur.ee/config/connection/", "@vocab": "https://ns.flur.ee/system#"},
"@graph": [
{ "@id": "commitStorage", "@type": "Storage", "s3Bucket": "commits-bucket", "s3Prefix": "fluree-data/" },
{ "@id": "indexStorage", "@type": "Storage", "s3Bucket": "index--use1-az1--x-s3" },
{ "@id": "publisher", "@type": "Publisher", "dynamodbTable": "fluree-nameservice", "dynamodbRegion": "us-east-1" },
{
"@id": "connection",
"@type": "Connection",
"commitStorage": {"@id": "commitStorage"},
"indexStorage": {"@id": "indexStorage"},
"primaryPublisher": {"@id": "publisher"}
}
]
}
IPFS storage (requires ipfs)
Supported:
ipfsApiUrl(defaulthttp://127.0.0.1:5001): Kubo HTTP RPC API base URLipfsPinOnPut(defaulttrue): pin blocks after writing
{
"@id": "ipfsStorage",
"@type": "Storage",
"ipfsApiUrl": "http://127.0.0.1:5001",
"ipfsPinOnPut": true
}
With env var indirection:
{
"@id": "ipfsStorage",
"@type": "Storage",
"ipfsApiUrl": { "envVar": "FLUREE_IPFS_API_URL", "defaultVal": "http://127.0.0.1:5001" },
"ipfsPinOnPut": true
}
Notes:
- Requires a running Kubo node at the specified URL
- Fluree’s CIDs (SHA-256 + private-use multicodec) are stored directly into IPFS
- No encryption support (
AES256Keyis not applicable) - See IPFS Storage Guide for Kubo setup and operational details
Publisher (nameservice) node fields
Storage-backed nameservice
Supported:
storage(reference to aStoragenode)
{
"@id": "publisher",
"@type": "Publisher",
"storage": { "@id": "s3" }
}
DynamoDB nameservice (requires aws)
Supported (and applied):
dynamodbTabledynamodbRegiondynamodbEndpointdynamodbTimeoutMs
Compatibility notes
This Rust JSON-LD model is intended to stay aligned with existing Fluree docs:
../db/docs/S3_STORAGE_GUIDE.md../db/docs/FILE_STORAGE_GUIDE.md../db/docs/DYNAMODB_NAMESERVICE_GUIDE.md
Current intentional gaps in Rust:
remoteSystemsnot supporteddefaults.identityis parsed but not currently applieddefaults.indexing.trackClassStatsis parsed but not currently applied