pub struct Client<A: Authenticate> {
    pub url: &'static str,
    /* private fields */
}
Expand description

A client capable of connecting to a dataverse environment

A client should be created once and then reused to take advantage of its connection-pooling.

Examples

let client_id = String::from("<clientid>");
let client_secret = String::from("<clientsecret>");

let client = Client::with_client_secret_auth(
    "https://instance.crm.dynamics.com/",
    "12345678-1234-1234-1234-123456789012",
    client_id,
    client_secret,
);

Fields

url: &'static str

Implementations

Creates a dataverse client that uses client/secret authentication

Please note that this function will not fail right away even when the provided credentials are invalid. This is because the authentication is handled lazily and a token is only acquired on the first call or when an acquired token is no longer valid and needs to be refreshed

Examples
let client_id = String::from("<clientid>");
let client_secret = String::from("<clientsecret>");

let client = Client::with_client_secret_auth(
    "https://instance.crm.dynamics.com/",
    "12345678-1234-1234-1234-123456789012",
    client_id,
    client_secret,
);

Creates a dataverse client with a custom authentication handler and backend

This function may not panic so the custom authentication should follow these rules:

  • tokens should be acquired lazily
  • tokens should be cached and reused where possible
  • each call to the get_valid_token() function should give a token that is valid for at least the next 2 minutes
Examples
let client = reqwest::Client::builder()
    .https_only(true)
    .connect_timeout(Duration::from_secs(120))
    .timeout(Duration::from_secs(120))
    .build()
    .unwrap();

let auth = ClientSecretAuth::new(
    client.clone(),
    format!(
        "https://login.microsoftonline.com/{}/oauth2/v2.0/token",
        tenant_id
    ),
    format!("{}.default", url),
    client_id,
    client_secret,
);

Client::new(url, client, auth)

Writes the given entity into the current dataverse instance and returns its generated Uuid

This may fail for any of these reasons

  • An authentication failure
  • A serde serialization error
  • Any http client or server error
  • there is already a record with this Uuid in the table
Examples
let contact = Contact {
    contactid: Uuid::parse_str("12345678-1234-1234-1234-123456789012").unwrap(),
    firstname: String::from("Testy"),
    lastname: String::from("McTestface"),
};

client.create(&contact).await.unwrap();

#[derive(Serialize)]
struct Contact {
    contactid: Uuid,
    firstname: String,
    lastname: String,
}

impl WriteEntity for Contact {}

impl Reference for Contact {
    fn get_reference(&self) -> ReferenceStruct {
        ReferenceStruct::new(
            "contacts",
            self.contactid,
        )
    }
}

Updates the attributes of the gven entity in the current dataverse instance

Please note that only those attributes are updated that are present in the serialization payload. Other attributes are untouched

This may fail for any of these reasons

  • An authentication failure
  • A serde serialization error
  • Any http client or server error
  • there is no record with this Uuid in the table
Examples
let contact = Contact {
    contactid: Uuid::parse_str("12345678-1234-1234-1234-123456789012").unwrap(),
    firstname: String::from("Testy"),
    lastname: String::from("McTestface"),
};

client.update(&contact).await.unwrap();

#[derive(Serialize)]
struct Contact {
    contactid: Uuid,
    firstname: String,
    lastname: String,
}

impl WriteEntity for Contact {}

impl Reference for Contact {
    fn get_reference(&self) -> ReferenceStruct {
        ReferenceStruct::new(
            "contacts",
            self.contactid,
        )
    }
}
    

Updates or creates the given entity in the current dataverse instance

Please note that only those attributes are updated that are present in the serialization payload. Other attributes are untouched

This may fail for any of these reasons

  • An authentication failure
  • A serde serialization error
  • Any http client or server error
Examples
let contact = Contact {
    contactid: Uuid::parse_str("12345678-1234-1234-1234-123456789012").unwrap(),
    firstname: String::from("Testy"),
    lastname: String::from("McTestface"),
};

client.upsert(&contact).await.unwrap();

#[derive(Serialize)]
struct Contact {
    contactid: Uuid,
    firstname: String,
    lastname: String,
}

