Skip to content

Commit

Permalink
remove explain endpoint in favor of nested endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
Gil Mizrahi committed Feb 2, 2024
1 parent b80867e commit e863cb5
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 65 deletions.
17 changes: 4 additions & 13 deletions ndc-client/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ pub struct LeafCapability {}
#[schemars(title = "Capabilities")]
pub struct Capabilities {
pub query: QueryCapabilities,
pub explain: ExplainCapabilities,
pub mutation: MutationCapabilities,
pub relationships: Option<RelationshipCapabilities>,
}
Expand All @@ -56,28 +55,20 @@ pub struct QueryCapabilities {
pub aggregates: Option<LeafCapability>,
/// Does the connector support queries which use variables
pub variables: Option<LeafCapability>,
/// Does the connector support explaining queries
pub explain: Option<LeafCapability>,
}
// ANCHOR_END: QueryCapabilities

// ANCHOR: ExplainCapabilities
#[skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
#[schemars(title = "Explain Capabilities")]
pub struct ExplainCapabilities {
/// Does the connector support explaining query
pub query: Option<LeafCapability>,
/// Does the connector support explaining mutations
pub mutation: Option<LeafCapability>,
}
// ANCHOR_END: ExplainCapabilities

// ANCHOR: MutationCapabilities
#[skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
#[schemars(title = "Mutation Capabilities")]
pub struct MutationCapabilities {
/// Does the connector support executing multiple mutations in a transaction.
pub transactional: Option<LeafCapability>,
/// Does the connector support explaining mutations
pub explain: Option<LeafCapability>,
}
// ANCHOR_END: MutationCapabilities

Expand Down
42 changes: 16 additions & 26 deletions ndc-client/tests/json_schema/capabilities_response.jsonschema
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,13 @@
"description": "Describes the features of the specification which a data connector implements.",
"type": "object",
"required": [
"explain",
"mutation",
"query"
],
"properties": {
"query": {
"$ref": "#/definitions/QueryCapabilities"
},
"explain": {
"$ref": "#/definitions/ExplainCapabilities"
},
"mutation": {
"$ref": "#/definitions/MutationCapabilities"
},
Expand Down Expand Up @@ -71,19 +67,30 @@
"type": "null"
}
]
},
"explain": {
"description": "Does the connector support explaining queries",
"anyOf": [
{
"$ref": "#/definitions/LeafCapability"
},
{
"type": "null"
}
]
}
}
},
"LeafCapability": {
"description": "A unit value to indicate a particular leaf capability is supported. This is an empty struct to allow for future sub-capabilities.",
"type": "object"
},
"ExplainCapabilities": {
"title": "Explain Capabilities",
"MutationCapabilities": {
"title": "Mutation Capabilities",
"type": "object",
"properties": {
"query": {
"description": "Does the connector support explaining query",
"transactional": {
"description": "Does the connector support executing multiple mutations in a transaction.",
"anyOf": [
{
"$ref": "#/definitions/LeafCapability"
Expand All @@ -93,7 +100,7 @@
}
]
},
"mutation": {
"explain": {
"description": "Does the connector support explaining mutations",
"anyOf": [
{
Expand All @@ -106,23 +113,6 @@
}
}
},
"MutationCapabilities": {
"title": "Mutation Capabilities",
"type": "object",
"properties": {
"transactional": {
"description": "Does the connector support executing multiple mutations in a transaction.",
"anyOf": [
{
"$ref": "#/definitions/LeafCapability"
},
{
"type": "null"
}
]
}
}
},
"RelationshipCapabilities": {
"title": "Relationship Capabilities",
"type": "object",
Expand Down
22 changes: 10 additions & 12 deletions ndc-reference/bin/reference/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ async fn main() {
.route("/capabilities", get(get_capabilities))
.route("/schema", get(get_schema))
.route("/query", post(post_query))
.route("/query/explain", post(post_query_explain))
.route("/mutation", post(post_mutation))
.route("/explain", post(post_explain))
.route("/explain/mutation", post(post_explain_mutation))
.route("/mutation/explain", post(post_mutation_explain))
.layer(axum::middleware::from_fn_with_state(
app_state.clone(),
metrics_middleware,
Expand Down Expand Up @@ -165,16 +165,14 @@ async fn get_capabilities() -> Json<models::CapabilitiesResponse> {
Json(models::CapabilitiesResponse {
version: "0.1.0".into(),
capabilities: models::Capabilities {
explain: models::ExplainCapabilities {
query: None,
mutation: None,
},
query: models::QueryCapabilities {
aggregates: Some(LeafCapability {}),
variables: Some(LeafCapability {}),
explain: None,
},
mutation: models::MutationCapabilities {
transactional: None,
explain: None,
},
relationships: Some(RelationshipCapabilities {
order_by_aggregate: Some(LeafCapability {}),
Expand Down Expand Up @@ -1550,8 +1548,8 @@ fn eval_field(
}
}
// ANCHOR_END: eval_field
// ANCHOR: explain
async fn post_explain(
// ANCHOR: query_explain
async fn post_query_explain(
Json(_request): Json<models::QueryRequest>,
) -> Result<Json<models::ExplainResponse>> {
Err((
Expand All @@ -1562,9 +1560,9 @@ async fn post_explain(
}),
))
}
// ANCHOR_END: explain
// ANCHOR: explain_mutation
async fn post_explain_mutation(
// ANCHOR_END: query_explain
// ANCHOR: mutation_explain
async fn post_mutation_explain(
Json(_request): Json<models::MutationRequest>,
) -> Result<Json<models::ExplainResponse>> {
Err((
Expand All @@ -1575,7 +1573,7 @@ async fn post_explain_mutation(
}),
))
}
// ANCHOR_END: explain_mutation
// ANCHOR_END: mutation_explain
// ANCHOR: post_mutation_signature
async fn post_mutation(
State(state): State<Arc<Mutex<AppState>>>,
Expand Down
1 change: 0 additions & 1 deletion ndc-reference/tests/capabilities/expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"aggregates": {},
"variables": {}
},
"explain": {},
"mutation": {},
"relationships": {
"relation_comparisons": {},
Expand Down
4 changes: 2 additions & 2 deletions specification/src/specification/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ A data connector must implement several web service endpoints:
- A __capabilities__ endpoint, which describes which features the data source is capable of implementing.
- A __schema__ endpoint, which describes the resources provided by the data source, and the shape of the data they contain.
- A __query__ endpoint, which reads data from one of the relations described by the schema endpoint.
- A __query/explain__ endpoint, which explains a query plan, without actually executing it.
- A __mutation__ endpoint, which modifies the data in one of the relations described by the schema endpoint.
- An __explain__ endpoint, which explains a query plan, without actually executing it.
- An __explain/mutation__ endpoint, which explains a mutation plan, without actually executing it.
- A __mutation/explain__ endpoint, which explains a mutation plan, without actually executing it.
- A __metrics__ endpoint, which exposes runtime metrics about the data connector.
6 changes: 3 additions & 3 deletions specification/src/specification/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ See [`CapabilitiesResponse`](../reference/types.md#capabilitiesresponse)
| Name | Description |
|------|-------------|
| `version` | A [semantic version number](https://semver.org) of this specification which the data connector claims to implement |
| `capabilities.explain.query` | Whether the data connector is capable of describing query plans |
| `capabilities.explain.mutation` | Whether the data connector is capable of describing mutation plans |
| `capabilities.mutation.transactional` | Whether the data connector is capable of executing multiple mutations in a transaction |
| `capabilities.query.aggregates` | Whether the data connector supports [aggregate queries](queries/aggregates.md) |
| `capabilities.query.variables` | Whether the data connector supports [queries with variables](queries/variables.md) |
| `capabilities.query.explain` | Whether the data connector is capable of describing query plans |
| `capabilities.mutation.transactional` | Whether the data connector is capable of executing multiple mutations in a transaction |
| `capabilities.mutation.explain` | Whether the data connector is capable of describing mutation plans |
| `capabilities.relationships` | Whether the data connector supports [relationships](queries/relationships.md) |
| `capabilities.relationships.order_by_aggregate` | Whether order by clauses can include aggregates |
| `capabilities.relationships.relation_comparisons` | Whether comparisons can include columns reachable via [relationships](queries/relationships.md) |
Expand Down
8 changes: 4 additions & 4 deletions specification/src/specification/explain.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@

There are two endpoints related to explain:

- The `/explain` endpoint, which accepts a [query](./queries/README.md) request.
- The `/explain/mutation` endpoint, which accepts a [mutation](./mutation/README.md) request.
- The `/query/explain` endpoint, which accepts a [query](./queries/README.md) request.
- The `/mutation/explain` endpoint, which accepts a [mutation](./mutation/README.md) request.

Both endpoints return a representation of the _execution plan_ without actually executing the query or mutation.

## Request

```
POST /explain
POST /query/explain
```

See [`QueryRequest`](../reference/types.md#queryrequest)

## Request

```
POST /explain/mutation
POST /mutation/explain
```

See [`MutationRequest`](../reference/types.md#mutationrequest)
Expand Down
2 changes: 1 addition & 1 deletion specification/src/tutorial/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ The reference implementation returns a static `CapabilitiesResponse`:
{{#include ../../../ndc-reference/bin/reference/main.rs:capabilities}}
```

_Note_: the reference implementation supports all capabilities with the exception of `explain`. This is because all queries are run in memory by naively interpreting the query request - there is no better description of the query plan than the raw query request itself!
_Note_: the reference implementation supports all capabilities with the exception of `query.explain` and `mutation.explain`. This is because all queries are run in memory by naively interpreting the query request - there is no better description of the query plan than the raw query request itself!
7 changes: 4 additions & 3 deletions specification/src/tutorial/explain.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Explain

The `/explain` and `/explain/mutation` endpoints are not implemented in the reference implementation, simply because the `QueryResponse` is interpreted directly in the `/query` endpoint.
The `/query/explain` and `/mutation/explain` endpoints are not implemented in the reference implementation, simply because the `QueryResponse` is interpreted directly in the `/query` endpoint.
There is no intermediate representation (such as SQL) which could be described as a "query plan".

The `explain` capability is turned off in the [capabilities endpoint](./capabilities.md), and the `/explain` endpoint throws an error:
The `query.explain` and `mutation.explain` capabilities are turned off in the [capabilities endpoint](./capabilities.md),
and the `/query/explain` and `/mutation/explain` endpoints throw an error:

```rust,no_run,noplayground
{{#include ../../../ndc-reference/bin/reference/main.rs:explain}}
{{#include ../../../ndc-reference/bin/reference/main.rs:query_explain}}
```

0 comments on commit e863cb5

Please sign in to comment.