Accessing the backend from the query editor

I had a version 6.x plugin that I am trying to convert to 7.1. I’m doing a clean rewrite, avoiding using any Legacy components. I have two main questions:

Accessing the backend from query editor

There is a go backend that does a few different things depend on the queryType string you send it.

My data source is basically a tree with different kinds of nodes in it. Many of the leaves of the trees are “Trends” - essentially time-series data streams. I wrote a dynamic, progressive query editor that lets you click your way through the tree. To get its data (without loading the tree up front) the query editor makes a query with queryType=“findChildren” and a starting node.

On the typescript side, my datasource extends DataSourceWithBackend, which is very helpful. It eliminates a lot of boilerplate doing that. But it causes a problem. It makes it so that I can’t easily call the datasource directly from the query editor. Well, I sort of can, but it’s really messy. The reason is that DataQueryRequest require a lot of fields that don’t really make sense for a non-time-based instantaneous query.

const datasource: AlcDatasource = this.props.datasource;
    app: "",
    dashboardId: 0,
    interval: "",
    panelId: 0,
    range: {
        from: dateTime(),
        to: dateTime(),
        raw: { from: "", to: ""}},
    requestId: "",
    scopedVars: {},
    startTime: 0,
    targets: [
            queryType: "findChildren",
            refId: "A",
            alias: "",
            metric: "/Trees/geographic",
            absolute: false
    timezone: ""

For what I’m doing, I really don’t need an app, dashboardId, panelId, time range, startTime, … a lot of that stuff. Whats more, I’m not even sure what some of these fields do - the documentation doesn’t have a description, and the object received by the datasource on the backend (go) side doesn’t have any of these fields.

The question really is: how can a Query Editor call datasource.query() and have it be a little bit cleaner? This seems too hard, and I don’t want to force it. I’m wondering if I need to take the approach that the zabbix driver does, and use an http.ServeMux to make adhoc requests. I’d prefer to not do that - having my requests formulated like real metric fetches is helpful (the data from these specialized queries comes back in a Frame just like everything else).

Different Query Types in a Single Datasource

My second question is: I have several different queryTypes

  • presentValue - returns “live” data
  • trendRequest - returns time series data
  • cacheStats - returns a bunch of data about my backend’s performance
  • findChildren - used by the navigation component described above

All four of those had their own query types in the previous driver, but now there’s only one query() method and everything conforms to a single query interface. That’s not really the way it is, though … each one of those query types has its own request format. When I was doing query parsing myself (version 6.x) I would just look at queryType and decode jsonData based on the query type. Now, a datasource is more or less expected to have a single query format. What’s the best way to deal with this? Subclass it? Or is this really a problem and I shoudn’t be doing it at all?