Expand description
Client for connecting to a BonsaiDb server.
Connecting via QUIC
The URL scheme to connect via QUIC is bonsaidb
. If no port is specified,
port 5645 is assumed.
With a valid TLS certificate
let client = Client::build(Url::parse("bonsaidb://my-server.com")?)
.finish()
.await?;
With a Self-Signed Pinned Certificate
When using install_self_signed_certificate()
, clients will need the
contents of the pinned-certificate.der
file within the database. It can be
specified when building the client:
let certificate =
Certificate::from_der(std::fs::read("mydb.bonsaidb/pinned-certificate.der")?)?;
let client = Client::build(Url::parse("bonsaidb://localhost")?)
.with_certificate(certificate)
.finish()
.await?;
Connecting via WebSockets
WebSockets are built atop the HTTP protocol. There are two URL schemes for WebSockets:
ws
: Insecure WebSockets. Port 80 is assumed if no port is specified.wss
: Secure WebSockets. Port 443 is assumed if no port is specified.
Without TLS
let client = Client::build(Url::parse("ws://localhost")?)
.finish()
.await?;
With TLS
let client = Client::build(Url::parse("wss://my-server.com")?)
.finish()
.await?;
Using a CustomApi
Our user guide has a section on creating and using a CustomApi.
// `bonsaidb_core` is re-exported to `bonsaidb::core` or `bonsaidb_client::core`.
use bonsaidb_core::custom_api::{CustomApi, Infallible};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
pub enum Request {
Ping,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum Response {
Pong,
}
#[derive(Debug)]
pub enum MyApi {}
impl CustomApi for MyApi {
type Request = Request;
type Response = Response;
type Error = Infallible;
}
let client = Client::build(Url::parse("bonsaidb://localhost")?)
.with_custom_api::<MyApi>()
.finish()
.await?;
let Response::Pong = client.send_api_request(Request::Ping).await?;
Receiving out-of-band messages from the server
If the server sends a message that isn’t in response to a request, the client will invoke it’s custom api callback:
let client = Client::build(Url::parse("bonsaidb://localhost")?)
.with_custom_api_callback::<MyApi, _>(|result: Result<Response, Infallible>| {
let Response::Pong = result.unwrap();
})
.finish()
.await?;
Implementations
sourceimpl<A> Client<A> where
A: CustomApi,
impl<A> Client<A> where
A: CustomApi,
sourcepub async fn new(url: Url) -> Result<Client<A>, Error<<A as CustomApi>::Error>>
pub async fn new(url: Url) -> Result<Client<A>, Error<<A as CustomApi>::Error>>
Initialize a client connecting to url
. This client can be shared by
cloning it. All requests are done asynchronously over the same
connection.
If the client has an error connecting, the first request made will
present that error. If the client disconnects while processing requests,
all requests being processed will exit and return
Error::Disconnected
. The client will automatically try reconnecting.
The goal of this design of this reconnection strategy is to make it easier to build resilliant apps. By allowing existing Client instances to recover and reconnect, each component of the apps built can adopt a “retry-to-recover” design, or “abort-and-fail” depending on how critical the database is to operation.
sourcepub async fn send_api_request(
&'_ self,
request: <A as CustomApi>::Request
) -> Result<<A as CustomApi>::Response, Error<<A as CustomApi>::Error>>
pub async fn send_api_request(
&'_ self,
request: <A as CustomApi>::Request
) -> Result<<A as CustomApi>::Response, Error<<A as CustomApi>::Error>>
Sends an api request
.
sourcepub async fn effective_permissions(&'_ self) -> Option<Permissions>
pub async fn effective_permissions(&'_ self) -> Option<Permissions>
Returns the current effective permissions for the client. Returns None if unauthenticated.
Trait Implementations
sourceimpl<A> StorageConnection for Client<A> where
A: CustomApi,
impl<A> StorageConnection for Client<A> where
A: CustomApi,
type Database = RemoteDatabase<A>
type Database = RemoteDatabase<A>
The type that represents a database for this implementation.
sourcefn create_database_with_schema<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
schema: SchemaName,
only_if_needed: bool
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'life0: 'async_trait,
'life1: 'async_trait,
Client<A>: 'async_trait,
fn create_database_with_schema<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
schema: SchemaName,
only_if_needed: bool
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'life0: 'async_trait,
'life1: 'async_trait,
Client<A>: 'async_trait,
Creates a database named name
using the SchemaName
schema
. Read more
sourcefn database<'life0, 'life1, 'async_trait, DB>(
&'life0 self,
name: &'life1 str
) -> Pin<Box<dyn Future<Output = Result<<Client<A> as StorageConnection>::Database, Error>> + Send + 'async_trait, Global>> where
'life0: 'async_trait,
'life1: 'async_trait,
DB: Schema + 'async_trait,
Client<A>: 'async_trait,
fn database<'life0, 'life1, 'async_trait, DB>(
&'life0 self,
name: &'life1 str
) -> Pin<Box<dyn Future<Output = Result<<Client<A> as StorageConnection>::Database, Error>> + Send + 'async_trait, Global>> where
'life0: 'async_trait,
'life1: 'async_trait,
DB: Schema + 'async_trait,
Client<A>: 'async_trait,
Returns a reference to database name
with schema DB
.
sourcefn delete_database<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'life0: 'async_trait,
'life1: 'async_trait,
Client<A>: 'async_trait,
fn delete_database<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'life0: 'async_trait,
'life1: 'async_trait,
Client<A>: 'async_trait,
Deletes a database named name
. Read more
sourcefn list_databases<'life0, 'async_trait>(
&'life0 self
) -> Pin<Box<dyn Future<Output = Result<Vec<Database, Global>, Error>> + Send + 'async_trait, Global>> where
'life0: 'async_trait,
Client<A>: 'async_trait,
fn list_databases<'life0, 'async_trait>(
&'life0 self
) -> Pin<Box<dyn Future<Output = Result<Vec<Database, Global>, Error>> + Send + 'async_trait, Global>> where
'life0: 'async_trait,
Client<A>: 'async_trait,
Lists the databases in this storage.
sourcefn list_available_schemas<'life0, 'async_trait>(
&'life0 self
) -> Pin<Box<dyn Future<Output = Result<Vec<SchemaName, Global>, Error>> + Send + 'async_trait, Global>> where
'life0: 'async_trait,
Client<A>: 'async_trait,
fn list_available_schemas<'life0, 'async_trait>(
&'life0 self
) -> Pin<Box<dyn Future<Output = Result<Vec<SchemaName, Global>, Error>> + Send + 'async_trait, Global>> where
'life0: 'async_trait,
Client<A>: 'async_trait,
Lists the SchemaName
s registered with this storage.
sourcefn create_user<'life0, 'life1, 'async_trait>(
&'life0 self,
username: &'life1 str
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait, Global>> where
'life0: 'async_trait,
'life1: 'async_trait,
Client<A>: 'async_trait,
fn create_user<'life0, 'life1, 'async_trait>(
&'life0 self,
username: &'life1 str
) -> Pin<Box<dyn Future<Output = Result<u64, Error>> + Send + 'async_trait, Global>> where
'life0: 'async_trait,
'life1: 'async_trait,
Client<A>: 'async_trait,
Creates a user.
sourcefn delete_user<'user, 'life0, 'async_trait, U>(
&'life0 self,
user: U
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'user: 'async_trait,
'life0: 'async_trait,
U: Nameable<'user, u64> + Send + Sync + 'async_trait,
Client<A>: 'async_trait,
fn delete_user<'user, 'life0, 'async_trait, U>(
&'life0 self,
user: U
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'user: 'async_trait,
'life0: 'async_trait,
U: Nameable<'user, u64> + Send + Sync + 'async_trait,
Client<A>: 'async_trait,
Deletes a user.
sourcefn set_user_password<'user, 'life0, 'async_trait, U>(
&'life0 self,
user: U,
password: SensitiveString
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'user: 'async_trait,
'life0: 'async_trait,
U: Nameable<'user, u64> + Send + Sync + 'async_trait,
Client<A>: 'async_trait,
fn set_user_password<'user, 'life0, 'async_trait, U>(
&'life0 self,
user: U,
password: SensitiveString
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'user: 'async_trait,
'life0: 'async_trait,
U: Nameable<'user, u64> + Send + Sync + 'async_trait,
Client<A>: 'async_trait,
Sets a user’s password.
sourcefn authenticate<'user, 'life0, 'async_trait, U>(
&'life0 self,
user: U,
authentication: Authentication
) -> Pin<Box<dyn Future<Output = Result<Authenticated, Error>> + Send + 'async_trait, Global>> where
'user: 'async_trait,
'life0: 'async_trait,
U: Nameable<'user, u64> + Send + Sync + 'async_trait,
Client<A>: 'async_trait,
fn authenticate<'user, 'life0, 'async_trait, U>(
&'life0 self,
user: U,
authentication: Authentication
) -> Pin<Box<dyn Future<Output = Result<Authenticated, Error>> + Send + 'async_trait, Global>> where
'user: 'async_trait,
'life0: 'async_trait,
U: Nameable<'user, u64> + Send + Sync + 'async_trait,
Client<A>: 'async_trait,
Authenticates as a user with a authentication method.
sourcefn add_permission_group_to_user<'user, 'group, 'life0, 'async_trait, U, G>(
&'life0 self,
user: U,
permission_group: G
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'user: 'async_trait,
'group: 'async_trait,
'life0: 'async_trait,
U: Nameable<'user, u64> + Send + Sync + 'async_trait,
G: Nameable<'group, u64> + Send + Sync + 'async_trait,
Client<A>: 'async_trait,
fn add_permission_group_to_user<'user, 'group, 'life0, 'async_trait, U, G>(
&'life0 self,
user: U,
permission_group: G
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'user: 'async_trait,
'group: 'async_trait,
'life0: 'async_trait,
U: Nameable<'user, u64> + Send + Sync + 'async_trait,
G: Nameable<'group, u64> + Send + Sync + 'async_trait,
Client<A>: 'async_trait,
Adds a user to a permission group.
sourcefn remove_permission_group_from_user<'user, 'group, 'life0, 'async_trait, U, G>(
&'life0 self,
user: U,
permission_group: G
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'user: 'async_trait,
'group: 'async_trait,
'life0: 'async_trait,
U: Nameable<'user, u64> + Send + Sync + 'async_trait,
G: Nameable<'group, u64> + Send + Sync + 'async_trait,
Client<A>: 'async_trait,
fn remove_permission_group_from_user<'user, 'group, 'life0, 'async_trait, U, G>(
&'life0 self,
user: U,
permission_group: G
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'user: 'async_trait,
'group: 'async_trait,
'life0: 'async_trait,
U: Nameable<'user, u64> + Send + Sync + 'async_trait,
G: Nameable<'group, u64> + Send + Sync + 'async_trait,
Client<A>: 'async_trait,
Removes a user from a permission group.
sourcefn add_role_to_user<'user, 'group, 'life0, 'async_trait, U, G>(
&'life0 self,
user: U,
role: G
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'user: 'async_trait,
'group: 'async_trait,
'life0: 'async_trait,
U: Nameable<'user, u64> + Send + Sync + 'async_trait,
G: Nameable<'group, u64> + Send + Sync + 'async_trait,
Client<A>: 'async_trait,
fn add_role_to_user<'user, 'group, 'life0, 'async_trait, U, G>(
&'life0 self,
user: U,
role: G
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'user: 'async_trait,
'group: 'async_trait,
'life0: 'async_trait,
U: Nameable<'user, u64> + Send + Sync + 'async_trait,
G: Nameable<'group, u64> + Send + Sync + 'async_trait,
Client<A>: 'async_trait,
Adds a user to a permission group.
sourcefn remove_role_from_user<'user, 'group, 'life0, 'async_trait, U, G>(
&'life0 self,
user: U,
role: G
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'user: 'async_trait,
'group: 'async_trait,
'life0: 'async_trait,
U: Nameable<'user, u64> + Send + Sync + 'async_trait,
G: Nameable<'group, u64> + Send + Sync + 'async_trait,
Client<A>: 'async_trait,
fn remove_role_from_user<'user, 'group, 'life0, 'async_trait, U, G>(
&'life0 self,
user: U,
role: G
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'user: 'async_trait,
'group: 'async_trait,
'life0: 'async_trait,
U: Nameable<'user, u64> + Send + Sync + 'async_trait,
G: Nameable<'group, u64> + Send + Sync + 'async_trait,
Client<A>: 'async_trait,
Removes a user from a permission group.
sourcefn create_database<'life0, 'life1, 'async_trait, DB>(
&'life0 self,
name: &'life1 str,
only_if_needed: bool
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'life0: 'async_trait,
'life1: 'async_trait,
DB: Schema + 'async_trait,
Self: 'async_trait,
fn create_database<'life0, 'life1, 'async_trait, DB>(
&'life0 self,
name: &'life1 str,
only_if_needed: bool
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait, Global>> where
'life0: 'async_trait,
'life1: 'async_trait,
DB: Schema + 'async_trait,
Self: 'async_trait,
Creates a database named name
with the Schema
provided. Read more
Auto Trait Implementations
impl<A = ()> !RefUnwindSafe for Client<A>
impl<A> Send for Client<A>
impl<A> Sync for Client<A>
impl<A> Unpin for Client<A>
impl<A = ()> !UnwindSafe for Client<A>
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> Instrument for T
impl<T> Instrument for T
sourcefn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
sourcefn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
impl<T> Pointable for T
impl<T> Pointable for T
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcefn clone_into(&self, target: &mut T)
fn clone_into(&self, target: &mut T)
toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
fn vzip(self) -> V
sourceimpl<T> WithSubscriber for T
impl<T> WithSubscriber for T
sourcefn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> where
S: Into<Dispatch>,
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> where
S: Into<Dispatch>,
Attaches the provided Subscriber
to this type, returning a
WithDispatch
wrapper. Read more
sourcefn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
Attaches the current default Subscriber
to this type, returning a
WithDispatch
wrapper. Read more