The relationship between queries and their responses is confusing when developing plugins, since we don't directly map queries to query responses in the structure.
A data query request has multiple queries:
// QueryDataRequest
message QueryDataRequest {
// Plugin Configuration
PluginConfig config = 1;
//Info about the user who calls the plugin.
User user = 2;
// Environment info
map<string,string> headers = 3;
// List of data queries
repeated DataQuery queries = 4;
}
However, a response groups all the queries in a slice of frames (where the bytes of frames is really a repeated frame
, but encoded at a different layer):
message QueryDataResponse {
// Arrow encoded DataFrames
// Each frame encodes its own: Errors, meta, and refId
repeated bytes frames = 1;
// Additional response metadata
map<string,string> metadata = 2;
}
While the frames can be tied to the response by their RefId property, this structure seems to lead to some awkward situations:
- The
QueryData
endpoint in the normal case handles multiple queries. If some of those queries fail, one still wants to return the queries that did work. This can be worked around by adding an empty frame with only RefId, Meta, and Error/Warning info, but this not intuitive. This case stands out as being strange in particular when you consider a query error that has been detected before it is even sent to whatever service the plugin talks to.
- One of the most common results of a single Query is to have multiple frames as the result of that query. For example, a query might return a bunch of time series that don't share the same time index, and the way to represent this is with []Frame (So a response ends up like
[]{ Frame.Refid = A, Frame.Refid = A, Frame.RefId = B, Frame.RefId = B, Frame.RefId = B }
). However, within a Frame we have QueryResultMeta. When you have multiple frames, this gets confusing - what frame(s) should you attach the QueryResultMeta to? One of them, all of them, ( some of them ;-) ) or add an extra frame?
I also noticed when writing a plugin, the removing of the query encapsulation the came in on the query in the response is confusing to me, because the query->queryResponse mapping doesn't exist in the Response structure, only in the request. So I believe this relationship change from the request to response within the QueryData method is too confusing.
I think it might be less confusing if a QueryDataResponse
where is a collection of QueryResponses
and each QueryResponse has []Frame
. Frames still can have metadata particular to the frame, and the QueryResponses, which can contain []Frame, have a metadata for information related to the query.
So in summary:
A request contains multiple query objects. I think a response should also contain multiple queryResponse objects, so there is a one-to-one mapping (symmetry) from query to response within the call.
Also of note is that this basically maps to the way plugin query/responses were before (a map of refId -> response), and I think it was better - so this might be taken as a regression.