Skip to content

Commit 28e1065

Browse files
authored
chore: update compatibility project to use latest Spring integrations (#410)
Update to use Java records and latest [Spring GraphQL integrations](https://docs.spring.io/spring-graphql/reference/federation.html).
1 parent a787bdc commit 28e1065

19 files changed

+256
-430
lines changed

compatibility/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
graphql-java.version = 21.1
1+
graphql-java.version=21.1

compatibility/src/main/java/com/apollographql/federation/compatibility/App.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
@SpringBootApplication
77
public class App {
8-
public static void main(String[] args) {
9-
SpringApplication.run(App.class, args);
10-
}
8+
public static void main(String[] args) {
9+
SpringApplication.run(App.class, args);
10+
}
1111
}
Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.apollographql.federation.compatibility;
22

33
import com.apollographql.federation.compatibility.model.DeprecatedProduct;
4+
import org.springframework.graphql.data.federation.EntityMapping;
45
import org.springframework.graphql.data.method.annotation.Argument;
56
import org.springframework.graphql.data.method.annotation.QueryMapping;
67
import org.springframework.graphql.data.method.annotation.SchemaMapping;
@@ -9,13 +10,14 @@
910
@Controller
1011
public class DeprecatedProductController {
1112

12-
@QueryMapping
13-
public DeprecatedProduct deprecatedProduct(@Argument String sku, @Argument("package") String pkg) {
14-
return DeprecatedProduct.resolveBySkuAndPackage(sku, pkg);
15-
}
13+
@QueryMapping
14+
@EntityMapping
15+
public DeprecatedProduct deprecatedProduct(@Argument String sku, @Argument("package") String pkg) {
16+
return DeprecatedProduct.resolveBySkuAndPackage(sku, pkg);
17+
}
1618

17-
@SchemaMapping(typeName="DeprecatedProduct", field="package")
18-
public String getPackage(DeprecatedProduct product) {
19-
return product.getPkg();
20-
}
19+
@SchemaMapping(typeName = "DeprecatedProduct", field = "package")
20+
public String getPackage(DeprecatedProduct product) {
21+
return product.pkg();
22+
}
2123
}
Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,10 @@
11
package com.apollographql.federation.compatibility;
22

3-
import com.apollographql.federation.compatibility.model.DeprecatedProduct;
4-
import com.apollographql.federation.compatibility.model.Inventory;
5-
import com.apollographql.federation.compatibility.model.Product;
6-
import com.apollographql.federation.compatibility.model.ProductResearch;
7-
import com.apollographql.federation.compatibility.model.User;
8-
import com.apollographql.federation.graphqljava.Federation;
9-
import com.apollographql.federation.graphqljava._Entity;
103
import com.apollographql.federation.graphqljava.tracing.FederatedTracingInstrumentation;
11-
import java.util.List;
12-
import java.util.Map;
13-
import java.util.stream.Collectors;
144
import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer;
155
import org.springframework.context.annotation.Bean;
166
import org.springframework.context.annotation.Configuration;
17-
import org.springframework.graphql.execution.ClassNameTypeResolver;
7+
import org.springframework.graphql.data.federation.FederationSchemaFactory;
188

199
@Configuration
2010
public class GraphQLConfiguration {
@@ -25,24 +15,12 @@ public FederatedTracingInstrumentation federatedTracingInstrumentation() {
2515
}
2616

2717
@Bean
28-
public GraphQlSourceBuilderCustomizer federationTransform() {
29-
return builder -> builder.schemaFactory((registry, wiring) ->
30-
Federation.transform(registry, wiring)
31-
.fetchEntities(env ->
32-
env.<List<Map<String, Object>>>getArgument(_Entity.argumentName).stream().map(reference -> {
33-
final String typeName = (String) reference.get("__typename");
34-
return switch (typeName) {
35-
case "DeprecatedProduct" -> DeprecatedProduct.resolveReference(reference);
36-
case "Product" -> Product.resolveReference(reference);
37-
case "ProductResearch" -> ProductResearch.resolveReference(reference);
38-
case "User" -> User.resolveReference(reference);
39-
case "Inventory" -> Inventory.resolveReference(reference);
40-
default -> null;
41-
};
42-
}).collect(Collectors.toList())
43-
)
44-
.resolveEntityType(new ClassNameTypeResolver())
45-
.build()
46-
);
18+
public GraphQlSourceBuilderCustomizer customizer(FederationSchemaFactory factory) {
19+
return builder -> builder.schemaFactory(factory::createGraphQLSchema);
20+
}
21+
22+
@Bean
23+
FederationSchemaFactory federationSchemaFactory() {
24+
return new FederationSchemaFactory();
4725
}
4826
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.apollographql.federation.compatibility;
2+
3+
import com.apollographql.federation.compatibility.model.Inventory;
4+
import org.springframework.graphql.data.federation.EntityMapping;
5+
import org.springframework.graphql.data.method.annotation.Argument;
6+
import org.springframework.stereotype.Controller;
7+
8+
@Controller
9+
public class InventoryController {
10+
@EntityMapping
11+
public Inventory inventory(@Argument("id") String id) {
12+
return Inventory.resolveById(id);
13+
}
14+
}
Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,42 @@
11
package com.apollographql.federation.compatibility;
22

3-
import com.apollographql.federation.compatibility.model.DeprecatedProduct;
43
import com.apollographql.federation.compatibility.model.Product;
4+
import org.springframework.graphql.data.federation.EntityMapping;
55
import org.springframework.graphql.data.method.annotation.Argument;
66
import org.springframework.graphql.data.method.annotation.QueryMapping;
77
import org.springframework.graphql.data.method.annotation.SchemaMapping;
88
import org.springframework.stereotype.Controller;
99

10+
import java.util.Map;
11+
1012
@Controller
1113
public class ProductController {
12-
13-
@QueryMapping
14-
public Product product(@Argument String id) {
15-
return Product.resolveById(id);
14+
@EntityMapping
15+
public Product product(
16+
@Argument String id,
17+
@Argument String sku,
18+
@Argument("package") String pkg,
19+
@Argument("variation") Map<String, String> variation
20+
) {
21+
if (id != null) {
22+
return Product.resolveById(id);
23+
} else if (sku != null) {
24+
if (pkg != null) {
25+
return Product.resolveBySkuAndPackage(sku, pkg);
26+
} else if (variation != null) {
27+
return Product.resolveBySkuAndVariation(sku, variation.get("id"));
28+
}
1629
}
30+
return null;
31+
}
1732

18-
@SchemaMapping(typeName="Product", field="package")
19-
public String getPackage(Product product) {
20-
return product.getPkg();
21-
}
33+
@QueryMapping
34+
public Product product(@Argument String id) {
35+
return Product.resolveById(id);
36+
}
37+
38+
@SchemaMapping(typeName = "Product", field = "package")
39+
public String getPackage(Product product) {
40+
return product.pkg();
41+
}
2242
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.apollographql.federation.compatibility;
2+
3+
import com.apollographql.federation.compatibility.model.ProductResearch;
4+
import org.springframework.graphql.data.federation.EntityMapping;
5+
import org.springframework.graphql.data.method.annotation.Argument;
6+
import org.springframework.stereotype.Controller;
7+
8+
import java.util.Map;
9+
10+
@Controller
11+
public class ProductResearchController {
12+
@EntityMapping
13+
public ProductResearch productResearch(@Argument("study") Map<String, String> study) {
14+
return ProductResearch.resolveByCaseNumber(study.get("caseNumber"));
15+
}
16+
}
Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
package com.apollographql.federation.compatibility;
22

3-
import java.util.Collections;
43
import org.jetbrains.annotations.NotNull;
54
import org.springframework.graphql.server.WebGraphQlInterceptor;
65
import org.springframework.graphql.server.WebGraphQlRequest;
76
import org.springframework.graphql.server.WebGraphQlResponse;
87
import org.springframework.stereotype.Component;
98
import reactor.core.publisher.Mono;
109

10+
import java.util.Collections;
11+
1112
import static com.apollographql.federation.graphqljava.tracing.FederatedTracingInstrumentation.FEDERATED_TRACING_HEADER_NAME;
1213

1314
@Component
1415
public class TracingInterceptor implements WebGraphQlInterceptor {
1516

16-
@Override
17-
public @NotNull Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, @NotNull Chain chain) {
18-
String headerValue = request.getHeaders().getFirst(FEDERATED_TRACING_HEADER_NAME);
19-
if (headerValue != null) {
20-
request.configureExecutionInput((executionInput, builder) ->
21-
builder.graphQLContext(Collections.singletonMap(FEDERATED_TRACING_HEADER_NAME, headerValue)).build());
22-
}
23-
return chain.next(request);
17+
@Override
18+
public @NotNull Mono<WebGraphQlResponse> intercept(WebGraphQlRequest request, @NotNull Chain chain) {
19+
String headerValue = request.getHeaders().getFirst(FEDERATED_TRACING_HEADER_NAME);
20+
if (headerValue != null) {
21+
request.configureExecutionInput((executionInput, builder) ->
22+
builder.graphQLContext(Collections.singletonMap(FEDERATED_TRACING_HEADER_NAME, headerValue)).build());
2423
}
25-
}
24+
return chain.next(request);
25+
}
26+
}
Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,32 @@
11
package com.apollographql.federation.compatibility;
22

33
import com.apollographql.federation.compatibility.model.User;
4+
import org.springframework.graphql.data.federation.EntityMapping;
5+
import org.springframework.graphql.data.method.annotation.Argument;
46
import org.springframework.graphql.data.method.annotation.SchemaMapping;
57
import org.springframework.stereotype.Controller;
68

79
@Controller
810
public class UserController {
911

10-
@SchemaMapping(typeName="User", field="averageProductsCreatedPerYear")
11-
public Integer getAverageProductsCreatedPerYear(User user) {
12-
if (user.getTotalProductsCreated() != null) {
13-
return Math.round(1.0f * user.getTotalProductsCreated() / user.getYearsOfEmployment());
14-
} else {
15-
return null;
16-
}
12+
@EntityMapping
13+
public User user(@Argument String email, @Argument Integer totalProductsCreated, @Argument Integer yearsOfEmployment) {
14+
final User user = new User(email);
15+
if (totalProductsCreated != null) {
16+
user.setTotalProductsCreated(totalProductsCreated);
1717
}
18-
}
18+
if (yearsOfEmployment != null) {
19+
user.setYearsOfEmployment(yearsOfEmployment);
20+
}
21+
return user;
22+
}
23+
24+
@SchemaMapping(typeName = "User", field = "averageProductsCreatedPerYear")
25+
public Integer getAverageProductsCreatedPerYear(User user) {
26+
if (user.getTotalProductsCreated() != null && user.getYearsOfEmployment() > 0) {
27+
return Math.round(1.0f * user.getTotalProductsCreated() / user.getYearsOfEmployment());
28+
} else {
29+
return null;
30+
}
31+
}
32+
}
Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,4 @@
11
package com.apollographql.federation.compatibility.model;
22

3-
public class CaseStudy {
4-
private final String caseNumber;
5-
private final String description;
6-
7-
public CaseStudy(String caseNumber, String description) {
8-
this.caseNumber = caseNumber;
9-
this.description = description;
10-
}
11-
12-
public String getCaseNumber() {
13-
return caseNumber;
14-
}
15-
16-
public String getDescription() {
17-
return description;
18-
}
3+
public record CaseStudy(String caseNumber, String description) {
194
}
Lines changed: 11 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,18 @@
11
package com.apollographql.federation.compatibility.model;
22

3-
import java.util.Map;
4-
import org.jetbrains.annotations.NotNull;
3+
public record DeprecatedProduct(String sku, String pkg, String reason, User createdBy) {
54

6-
public class DeprecatedProduct {
5+
public static DeprecatedProduct DEPRECATED_PRODUCT = new DeprecatedProduct("apollo-federation-v1", "@apollo/federation-v1", "Migrate to Federation V2");
76

8-
public static DeprecatedProduct DEPRECATED_PRODUCT = new DeprecatedProduct("apollo-federation-v1", "@apollo/federation-v1", "Migrate to Federation V2");
7+
public DeprecatedProduct(String sku, String pkg, String reason) {
8+
this(sku, pkg, reason, User.DEFAULT_USER);
9+
}
910

10-
private final String sku;
11-
private final String pkg;
12-
private final String reason;
13-
private final User createdBy;
14-
15-
public DeprecatedProduct(String sku, String pkg) {
16-
this.sku = sku;
17-
this.pkg = pkg;
18-
this.reason = null;
19-
this.createdBy = User.DEFAULT_USER;
20-
}
21-
22-
public DeprecatedProduct(String sku, String pkg, String reason) {
23-
this.sku = sku;
24-
this.pkg = pkg;
25-
this.reason = reason;
26-
this.createdBy = User.DEFAULT_USER;
27-
}
28-
29-
public DeprecatedProduct(String sku, String pkg, String reason, User createdBy) {
30-
this.sku = sku;
31-
this.pkg = pkg;
32-
this.reason = reason;
33-
this.createdBy = createdBy;
34-
}
35-
36-
public String getSku() {
37-
return sku;
38-
}
39-
40-
public String getPkg() {
41-
return pkg;
42-
}
43-
44-
public String getReason() {
45-
return reason;
46-
}
47-
48-
public User getCreatedBy() {
49-
return createdBy;
50-
}
51-
52-
public static DeprecatedProduct resolveBySkuAndPackage(String sku, String pkg) {
53-
if (DEPRECATED_PRODUCT.sku.equals(sku) && DEPRECATED_PRODUCT.pkg.equals(pkg)) {
54-
return DEPRECATED_PRODUCT;
55-
} else {
56-
return null;
57-
}
58-
}
59-
60-
public static DeprecatedProduct resolveReference(@NotNull Map<String, Object> reference) {
61-
if (reference.get("sku") instanceof String sku && reference.get("package") instanceof String pkg) {
62-
return resolveBySkuAndPackage(sku, pkg);
63-
}
64-
return null;
11+
public static DeprecatedProduct resolveBySkuAndPackage(String sku, String pkg) {
12+
if (DEPRECATED_PRODUCT.sku.equals(sku) && DEPRECATED_PRODUCT.pkg.equals(pkg)) {
13+
return DEPRECATED_PRODUCT;
14+
} else {
15+
return null;
6516
}
17+
}
6618
}

0 commit comments

Comments
 (0)