Yookr Logo

Tutorial: Rust Integration

Production-grade prediction worker using reqwest and serde.

Rust offers the best performance and type-safety for production environments. prediction worker in Rust using the reqwest and serde libraries.

Table of Contents


1. Authentication

Authenticate with the API to get a Bearer token.

rust
// POST /serviceLogin with service_id and password
let login_body = serde_json::json!({
    "service_id": service_id,
    "password": service_password
});
// ... Receive token ...

2. Fetch Jobs

Get the list of active jobs to see what work needs to be done.

rust
// GET /api/v1/jobs/service/{service_id}
let jobs_url = format!("{}/api/v1/jobs/service/{}", base_url, service_id);
let jobs: Vec<Job> = client
    .get(&jobs_url)
    .header("Authorization", format!("Bearer {}", token))
    .send()
    .await?
    .json()
    .await?;

3. Process Each Job

Loop through the jobs. For each job, look at its bindings to find input parameters (like Location).

rust
for job in jobs {
    // Find the location binding to know WHERE to forecast for
    let location = job.job_role_bindings.iter()
        .find(|b| b.input_type == "location")
        .expect("Job must have a location binding");

    println!("Processing job {} for location: {}", job.id, location.name);

    // Call external API (e.g. Weather Provider) using the location coordinates
    let weather_data = fetch_weather(location.latitude, location.longitude).await?;
    
    // ... Map weather_data to the job targets ...
}

4. Map Data to Targets

Map external data (e.g., "temp_c") to the specific target_id requested by the Job.

rust
// Iterate through the job's 'targets' to see what metrics are required
for target in job.job_targets {
    if target.role == "temperature" {
        let value = weather_data.get_temperature();
        
        // Add to your prediction payload using the explicit target_id
        current_prediction.targets.push(PredictionTarget {
            target_id: target.target_id, // CRITICAL: Use the ID from the job
            value_num: Some(value),
        });
    }
}

5. Submit Predictions

Send the constructed payload back to the API.

rust
// POST /api/v1/predictions
let request = PredictionRequest {
    job_id: job.id,
    predictions: my_predictions
};

client
    .post("/api/v1/predictions")
    .header("Authorization", format!("Bearer {}", token))
    .json(&request)
    .send()
    .await?;

Why this pattern?

This job-driven approach allows you to add new Locations or change required Metrics in the Dashboard without modifying or redeploying your Rust code!