Skip to content

Commit 953d83c

Browse files
Merge pull request #932 from jmartisk/main-issue-871
Fragment support for dynamic clients
2 parents 8002b2e + a9373ab commit 953d83c

32 files changed

Lines changed: 644 additions & 35 deletions

client/api/src/main/java/io/smallrye/graphql/client/core/Document.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public interface Document extends Buildable {
1010
/*
1111
* Static factory methods
1212
*/
13-
static Document document(Operation... operations) {
13+
static Document document(FragmentOrOperation... operations) {
1414
Document document = getNewInstanceOf(Document.class);
1515

1616
document.setOperations(asList(operations));
@@ -21,7 +21,7 @@ static Document document(Operation... operations) {
2121
/*
2222
* Getter/Setter
2323
*/
24-
List<Operation> getOperations();
24+
List<FragmentOrOperation> getOperations();
2525

26-
void setOperations(List<Operation> operations);
26+
void setOperations(List<FragmentOrOperation> operations);
2727
}

client/api/src/main/java/io/smallrye/graphql/client/core/Field.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import java.util.List;
88

9-
public interface Field extends Buildable {
9+
public interface Field extends FieldOrFragment {
1010
/*
1111
* Static factory methods
1212
*/
@@ -26,7 +26,7 @@ static Field field(String name) {
2626
}
2727

2828
// (name, subfields)
29-
static Field field(String name, Field... fields) {
29+
static Field field(String name, FieldOrFragment... fields) {
3030
Field field = getNewInstanceOf(Field.class);
3131

3232
field.setName(name);
@@ -69,7 +69,7 @@ static Field field(String name, List<Argument> args, Field... fields) {
6969

7070
void setArguments(List<Argument> arguments);
7171

72-
List<Field> getFields();
72+
List<FieldOrFragment> getFields();
7373

74-
void setFields(List<Field> fields);
74+
void setFields(List<FieldOrFragment> fields);
7575
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.smallrye.graphql.client.core;
2+
3+
/**
4+
* Represents one of these nodes in a GraphQL document:
5+
* - regular field (name), for example "color"
6+
* - reference to a named fragment, for example "...comparisonFields"
7+
* - an inline fragment, for example ("... on Person { name } ")
8+
*/
9+
public interface FieldOrFragment extends Buildable {
10+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package io.smallrye.graphql.client.core;
2+
3+
import static io.smallrye.graphql.client.core.utils.ServiceUtils.getNewInstanceOf;
4+
import static java.util.Arrays.asList;
5+
6+
import java.util.List;
7+
8+
/**
9+
* Represents a named fragment definition in a GraphQL document. Such definition consists of a name,
10+
* target type, and a set of fields.
11+
*/
12+
public interface Fragment extends FragmentOrOperation {
13+
/*
14+
* Static factory methods
15+
*/
16+
static List<Fragment> fragments(Fragment... fragments) {
17+
return asList(fragments);
18+
}
19+
20+
static FragmentBuilder fragment(String name) {
21+
return new FragmentBuilder(name);
22+
}
23+
24+
/*
25+
* Getter/Setter
26+
*/
27+
String getName();
28+
29+
void setName(String name);
30+
31+
String getTargetType();
32+
33+
void setTargetType(String name);
34+
35+
List<FieldOrFragment> getFields();
36+
37+
void setFields(List<FieldOrFragment> fields);
38+
39+
class FragmentBuilder {
40+
41+
private String name;
42+
43+
private String targetType;
44+
45+
private List<FieldOrFragment> fields;
46+
47+
FragmentBuilder(String name) {
48+
this.name = name;
49+
}
50+
51+
public Fragment on(String targetType, FieldOrFragment... fields) {
52+
this.targetType = targetType;
53+
this.fields = asList(fields);
54+
return build();
55+
}
56+
57+
Fragment build() {
58+
Fragment fragment = getNewInstanceOf(Fragment.class);
59+
fragment.setName(name);
60+
fragment.setTargetType(targetType);
61+
fragment.setFields(fields);
62+
return fragment;
63+
}
64+
}
65+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package io.smallrye.graphql.client.core;
2+
3+
/**
4+
* Represents a node in a GraphQL document that can contain either an operation (query/mutation/subscription),
5+
* or a definition of a named fragment. On the top level, a GraphQL document basically consists of a list
6+
* of these nodes.
7+
*/
8+
public interface FragmentOrOperation extends Buildable {
9+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package io.smallrye.graphql.client.core;
2+
3+
import static io.smallrye.graphql.client.core.utils.ServiceUtils.getNewInstanceOf;
4+
5+
/**
6+
* Represents a reference to a named fragment.
7+
*/
8+
public interface FragmentReference extends FieldOrFragment {
9+
10+
/**
11+
* Create a fragment reference by specifying the name of the target fragment.
12+
* In the resulting document, this will appear as `...FRAGMENTNAME`
13+
*/
14+
static FragmentReference fragmentRef(String name) {
15+
FragmentReference ref = getNewInstanceOf(FragmentReference.class);
16+
ref.setName(name);
17+
return ref;
18+
}
19+
20+
/**
21+
* Create a fragment reference by providing a built instance of a named fragment.
22+
* This will actually only use the name of the fragment - in the resulting document,
23+
* this will appear as `...FRAGMENTNAME`
24+
*/
25+
static FragmentReference fragmentRef(Fragment fragment) {
26+
FragmentReference ref = getNewInstanceOf(FragmentReference.class);
27+
ref.setName(fragment.getName());
28+
return ref;
29+
}
30+
31+
String getName();
32+
33+
void setName(String name);
34+
35+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.smallrye.graphql.client.core;
2+
3+
import static io.smallrye.graphql.client.core.utils.ServiceUtils.getNewInstanceOf;
4+
import static java.util.Arrays.asList;
5+
6+
import java.util.List;
7+
8+
/**
9+
* Represents an inline fragment in a GraphQL document. This can be used
10+
* anywhere where a field is expected (thus it implements `FieldOrFragment`).
11+
*/
12+
public interface InlineFragment extends FieldOrFragment {
13+
14+
static InlineFragment on(String type, FieldOrFragment... fields) {
15+
InlineFragment fragment = getNewInstanceOf(InlineFragment.class);
16+
17+
fragment.setType(type);
18+
fragment.setFields(asList(fields));
19+
20+
return fragment;
21+
}
22+
23+
String getType();
24+
25+
void setType(String name);
26+
27+
List<FieldOrFragment> getFields();
28+
29+
void setFields(List<FieldOrFragment> fields);
30+
31+
}

client/api/src/main/java/io/smallrye/graphql/client/core/Operation.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import java.util.List;
99

10-
public interface Operation extends Buildable {
10+
public interface Operation extends FragmentOrOperation {
1111
/*
1212
* Helpers
1313
*/
@@ -16,7 +16,7 @@ static List<Operation> operations(Operation... operations) {
1616
}
1717

1818
// (fields)
19-
static Operation operation(Field... fields) {
19+
static Operation operation(FieldOrFragment... fields) {
2020
Operation operation = getNewInstanceOf(Operation.class);
2121

2222
operation.setType(QUERY);
@@ -28,7 +28,7 @@ static Operation operation(Field... fields) {
2828
}
2929

3030
// (vars, fields)
31-
static Operation operation(List<Variable> vars, Field... fields) {
31+
static Operation operation(List<Variable> vars, FieldOrFragment... fields) {
3232
Operation operation = getNewInstanceOf(Operation.class);
3333

3434
operation.setType(QUERY);
@@ -40,7 +40,7 @@ static Operation operation(List<Variable> vars, Field... fields) {
4040
}
4141

4242
// (type, fields)
43-
static Operation operation(OperationType type, Field... fields) {
43+
static Operation operation(OperationType type, FieldOrFragment... fields) {
4444
Operation operation = getNewInstanceOf(Operation.class);
4545

4646
operation.setType(type);
@@ -52,7 +52,7 @@ static Operation operation(OperationType type, Field... fields) {
5252
}
5353

5454
// (type, vars, fields)
55-
static Operation operation(OperationType type, List<Variable> vars, Field... fields) {
55+
static Operation operation(OperationType type, List<Variable> vars, FieldOrFragment... fields) {
5656
Operation operation = getNewInstanceOf(Operation.class);
5757

5858
operation.setType(type);
@@ -64,7 +64,7 @@ static Operation operation(OperationType type, List<Variable> vars, Field... fie
6464
}
6565

6666
// (name, fields)
67-
static Operation operation(String name, Field... fields) {
67+
static Operation operation(String name, FieldOrFragment... fields) {
6868
Operation operation = getNewInstanceOf(Operation.class);
6969

7070
operation.setType(QUERY);
@@ -76,7 +76,7 @@ static Operation operation(String name, Field... fields) {
7676
}
7777

7878
// (type, name, fields)
79-
static Operation operation(OperationType type, String name, Field... fields) {
79+
static Operation operation(OperationType type, String name, FieldOrFragment... fields) {
8080
Operation operation = getNewInstanceOf(Operation.class);
8181

8282
operation.setType(type);
@@ -88,7 +88,7 @@ static Operation operation(OperationType type, String name, Field... fields) {
8888
}
8989

9090
// (name, vars, fields)
91-
static Operation operation(String name, List<Variable> vars, Field... fields) {
91+
static Operation operation(String name, List<Variable> vars, FieldOrFragment... fields) {
9292
Operation operation = getNewInstanceOf(Operation.class);
9393

9494
operation.setType(QUERY);
@@ -100,7 +100,7 @@ static Operation operation(String name, List<Variable> vars, Field... fields) {
100100
}
101101

102102
// (type, name, vars, fields)
103-
static Operation operation(OperationType type, String name, List<Variable> vars, Field... fields) {
103+
static Operation operation(OperationType type, String name, List<Variable> vars, FieldOrFragment... fields) {
104104
Operation operation = getNewInstanceOf(Operation.class);
105105

106106
operation.setType(type);
@@ -126,7 +126,7 @@ static Operation operation(OperationType type, String name, List<Variable> vars,
126126

127127
void setVariables(List<Variable> vars);
128128

129-
List<Field> getFields();
129+
List<FieldOrFragment> getFields();
130130

131-
void setFields(List<Field> fields);
131+
void setFields(List<FieldOrFragment> fields);
132132
}

client/implementation/src/main/java/io/smallrye/graphql/client/dynamic/core/AbstractDocument.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@
33
import java.util.List;
44

55
import io.smallrye.graphql.client.core.Document;
6-
import io.smallrye.graphql.client.core.Operation;
6+
import io.smallrye.graphql.client.core.FragmentOrOperation;
77

88
public abstract class AbstractDocument implements Document {
9-
private List<Operation> operations;
9+
private List<FragmentOrOperation> operations;
1010

1111
public AbstractDocument() {
1212
}
1313

14-
public List<Operation> getOperations() {
14+
public List<FragmentOrOperation> getOperations() {
1515
return operations;
1616
}
1717

18-
public void setOperations(List<Operation> operations) {
18+
public void setOperations(List<FragmentOrOperation> operations) {
1919
this.operations = operations;
2020
}
2121
}

client/implementation/src/main/java/io/smallrye/graphql/client/dynamic/core/AbstractField.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44

55
import io.smallrye.graphql.client.core.Argument;
66
import io.smallrye.graphql.client.core.Field;
7+
import io.smallrye.graphql.client.core.FieldOrFragment;
78

89
public abstract class AbstractField implements Field {
910
private String name;
1011
private List<Argument> arguments;
11-
private List<Field> fields;
12+
private List<FieldOrFragment> fields;
1213

1314
public AbstractField() {
1415
}
@@ -29,11 +30,11 @@ public void setArguments(List<Argument> arguments) {
2930
this.arguments = arguments;
3031
}
3132

32-
public List<Field> getFields() {
33+
public List<FieldOrFragment> getFields() {
3334
return fields;
3435
}
3536

36-
public void setFields(List<Field> fields) {
37+
public void setFields(List<FieldOrFragment> fields) {
3738
this.fields = fields;
3839
}
3940
}

0 commit comments

Comments
 (0)