Octri

Rust

The Rust SDK publishes to crates.io. Operations are blocking calls on ureq, so a consumer needs no async runtime to use it. The crate depends on ureq, serde, serde_json and base64.

Install

bash
cargo add your-org-api-client

Or in Cargo.toml:

toml
[dependencies]
your-org-api-client = "1.0"

Options

Set these for Rust in SDK Studio. Each one names its key for octri sdk settings set. Every option, for every language, is in the settings reference.

Client stylechoicedefault: class

class gives callers a client to create. functions gives free functions to import. See client style.

clientStyleByLang.rust

Namespacechoicedefault: tags

Groups operations by tags, by URL path, or not at all with none.

namespaceByLang.rust

Method namingchoicedefault: short

short drops the group's word from the method name, and full keeps the operation ID. Set for every language at once.

methodNaming

Argument stylechoicedefault: positional

object takes one parameters object, and positional takes arguments in order. See argument style.

outputByLang.rust.argumentStyle

Doc commentschoicedefault: full

full or minimal.

outputByLang.rust.docComments

Usage examplechoicedefault: full

full or concise.

outputByLang.rust.usageExample

File headerchoicedefault: include

include or omit. Omitting it needs the Enterprise plan. Set for every language at once.

fileHeader

Package name

Crate names are global, flat, and first-come-first-served. There are no scopes, so the good short names went years ago:

text
acme-api
crates.io is permanent and unscoped

A crate name cannot be transferred away from you, reused, or renamed, and a published version can be yanked but never replaced. With no namespace to hide behind, pick a name you can live with. See Publishing.

What callers write

rust
use acme_api::{Acme, ClientAuthConfig, ClientConfig};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let acme = Acme::new(ClientConfig {
        base_url: Some("https://api.acme.com/v1".to_string()),
        auth: Some(ClientAuthConfig {
            bearer: Some(std::env::var("ACME_TOKEN")?),
            ..Default::default()
        }),
        ..Default::default()
    });

    // The closure sees each item. Return false to stop paging early.
    acme.users.list_paginated(Some(100), None, None, |user| {
        println!("{}", user.id);
        true
    })?;

    Ok(())
}

Every call returns a typed Result, so a caller who ignores a failure gets a compiler warning. SdkError is an enum with separate variants for validation, HTTP, network and timeout failures, and SdkHttpError::kind() maps the common statuses to SdkHttpErrorKind (NotFound, RateLimit and so on).

Async

The crate's async feature, off by default, adds a reqwest and tokio transport for the low-level request layer. The generated operation methods stay blocking, and consumers who never enable the feature never compile tokio.

Runtime

RequiresA current stable Rust toolchain
HTTPureq, blocking
Timeout30 seconds per attempt
RetriesUp to 3 attempts, with backoff from 500 ms to 8 seconds
Idempotency keysPOST and PATCH

Those are the defaults. See every setting and retries and timeouts to change them.

Streaming

For an operation that streams:

rust
for event in client.events.stream(None)? {
    println!("{}", event?.id);
}

An iterator of Result<Event, SdkError>. See streaming.

Handling errors

rust
match client.users.get("usr_1".to_string(), None) {
    Ok(user) => println!("{user:#?}"),
    Err(SdkError::Http(error)) => match error.kind() {
        SdkHttpErrorKind::NotFound => println!("no such user"),
        _ => eprintln!("{} {:?}", error.status_code, error.request_id),
    },
    Err(error) => return Err(error.into()),
}

SdkError is an enum with a variant per failure. Branch on common statuses with kind(). error.data holds the decoded model. See what's in the package.