impl WriteEntity for Contact {}

impl Reference for Contact {
    fn get_reference(&self) -> ReferenceStruct {
        ReferenceStruct::new(
            "contacts",
            self.contactid,
        )
    }
}
    

Deletes the entity record this reference points to

Please note that each structs that implements WriteEntity also implements Reference so you can use it as input here, but there is a sensible default implementation called ReferenceStruct for those cases where you only have access to the raw reference data

This may fail for any of these reasons

  • An authentication failure
  • Any http client or server error
  • The referenced entity record doesn’t exist
Examples
let reference = ReferenceStruct::new(
    "contacts",
    Uuid::parse_str("12345678-1234-1234-1234-123456789012").unwrap()
);

client.delete(&reference).unwrap();

retrieves the entity record that the reference points to from dataverse

This function uses the implementation of the Select trait to only retrieve those attributes relevant to the struct defined. It is an Anti-Pattern to retrieve all attributes when they are not needed, so this library does not give the option to do that

This may fail for any of these reasons

  • An authentication failure
  • A serde deserialization error
  • Any http client or server error
  • The entity record referenced doesn’t exist
Examples
let contact: Contact = client
    .retrieve(
        &ReferenceStruct::new(
            "contacts",
            Uuid::parse_str("12345678-1234-1234-1234-123456789012").unwrap()
        )
    )
    .await
    .unwrap();

#[derive(Deserialize)]
struct Contact {
    contactid: Uuid,
    firstname: String,
    lastname: String,
}

impl ReadEntity for Contact {}

impl Select for Contact {
    fn get_columns() -> &'static [&'static str] {
        &["contactid", "firstname", "lastname"]
    }
}

Executes the query and retrieves the entities from dataverse

This function uses the implementation of the Select trait to only retrieve those attributes relevant to the struct defined. It is an Anti-Pattern to retrieve all attributes when they are not needed, so this library does not give the option to do that

Please note that if you don’t specify a limit then the client will try to retrieve all matching records. This can take a lot of time.

This may fail for any of these reasons

  • An authentication failure
  • A serde deserialization error
  • Any http client or server error
Examples
// this query retrieves the first 3 contacts
let query = Query::new("contacts").limit(3);
let contacts = client.retrieve_multiple(&query).unwrap();

#[derive(Deserialize)]
struct Contact {
    contactid: Uuid,
    firstname: String,
    lastname: String,
}

impl ReadEntity for Contact {}

impl Select for Contact {
    fn get_columns() -> &'static [&'static str] {
        &["contactid", "firstname", "lastname"]
    }
}

executes the batch against the dataverse environment

This function will fail if:

  • the batch size exceeds 1000 calls
  • the batch execution time exceeds 2 minutes

the second restriction is especially tricky to handle because the execution time depends on the complexity of the entity in dataverse. So it is possible to create 300 records of an entity with low complexity but only 50 records of an entity with high complexity in that timeframe.

Based on experience a batch size of 50 should be safe for all entities though

Examples
let testy_contact = Contact {
    contactid: Uuid::parse_str("12345678-1234-1234-1234-123456789012").unwrap(),
    firstname: String::from("Testy"),
    lastname: String::from("McTestface"),
};

let marianne_contact = Contact {
    contactid: Uuid::parse_str("12345678-1234-1234-1234-123456789abc").unwrap(),
    firstname: String::from("Marianne"),
    lastname: String::from("McTestface"),
};

// this batch creates both contacts in one call
let mut batch = Batch::new("https://instance.crm.dynamics.com/");
batch.create(&testy_contact).unwrap();
batch.create(&marianne_contact).unwrap();

client.execute(&batch).unwrap();

#[derive(Serialize)]
struct Contact {
    contactid: Uuid,
    firstname: String,
    lastname: String,
}

impl WriteEntity for Contact {}

impl Reference for Contact {
    fn get_reference(&self) -> ReferenceStruct {
        ReferenceStruct::new(
            "contacts",
            self.contactid,
        )
    }
}

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more

Instruments this type with the current Span, returning an Instrumented wrapper. Read more

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more