add nodes exposure on ConectionType so nesting through edges isn't always needed. (#952)

This commit is contained in:
Edward Rudd 2022-06-16 12:12:07 -04:00 committed by GitHub
parent 359f1ed23b
commit a445606e5a
4 changed files with 89 additions and 8 deletions

View File

@ -137,11 +137,13 @@ async fn test_hello_header() {
async fn test_count() { async fn test_count() {
let srv = test::init_service( let srv = test::init_service(
App::new() App::new()
.app_data(Data::new( .app_data(
Schema::build(CountQueryRoot, CountMutation, EmptySubscription) Data::new(
.data(Count::default()) Schema::build(CountQueryRoot, CountMutation, EmptySubscription)
.finish(), .data(Count::default())
)) .finish(),
),
)
.service( .service(
web::resource("/") web::resource("/")
.guard(guard::Post()) .guard(guard::Post())

View File

@ -83,13 +83,14 @@ where
next: NextSubscribe<'_>, next: NextSubscribe<'_>,
) -> BoxStream<'s, Response> { ) -> BoxStream<'s, Response> {
Box::pin( Box::pin(
next.run(ctx, stream) next.run(ctx, stream).with_context(
.with_context(OpenTelemetryContext::current_with_span( OpenTelemetryContext::current_with_span(
self.tracer self.tracer
.span_builder("subscribe") .span_builder("subscribe")
.with_kind(SpanKind::Server) .with_kind(SpanKind::Server)
.start(&*self.tracer), .start(&*self.tracer),
)), ),
),
) )
} }

View File

@ -117,6 +117,11 @@ where
&self.edges &self.edges
} }
/// A list of nodes.
async fn nodes(&self) -> Vec<&Node> {
self.edges.iter().map(|e| &e.node).collect()
}
#[graphql(flatten)] #[graphql(flatten)]
#[inline] #[inline]
async fn additional_fields(&self) -> &ConnectionFields { async fn additional_fields(&self) -> &ConnectionFields {

View File

@ -94,3 +94,76 @@ pub async fn test_connection_additional_fields() {
}) })
); );
} }
#[tokio::test]
pub async fn test_connection_nodes() {
struct Query;
#[Object]
impl Query {
async fn numbers(
&self,
after: Option<String>,
before: Option<String>,
first: Option<i32>,
last: Option<i32>,
) -> Result<Connection<usize, i32>> {
connection::query(
after,
before,
first,
last,
|after, before, first, last| async move {
let mut start = after.map(|after| after + 1).unwrap_or(0);
let mut end = before.unwrap_or(10000);
if let Some(first) = first {
end = (start + first).min(end);
}
if let Some(last) = last {
start = if last > end - start { end } else { end - last };
}
let mut connection = Connection::new(start > 0, end < 10000);
connection
.edges
.extend((start..end).map(|n| Edge::new(n, n as i32)));
Ok::<_, Error>(connection)
},
)
.await
}
}
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
assert_eq!(
schema
.execute("{ numbers(first: 2) { __typename edges { __typename node } nodes } }")
.await
.data,
value!({
"numbers": {
"__typename": "IntConnection",
"edges": [
{"__typename": "IntEdge", "node": 0},
{"__typename": "IntEdge", "node": 1},
],
"nodes": [
0,
1,
],
},
})
);
assert_eq!(
schema.execute("{ numbers(last: 2) { nodes } }").await.data,
value!({
"numbers": {
"nodes": [
9998,
9999,
],
},
})
);
}