Skip to content

Commit 3c7c8c2

Browse files
lrlnagoto-bus-stop
andauthored
docs(parser): example of modifying queries with parser + encoder (#346)
Co-authored-by: Renée Kooi <[email protected]>
1 parent 1651b6f commit 3c7c8c2

File tree

3 files changed

+123
-1
lines changed

3 files changed

+123
-1
lines changed

crates/apollo-encoder/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ categories = [
2020
edition = "2021"
2121

2222
[dependencies]
23-
apollo-parser = { version = "0.3.0", optional = true }
23+
apollo-parser = { path = "../apollo-parser", version = "0.3.0", optional = true }
2424
thiserror = "1.0.37"
2525

2626
[features]

crates/apollo-parser/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ rowan = "0.15.5"
2121

2222
[dev-dependencies]
2323
miette = { version = "3.2.0", features = ["fancy"] }
24+
apollo-encoder = { path = "../apollo-encoder", version = "0.3.3", features = ["apollo-parser"] }
25+
anyhow = "1.0.66"
2426
thiserror = "1.0.30"
2527
pretty_assertions = "0.7.1"
2628
annotate-snippets = "0.9.1"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
use apollo_parser::{ast, Parser};
2+
3+
use anyhow::Result;
4+
5+
// This example merges the two operation definitions into a single one.
6+
fn merge_queries() -> Result<apollo_encoder::Document> {
7+
let query = r"#
8+
query LaunchSite {
9+
launches {
10+
launches {
11+
id
12+
site
13+
}
14+
}
15+
}
16+
17+
query AstronautInfo {
18+
user
19+
me
20+
}
21+
#";
22+
23+
let parser = Parser::new(query);
24+
let ast = parser.parse();
25+
assert_eq!(ast.errors().len(), 0);
26+
27+
let doc = ast.document();
28+
29+
let mut new_query = apollo_encoder::Document::new();
30+
let mut sel_set = Vec::new();
31+
for def in doc.definitions() {
32+
// We want to combine all of our operations into a single one.
33+
if let ast::Definition::OperationDefinition(op) = def {
34+
let selections: Vec<apollo_encoder::Selection> = op
35+
.selection_set()
36+
.unwrap()
37+
.selections()
38+
.map(|sel| sel.try_into())
39+
.collect::<Result<Vec<apollo_encoder::Selection>, _>>()?;
40+
sel_set.extend(selections)
41+
}
42+
}
43+
44+
let op_def = apollo_encoder::OperationDefinition::new(
45+
apollo_encoder::OperationType::Query,
46+
apollo_encoder::SelectionSet::with_selections(sel_set),
47+
);
48+
new_query.operation(op_def);
49+
50+
Ok(new_query)
51+
}
52+
53+
// This example only includes fields without the `@omitted` directive.
54+
fn omitted_fields() -> Result<apollo_encoder::Document> {
55+
let query = r"#
56+
query Products {
57+
isbn @omitted
58+
title
59+
year @omitted
60+
metadata @omitted
61+
reviews
62+
...details
63+
}
64+
65+
fragment details on ProductDetails {
66+
country
67+
}
68+
69+
#";
70+
71+
let parser = Parser::new(query);
72+
let ast = parser.parse();
73+
assert_eq!(ast.errors().len(), 0);
74+
75+
let doc = ast.document();
76+
77+
let mut new_query = apollo_encoder::Document::new();
78+
for def in doc.definitions() {
79+
if let ast::Definition::OperationDefinition(op) = def {
80+
let mut selection_set = apollo_encoder::SelectionSet::new();
81+
for selection in op.selection_set().unwrap().selections() {
82+
if let ast::Selection::Field(field) = selection {
83+
if let Some(dir) = field.directives() {
84+
let omit = dir
85+
.directives()
86+
.any(|dir| dir.name().unwrap().text() == "omitted");
87+
if !omit {
88+
selection_set.selection(apollo_encoder::Selection::Field(
89+
field.clone().try_into()?,
90+
))
91+
}
92+
} else {
93+
selection_set.selection(apollo_encoder::Selection::Field(field.try_into()?))
94+
}
95+
} else {
96+
selection_set.selection(selection.try_into()?)
97+
}
98+
}
99+
let op_def = apollo_encoder::OperationDefinition::new(
100+
op.operation_type().unwrap().try_into()?,
101+
selection_set,
102+
);
103+
new_query.operation(op_def)
104+
} else if let ast::Definition::FragmentDefinition(fragment) = def {
105+
new_query.fragment(fragment.try_into()?);
106+
}
107+
}
108+
109+
Ok(new_query)
110+
}
111+
112+
fn main() -> Result<()> {
113+
let merged = merge_queries()?;
114+
println!("{}", merged);
115+
116+
let omitted_fields = omitted_fields()?;
117+
println!("{}", omitted_fields);
118+
119+
Ok(())
120+
}

0 commit comments

Comments
 (0)