Skip to content

BREAKING: Modularize client architecture; add Bulk, Tooling, and Metadata API support - #36

Open
tance77 wants to merge 8 commits into
tzmfreedom:mainfrom
tance77:modular-client-refactor
Open

BREAKING: Modularize client architecture; add Bulk, Tooling, and Metadata API support#36
tance77 wants to merge 8 commits into
tzmfreedom:mainfrom
tance77:modular-client-refactor

Conversation

@tance77

@tance77 tance77 commented Mar 13, 2026

Copy link
Copy Markdown

⚠️ Breaking Changes

This is a major refactor that restructures the crate's internals and changes the public API. It is not backwards compatible with the current release.

What breaks

  • Response types removed: All typed response structs (QueryResponse, SearchResponse, DescribeResponse, etc.) have been removed. Methods now return serde_json::Value, giving consumers full flexibility to deserialize as needed.
  • Module structure changed: src/client.rs and src/response.rs have been split into submodules. Anyone importing internals directly will need to update paths.
  • Client constructor changed: Now takes client_id and client_secret directly, with setters for login URL, version, etc.
  • Removed describe_global example (method still exists)
  • Removed old integration tests — they depended on the deleted response types

What's new

Modular architecture
Client split into focused submodules — client, rest_api, bulk_api, bulk_api_v2, tooling_api, metadata_api — each wrapping a shared Client that owns auth and token refresh.

Bulk API v1 (bulk_api)
XML-based classic Bulk API: job create/close/abort, batch submission, status polling, result retrieval.

Bulk API v2 (bulk_api_v2)
CSV/JSON-based Bulk API v2 job lifecycle.

Tooling API (tooling_api)

  • execute_anonymous for running Apex, returning a typed ExecuteAnonymousResult (compile/run success, line/column, stack trace)
  • Debug log access: get_latest_apex_logs, get_apex_log_body
  • Trace flag and debug level management: create_trace_flag, update_trace_flag, delete_trace_flag, get_trace_flags, get_debug_level, create_debug_level, get_current_user_id
  • Generic Tooling object CRUD + SOQL: query, find_by_id, create, update, destroy

Metadata API (metadata_api)
CRUD-based (not file-based) Metadata API over SOAP — the Metadata API has no REST binding for these calls.

  • create_metadata / delete_metadata / delete_metadata_chunked, returning per-component MetadataResult with success and structured MetadataErrors
  • Exists because some operations have no equivalent elsewhere — notably deleting a CustomField, which the Tooling API does not support at all (that object exposes only Query/GET/POST/PATCH)
  • Enforces Salesforce's per-call component caps before sending (10 for most types, 200 for CustomMetadata / CustomApplication); delete_metadata_chunked splits oversized input automatically
  • JSON payloads are serialised to XML in the element order the Metadata WSDL's sequence requires (fullName first, then alphabetical), since Salesforce rejects out-of-order elements

Shared XML support (src/xml.rs)
Common XML escaping/serialisation used by the Bulk and Metadata clients.

Other

  • Dedicated response modules: token_response, token_error_response, error_response, execute_anonymous_response
  • Dedicated access_token module for token management
  • More granular error variants in errors.rs
  • Edition 2021, dependencies updated
  • New examples: execute_anonymous, debug_logs, trace_flags, versions

Why

The original monolithic client.rs was difficult to extend. Typed response structs broke when Salesforce changed their API payloads. Returning generic JSON is more resilient and lets consumers define their own types if needed. Splitting per-API keeps each surface independently testable, which is what made adding the Tooling and Metadata clients cheap.

Test plan

  • Verify existing examples compile and run against a Salesforce instance
  • Test Bulk API v1 job creation, batching, and result retrieval
  • Test Bulk API v2 job lifecycle
  • Verify authentication flows (login, refresh token)
  • Test Tooling API execute_anonymous, debug log retrieval, and trace flag lifecycle
  • Test Metadata API CustomField create and delete against a scratch org
  • Unit tests for SOAP response parsing, XML element ordering/escaping, and component-limit enforcement (cargo test)

tance77 added 3 commits March 13, 2026 13:58
Split monolithic client.rs into organized submodules (client, rest_api).
Split response.rs into dedicated response types (token, error).
Add access_token module for token management.
Modernize error handling, update dependencies, and remove outdated tests.
Add bulk_api module for Salesforce Bulk API v1 (XML-based).
Add bulk_api_v2 module for Bulk API v2 (CSV/JSON-based).
Add XML utility module for serialization/deserialization.
Rewrite examples to use generic JSON responses (serde_json::Value).
Update README with current API usage and module structure.
@tance77
tance77 force-pushed the modular-client-refactor branch from 46c78d8 to 1730ffd Compare March 13, 2026 20:58
@tance77 tance77 changed the title Modularize client architecture, add Bulk API support BREAKING: Modularize client architecture, add Bulk API support Mar 13, 2026
@tance77
tance77 marked this pull request as ready for review March 13, 2026 21:17
@tance77

tance77 commented Mar 16, 2026

Copy link
Copy Markdown
Author

Adding Tooling API Support

@wimvelzeboer

wimvelzeboer commented Aug 4, 2026

Copy link
Copy Markdown

Hi @tance77 ,
I saw your PR while I was looking for a crate that integrates Rust and Salesforce, and I noticed that it looks like this repo is abandoned. With last updates from a year or two ago.
That is why I forked this repo and applied your changes there.
I also modified some methods (mostly what they return), using rust generics I was able to replace the Value of some return methods into specific responses.
What do you think of my changes? Rustsf crate

I plan to add support for the metadata api, which I require for my project.

Let me know what you think, maybe we can work together in getting rustforce to the next level.

@tance77

tance77 commented Aug 4, 2026

Copy link
Copy Markdown
Author

@wimvelzeboer feel free to take the reins my times very limited when it comes to open source projects. Ill contribute from time to time but that's about it. I'm glad to see there are some active members out there wanting to see this one through.

SOAP deleteMetadata with chunking at the 10-component cap. Tooling
API's CustomField exposes no delete, so field teardown has no other
path.
Pin the fullName-first, otherwise-alphabetical element order the WSDL
sequence requires, plus null omission, escaping, nesting, and per-type
component caps.
@tance77 tance77 changed the title BREAKING: Modularize client architecture, add Bulk API support BREAKING: Modularize client architecture; add Bulk, Tooling, and Metadata API support Aug 13, 2026
@tance77

tance77 commented Aug 13, 2026

Copy link
Copy Markdown
Author

@wimvelzeboer added Metadata cause i needed it.

@wimvelzeboer

Copy link
Copy Markdown

@wimvelzeboer added Metadata cause i needed it.

Thanks! Let me see if I can copy it over to my Rustsf crate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants