1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#![allow(missing_docs)] // FIXME
use std::sync::Arc;
use serde_json_bytes::Value;
use static_assertions::assert_impl_all;
use tokio::sync::mpsc;
use tower::BoxError;
use crate::Context;
use crate::graphql;
pub(crate) mod service;
pub type BoxService = tower::util::BoxService<Request, Response, BoxError>;
pub type BoxCloneService = tower::util::BoxCloneService<Request, Response, BoxError>;
pub type ServiceResult = Result<Response, BoxError>;
// Reachable from Request
use crate::plugins::subscription::SubscriptionTaskParams;
pub use crate::query_planner::QueryPlan;
assert_impl_all!(Request: Send);
#[non_exhaustive]
pub struct Request {
/// Original request to the Router.
pub supergraph_request: http::Request<graphql::Request>,
pub query_plan: Arc<QueryPlan>,
pub context: Context,
/// Initial data coming from subscription event if it's a subscription
pub(crate) source_stream_value: Option<Value>,
/// Channel to send all parameters needed for the subscription
pub(crate) subscription_tx: Option<mpsc::Sender<SubscriptionTaskParams>>,
}
#[buildstructor::buildstructor]
impl Request {
/// This is the constructor (or builder) to use when constructing a real ExecutionRequest.
///
/// The parameters are not optional, because in a live situation all of these properties must be
/// set and be correct to create a ExecutionRequest.
#[builder(visibility = "pub")]
fn new(
supergraph_request: http::Request<graphql::Request>,
query_plan: Arc<QueryPlan>,
context: Context,
source_stream_value: Option<Value>,
subscription_tx: Option<mpsc::Sender<SubscriptionTaskParams>>,
) -> Request {
Self {
supergraph_request,
query_plan,
context,
source_stream_value,
subscription_tx,
}
}
#[builder(visibility = "pub(crate)")]
#[allow(clippy::needless_lifetimes)] // needed by buildstructor-generated code
async fn internal_new(
supergraph_request: http::Request<graphql::Request>,
query_plan: Arc<QueryPlan>,
context: Context,
source_stream_value: Option<Value>,
subscription_tx: Option<mpsc::Sender<SubscriptionTaskParams>>,
) -> Request {
Self {
supergraph_request,
query_plan,
context,
source_stream_value,
subscription_tx,
}
}
/// This is the constructor (or builder) to use when constructing a "fake" ExecutionRequest.
///
/// This does not enforce the provision of the data that is required for a fully functional
/// ExecutionRequest. It's usually enough for testing, when a fully constructed ExecutionRequest is
/// difficult to construct and not required for the purposes of the test.
///
/// # Example
/// ```
/// use apollo_router::services::execution;
/// use apollo_router::Context;
///
/// // This builder must remain usable from external crates for plugin testing.
/// let request = execution::Request::fake_builder()
/// .context(Context::default())
/// .build();
/// ```
// WARN: make sure to keep the example in the doc test; it gets compiled as an external crate,
// which is very useful in determining whether the public API has changed. In particular, we
// had an issue with SubscriptionTaskParams going from pub to pub(crate), preventing folks from
// compiling their unit tests for plugins because of the visibility change for the fake_builder
#[builder(visibility = "pub")]
fn fake_new(
supergraph_request: Option<http::Request<graphql::Request>>,
query_plan: Option<QueryPlan>,
context: Option<Context>,
source_stream_value: Option<Value>,
subscription_tx: Option<mpsc::Sender<SubscriptionTaskParams>>,
) -> Request {
Request::new(
supergraph_request.unwrap_or_default(),
Arc::new(query_plan.unwrap_or_else(|| QueryPlan::fake_builder().build())),
context.unwrap_or_default(),
source_stream_value,
subscription_tx,
)
}
}
/// The response type for execution services is the same as for supergraph services.
pub type Response = super::supergraph::Response;