force-rs
A canonical Salesforce Platform API client for Rust — built with production-grade safety, performance, and developer ergonomics.
force-rs provides idiomatic Rust bindings to the Salesforce Platform APIs, enabling you to build high-performance integrations, data pipelines, and automation tools. With comprehensive coverage of 7 API surfaces, compile-time safe workflows, and memory-efficient streaming, force-rs is designed for real-world enterprise workloads.
The workspace also includes force-sync, a Postgres-first bidirectional sync engine built on top of force and force-pubsub.
Features
REST API
- CRUD Operations - Create, read, update, delete, and upsert records with full type safety
- SOQL Queries - Execute typed queries with automatic pagination and streaming results
- SOSL Search - Full-text search across multiple objects with builder pattern
- Metadata Access - Describe objects, fields, and org limits programmatically
- Relationship Support - Query parent-child and lookup relationships seamlessly
Bulk API 2.0
- Compile-Time Safety - Strict guarantees for job lifecycle (Open -> Upload -> InProgress -> Complete)
- Ingest Jobs - Insert, update, upsert, and delete millions of records efficiently
- Query Jobs - Execute bulk queries with streaming CSV results
- Memory Efficient - Stream large datasets without loading entire payloads into RAM
- Error Handling - Comprehensive job monitoring and failure analysis
Composite API
- Batch Requests - Combine up to 25 subrequests in a single HTTP call
- Graph Requests - Up to 500 nodes with dependency ordering (feature:
composite_graph) - Reduced API Consumption - Minimize round trips and stay within governor limits
Tooling API
- Apex Management - Query and manage Apex classes, triggers, and components
- Execute Anonymous - Run Apex code on the fly with full result inspection
- Test Execution - Run Apex tests synchronously or asynchronously
- Code Completions - IDE-style completions for Apex and Visualforce
UI API
- Layout-Aware Records - Get presentation-ready data with display values and field visibility
- Object Metadata - Retrieve field info, picklist values, and record type mappings
- List Views - Access list view definitions, columns, and paginated records
- Lookups & Favorites - Type-ahead search and user favorite management
GraphQL API
- Unified Queries - Request specific fields and nested relationships in a single call
- Typed Results - Deserialize into custom Rust structs or use dynamic
Value - Variables & Operations - Parameterized queries with named operations
- Partial Success Handling - Inspect both data and errors when both are present
Core Features
- Multiple Auth Flows - JWT bearer, OAuth 2.0 client credentials
- Feature-Gated - Enable only the APIs you need for minimal binary size
- Async/Await - Built on Tokio for high-concurrency workloads
- Type-Safe Errors - Structured error types with context for debugging
- Production Ready - 870+ tests, zero clippy warnings, comprehensive examples
Installation
Add force-rs to your Cargo.toml:
[]
= "0.1"
= { = "1", = ["full"] }
= { = "1", = ["derive"] }
= "1.0"
# Or enable specific features:
= { = "0.1", = ["rest", "bulk", "jwt"] }
Quick Start
Here's a minimal example using OAuth 2.0 client credentials to query Salesforce:
use ClientCredentials;
use ForceClientBuilder;
use Deserialize;
async
Note: For Sandbox environments, use
ClientCredentials::new_sandbox("client-id", "client-secret")instead ofnew_production.
Advanced Examples
GraphQL Query
Query specific fields and nested relationships in a single request:
// Requires the "graphql" feature: force = { version = "0.1", features = ["graphql"] }
use GraphqlRequest;
use ClientCredentials;
use ForceClientBuilder;
use json;
async
Bulk Insert with Compile-Time Safety
The Bulk API uses Rust's type system to enforce the correct job lifecycle at compile time:
// Requires the "bulk" feature: force = { version = "0.1", features = ["bulk"] }
use ForceClientBuilder;
use ClientCredentials;
use Serialize;
async
Memory-Efficient Bulk Query
Stream millions of records without loading the entire dataset into memory:
// Requires the "bulk" feature: force = { version = "0.1", features = ["bulk"] }
use ForceClientBuilder;
use ClientCredentials;
use Deserialize;
// Requires `futures` crate
use StreamExt;
async
More Examples
The examples/ directory contains comprehensive demonstrations:
| Example | Feature | Description |
|---|---|---|
basic_crud.rs |
rest |
Complete CRUD lifecycle (create, read, update, delete) |
soql_query.rs |
rest |
Typed queries with pagination and relationships |
dynamic_query.rs |
rest |
Dynamic queries without predefined types |
search.rs |
rest |
SOSL full-text search with builder pattern |
describe.rs |
rest |
Object and field metadata introspection |
org_limits.rs |
rest |
API limits and usage monitoring |
bulk_insert.rs |
bulk |
Bulk insert with job monitoring |
bulk_query.rs |
bulk |
Bulk query with streaming results |
bulk_update.rs |
bulk |
Bulk update operations |
bulk_delete.rs |
bulk |
Bulk delete with error handling |
tooling.rs |
tooling |
Apex classes, anonymous execution, completions, tests |
ui_api.rs |
ui |
Layout-aware records, object info, list views, favorites |
graphql.rs |
graphql |
GraphQL queries, typed results, variables, error handling |
soql_mass_op.rs |
composite |
Composite batch operations |
query_plan.rs |
rest |
SOQL query plan inspection |
Run any example with:
Features Reference
force-rs uses feature flags to minimize dependencies and binary size:
| Feature | Description | Status |
|---|---|---|
rest |
REST API (CRUD, SOQL, SOSL, describe, limits) | Default |
bulk |
Bulk API 2.0 (ingest and query jobs) | Stable |
composite |
Composite API (batch requests) | Stable |
composite_graph |
Composite Graph API (dependency-ordered nodes) | Stable |
tooling |
Tooling API (Apex, execute anonymous, tests, completions) | Stable |
ui |
UI API (layout-aware records, object info, list views, favorites) | Stable |
graphql |
GraphQL API (queries, mutations, variables) | Stable |
jwt |
JWT bearer token authentication | Stable |
schema |
Schema analysis, scanning, and code generation utilities | Preview |
data_utility |
Mock-data generation and Salesforce seeding helpers | Preview |
mock |
Wiremock utilities for testing | Stable |
full |
All stable APIs (rest + bulk + composite + tooling + ui + graphql + jwt) |
Meta |
all |
Everything including preview features | Meta |
Recommendation: Start with default features, then add bulk and jwt as needed.
Preview Features
The force crate includes preview features for early adopters. These capabilities live in their real modules and remain feature-gated while the API settles before a future stabilization pass.
Query Plan API
Available with the default
restfeature.
The Query Plan API allows you to inspect the performance cost of a SOQL query before executing it. This is useful for identifying inefficient queries (e.g., table scans) in CI/CD pipelines.
[]
= "0.1"
// Available with the default "rest" feature: force = "0.1"
use ForceClientBuilder;
use ClientCredentials;
async
Preview Utility Modules
Preview utilities now live in the modules that own them:
force::api::composite::{QueryBatch, SoqlMassOp}: batch-aware helpers built on the Composite API.force::api::rest::analyze_query_plan: turnsexplain()responses into actionable warnings.force::schema: schema scanning, diffing, visualization, DDL export, and code generation helpers.force::data: mock-record generation and bulk seeding helpers.
Architecture
force-rs is built around a handler pattern where each API surface gets its own feature-gated handler type:
ForceClient<A>
|-- .rest() -> RestHandler<A> (feature: rest)
|-- .bulk() -> BulkHandler<A> (feature: bulk)
|-- .composite() -> CompositeHandler<A> (feature: composite)
|-- .tooling() -> ToolingHandler<A> (feature: tooling)
|-- .ui() -> UiHandler<A> (feature: ui)
|-- .graphql() -> GraphqlHandler<A> (feature: graphql)
All handlers share a common Session<A> (via Arc) containing the HTTP client, token manager, and configuration. This ensures zero-cost handler creation and shared authentication state.
For the sync layer, see crates/force-sync and its design notes in docs/adr/026-force-sync-crate.md.
Architectural decisions are documented in docs/adr/:
| ADR | Decision |
|---|---|
| 001 | Workspace structure and module organization |
| 002 | Authentication trait design and flow support |
| 003 | Error hierarchy with thiserror |
| 004 | Feature flag strategy for API surfaces |
| 005 | Compile-time auth safety with phantom types |
| 006 | Handler pattern for API organization |
| 007 | REST API design decisions |
| 019 | RestOperation trait and Tooling API |
| 020 | UI API handler design |
| 021 | GraphQL API error handling strategy |
Testing
force-rs has comprehensive test coverage (870+ tests) using wiremock for HTTP mocking:
# Run all tests
# Run with logging
RUST_LOG=debug
# Run specific API surface tests
Nightly live-contract tests (ignored by default in local runs) are available in CI and can be run manually with org credentials.
Enterprise DX and Governance
Runbooks
- Auth Credential Rotation
- Rate-Limit Incident Response
- Retry and Polling Tuning
- Salesforce API Version Upgrade
- Documentation Index
API Guarantees
The crate-level compatibility and feature-flag guarantees are documented in:
Incubation Specs
CI Lanes
- Fast unit/lint/format gates for PR velocity
- Full test lanes for broader confidence
- Nightly live-contract workflow for real Salesforce contract validation
Contributing
Contributions are welcome! force-rs follows strict TDD discipline and quality standards:
- Test-Driven Development - All features require failing tests first (RED -> GREEN -> REFACTOR)
- Code Quality -
cargo fmtandcargo clippy -- -D warningsmust pass - Documentation - All public APIs require doc comments with examples
- Architecture - ADRs (Architecture Decision Records) for significant changes
See CONTRIBUTING.md for detailed guidelines.
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Built by the force-rs contributors | Documentation | Examples | Issues