Trait grafana_plugin_sdk::backend::DataService [−][src]
pub trait DataService {
type QueryError: DataQueryError;
type Iter: Iterator<Item = Result<DataResponse, Self::QueryError>>;
fn query_data<'life0, 'async_trait>(
&'life0 self,
request: QueryDataRequest
) -> Pin<Box<dyn Future<Output = Self::Iter> + Send + 'async_trait>>
where
'life0: 'async_trait,
Self: 'async_trait;
}Expand description
Used to respond for requests for data from datasources and app plugins.
Datasource plugins will usually want to implement this trait to perform the bulk of their processing.
Example
use grafana_plugin_sdk::{backend, data, prelude::*};
use thiserror::Error;
struct MyPlugin;
/// An error that may occur during a query.
///
/// This must store the `ref_id` of the query so that Grafana can line it up.
#[derive(Debug, Error)]
#[error("Error querying backend for query {ref_id}: {source}")]
struct QueryError {
source: data::Error,
ref_id: String,
}
impl backend::DataQueryError for QueryError {
fn ref_id(self) -> String {
self.ref_id
}
}
#[backend::async_trait]
impl backend::DataService for MyPlugin {
/// The type of error that could be returned by an individual query.
type QueryError = QueryError;
/// The type of iterator we're returning.
///
/// In general the concrete type will be impossible to name in advance,
/// so the `backend::BoxDataResponseIter` type alias will be useful.
type Iter = backend::BoxDataResponseIter<Self::QueryError>;
/// Respond to a request for data from Grafana.
///
/// This request will contain zero or more queries, as well as information
/// about the datasource instance on behalf of which this request is made,
/// such as address, credentials, etc.
///
/// Our plugin must respond to each query and return an iterator of `DataResponse`s,
/// which themselves can contain zero or more `Frame`s.
async fn query_data(&self, request: backend::QueryDataRequest) -> Self::Iter {
Box::new(
request.queries.into_iter().map(|x| {
Ok(backend::DataResponse::new(
// Include the ID of the query in the response.
x.ref_id.clone(),
// Return zero or more frames.
// A real implementation would fetch this data from a database
// or something.
vec![
[
[1_u32, 2, 3].into_field("x"),
["a", "b", "c"].into_field("y"),
]
.into_frame("foo")
.check()
.map_err(|source| QueryError {
ref_id: x.ref_id,
source,
})?,
],
))
})
)
}
}Associated Types
The error type that can be returned by individual queries.
This must implement DataQueryError, which allows the SDK to
align queries up with any failed requests.
type Iter: Iterator<Item = Result<DataResponse, Self::QueryError>>
type Iter: Iterator<Item = Result<DataResponse, Self::QueryError>>
The type of iterator returned by the query_data method.
This will generally be impossible to name directly, so returning the
BoxDataResponseIter type alias will probably be more convenient.
Required methods
fn query_data<'life0, 'async_trait>(
&'life0 self,
request: QueryDataRequest
) -> Pin<Box<dyn Future<Output = Self::Iter> + Send + 'async_trait>> where
'life0: 'async_trait,
Self: 'async_trait,
fn query_data<'life0, 'async_trait>(
&'life0 self,
request: QueryDataRequest
) -> Pin<Box<dyn Future<Output = Self::Iter> + Send + 'async_trait>> where
'life0: 'async_trait,
Self: 'async_trait,
Query data for an input request.
The request will contain zero or more queries, as well as information about the
origin of the queries (such as the datasource instance) in the plugin_context field.
