From 28e106595e5dfbe793cfcc9c3ce5f769bf0da9a9 Mon Sep 17 00:00:00 2001 From: Dariusz Kuc <9501705+dariuszkuc@users.noreply.github.com> Date: Fri, 7 Jun 2024 17:28:31 -0500 Subject: [PATCH] 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). --- compatibility/gradle.properties | 2 +- .../federation/compatibility/App.java | 6 +- .../DeprecatedProductController.java | 18 ++- .../compatibility/GraphQLConfiguration.java | 38 +---- .../compatibility/InventoryController.java | 14 ++ .../compatibility/ProductController.java | 38 +++-- .../ProductResearchController.java | 16 ++ .../compatibility/TracingInterceptor.java | 21 +-- .../compatibility/UserController.java | 30 +++- .../compatibility/model/CaseStudy.java | 17 +- .../model/DeprecatedProduct.java | 70 ++------ .../compatibility/model/Inventory.java | 35 ++-- .../compatibility/model/Product.java | 152 +++++------------- .../compatibility/model/ProductDimension.java | 23 +-- .../compatibility/model/ProductResearch.java | 55 ++----- .../compatibility/model/ProductVariation.java | 13 +- .../federation/compatibility/model/User.java | 91 +++++------ .../src/main/resources/application.yml | 5 + .../main/resources/graphql/schema.graphqls | 42 ++--- 19 files changed, 256 insertions(+), 430 deletions(-) create mode 100644 compatibility/src/main/java/com/apollographql/federation/compatibility/InventoryController.java create mode 100644 compatibility/src/main/java/com/apollographql/federation/compatibility/ProductResearchController.java diff --git a/compatibility/gradle.properties b/compatibility/gradle.properties index 13ec18b8..ef83ffaa 100644 --- a/compatibility/gradle.properties +++ b/compatibility/gradle.properties @@ -1 +1 @@ -graphql-java.version = 21.1 +graphql-java.version=21.1 diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/App.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/App.java index f1a87f5f..245d5426 100644 --- a/compatibility/src/main/java/com/apollographql/federation/compatibility/App.java +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/App.java @@ -5,7 +5,7 @@ @SpringBootApplication public class App { - public static void main(String[] args) { - SpringApplication.run(App.class, args); - } + public static void main(String[] args) { + SpringApplication.run(App.class, args); + } } diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/DeprecatedProductController.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/DeprecatedProductController.java index fa5f8563..627ce355 100644 --- a/compatibility/src/main/java/com/apollographql/federation/compatibility/DeprecatedProductController.java +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/DeprecatedProductController.java @@ -1,6 +1,7 @@ package com.apollographql.federation.compatibility; import com.apollographql.federation.compatibility.model.DeprecatedProduct; +import org.springframework.graphql.data.federation.EntityMapping; import org.springframework.graphql.data.method.annotation.Argument; import org.springframework.graphql.data.method.annotation.QueryMapping; import org.springframework.graphql.data.method.annotation.SchemaMapping; @@ -9,13 +10,14 @@ @Controller public class DeprecatedProductController { - @QueryMapping - public DeprecatedProduct deprecatedProduct(@Argument String sku, @Argument("package") String pkg) { - return DeprecatedProduct.resolveBySkuAndPackage(sku, pkg); - } + @QueryMapping + @EntityMapping + public DeprecatedProduct deprecatedProduct(@Argument String sku, @Argument("package") String pkg) { + return DeprecatedProduct.resolveBySkuAndPackage(sku, pkg); + } - @SchemaMapping(typeName="DeprecatedProduct", field="package") - public String getPackage(DeprecatedProduct product) { - return product.getPkg(); - } + @SchemaMapping(typeName = "DeprecatedProduct", field = "package") + public String getPackage(DeprecatedProduct product) { + return product.pkg(); + } } diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/GraphQLConfiguration.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/GraphQLConfiguration.java index 8cb05577..6d5edc89 100644 --- a/compatibility/src/main/java/com/apollographql/federation/compatibility/GraphQLConfiguration.java +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/GraphQLConfiguration.java @@ -1,20 +1,10 @@ package com.apollographql.federation.compatibility; -import com.apollographql.federation.compatibility.model.DeprecatedProduct; -import com.apollographql.federation.compatibility.model.Inventory; -import com.apollographql.federation.compatibility.model.Product; -import com.apollographql.federation.compatibility.model.ProductResearch; -import com.apollographql.federation.compatibility.model.User; -import com.apollographql.federation.graphqljava.Federation; -import com.apollographql.federation.graphqljava._Entity; import com.apollographql.federation.graphqljava.tracing.FederatedTracingInstrumentation; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.graphql.execution.ClassNameTypeResolver; +import org.springframework.graphql.data.federation.FederationSchemaFactory; @Configuration public class GraphQLConfiguration { @@ -25,24 +15,12 @@ public FederatedTracingInstrumentation federatedTracingInstrumentation() { } @Bean - public GraphQlSourceBuilderCustomizer federationTransform() { - return builder -> builder.schemaFactory((registry, wiring) -> - Federation.transform(registry, wiring) - .fetchEntities(env -> - env.>>getArgument(_Entity.argumentName).stream().map(reference -> { - final String typeName = (String) reference.get("__typename"); - return switch (typeName) { - case "DeprecatedProduct" -> DeprecatedProduct.resolveReference(reference); - case "Product" -> Product.resolveReference(reference); - case "ProductResearch" -> ProductResearch.resolveReference(reference); - case "User" -> User.resolveReference(reference); - case "Inventory" -> Inventory.resolveReference(reference); - default -> null; - }; - }).collect(Collectors.toList()) - ) - .resolveEntityType(new ClassNameTypeResolver()) - .build() - ); + public GraphQlSourceBuilderCustomizer customizer(FederationSchemaFactory factory) { + return builder -> builder.schemaFactory(factory::createGraphQLSchema); + } + + @Bean + FederationSchemaFactory federationSchemaFactory() { + return new FederationSchemaFactory(); } } diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/InventoryController.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/InventoryController.java new file mode 100644 index 00000000..779cc124 --- /dev/null +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/InventoryController.java @@ -0,0 +1,14 @@ +package com.apollographql.federation.compatibility; + +import com.apollographql.federation.compatibility.model.Inventory; +import org.springframework.graphql.data.federation.EntityMapping; +import org.springframework.graphql.data.method.annotation.Argument; +import org.springframework.stereotype.Controller; + +@Controller +public class InventoryController { + @EntityMapping + public Inventory inventory(@Argument("id") String id) { + return Inventory.resolveById(id); + } +} diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/ProductController.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/ProductController.java index c0a3c3f8..66b6635a 100644 --- a/compatibility/src/main/java/com/apollographql/federation/compatibility/ProductController.java +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/ProductController.java @@ -1,22 +1,42 @@ package com.apollographql.federation.compatibility; -import com.apollographql.federation.compatibility.model.DeprecatedProduct; import com.apollographql.federation.compatibility.model.Product; +import org.springframework.graphql.data.federation.EntityMapping; import org.springframework.graphql.data.method.annotation.Argument; import org.springframework.graphql.data.method.annotation.QueryMapping; import org.springframework.graphql.data.method.annotation.SchemaMapping; import org.springframework.stereotype.Controller; +import java.util.Map; + @Controller public class ProductController { - - @QueryMapping - public Product product(@Argument String id) { - return Product.resolveById(id); + @EntityMapping + public Product product( + @Argument String id, + @Argument String sku, + @Argument("package") String pkg, + @Argument("variation") Map variation + ) { + if (id != null) { + return Product.resolveById(id); + } else if (sku != null) { + if (pkg != null) { + return Product.resolveBySkuAndPackage(sku, pkg); + } else if (variation != null) { + return Product.resolveBySkuAndVariation(sku, variation.get("id")); + } } + return null; + } - @SchemaMapping(typeName="Product", field="package") - public String getPackage(Product product) { - return product.getPkg(); - } + @QueryMapping + public Product product(@Argument String id) { + return Product.resolveById(id); + } + + @SchemaMapping(typeName = "Product", field = "package") + public String getPackage(Product product) { + return product.pkg(); + } } diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/ProductResearchController.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/ProductResearchController.java new file mode 100644 index 00000000..f2bc2126 --- /dev/null +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/ProductResearchController.java @@ -0,0 +1,16 @@ +package com.apollographql.federation.compatibility; + +import com.apollographql.federation.compatibility.model.ProductResearch; +import org.springframework.graphql.data.federation.EntityMapping; +import org.springframework.graphql.data.method.annotation.Argument; +import org.springframework.stereotype.Controller; + +import java.util.Map; + +@Controller +public class ProductResearchController { + @EntityMapping + public ProductResearch productResearch(@Argument("study") Map study) { + return ProductResearch.resolveByCaseNumber(study.get("caseNumber")); + } +} diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/TracingInterceptor.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/TracingInterceptor.java index 5c53544f..20ba30b8 100644 --- a/compatibility/src/main/java/com/apollographql/federation/compatibility/TracingInterceptor.java +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/TracingInterceptor.java @@ -1,6 +1,5 @@ package com.apollographql.federation.compatibility; -import java.util.Collections; import org.jetbrains.annotations.NotNull; import org.springframework.graphql.server.WebGraphQlInterceptor; import org.springframework.graphql.server.WebGraphQlRequest; @@ -8,18 +7,20 @@ import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; +import java.util.Collections; + import static com.apollographql.federation.graphqljava.tracing.FederatedTracingInstrumentation.FEDERATED_TRACING_HEADER_NAME; @Component public class TracingInterceptor implements WebGraphQlInterceptor { - @Override - public @NotNull Mono intercept(WebGraphQlRequest request, @NotNull Chain chain) { - String headerValue = request.getHeaders().getFirst(FEDERATED_TRACING_HEADER_NAME); - if (headerValue != null) { - request.configureExecutionInput((executionInput, builder) -> - builder.graphQLContext(Collections.singletonMap(FEDERATED_TRACING_HEADER_NAME, headerValue)).build()); - } - return chain.next(request); + @Override + public @NotNull Mono intercept(WebGraphQlRequest request, @NotNull Chain chain) { + String headerValue = request.getHeaders().getFirst(FEDERATED_TRACING_HEADER_NAME); + if (headerValue != null) { + request.configureExecutionInput((executionInput, builder) -> + builder.graphQLContext(Collections.singletonMap(FEDERATED_TRACING_HEADER_NAME, headerValue)).build()); } -} \ No newline at end of file + return chain.next(request); + } +} diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/UserController.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/UserController.java index 3fa2dc3a..56a71207 100644 --- a/compatibility/src/main/java/com/apollographql/federation/compatibility/UserController.java +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/UserController.java @@ -1,18 +1,32 @@ package com.apollographql.federation.compatibility; import com.apollographql.federation.compatibility.model.User; +import org.springframework.graphql.data.federation.EntityMapping; +import org.springframework.graphql.data.method.annotation.Argument; import org.springframework.graphql.data.method.annotation.SchemaMapping; import org.springframework.stereotype.Controller; @Controller public class UserController { - @SchemaMapping(typeName="User", field="averageProductsCreatedPerYear") - public Integer getAverageProductsCreatedPerYear(User user) { - if (user.getTotalProductsCreated() != null) { - return Math.round(1.0f * user.getTotalProductsCreated() / user.getYearsOfEmployment()); - } else { - return null; - } + @EntityMapping + public User user(@Argument String email, @Argument Integer totalProductsCreated, @Argument Integer yearsOfEmployment) { + final User user = new User(email); + if (totalProductsCreated != null) { + user.setTotalProductsCreated(totalProductsCreated); } -} \ No newline at end of file + if (yearsOfEmployment != null) { + user.setYearsOfEmployment(yearsOfEmployment); + } + return user; + } + + @SchemaMapping(typeName = "User", field = "averageProductsCreatedPerYear") + public Integer getAverageProductsCreatedPerYear(User user) { + if (user.getTotalProductsCreated() != null && user.getYearsOfEmployment() > 0) { + return Math.round(1.0f * user.getTotalProductsCreated() / user.getYearsOfEmployment()); + } else { + return null; + } + } +} diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/CaseStudy.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/CaseStudy.java index 882c9326..a12b6aa4 100644 --- a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/CaseStudy.java +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/CaseStudy.java @@ -1,19 +1,4 @@ package com.apollographql.federation.compatibility.model; -public class CaseStudy { - private final String caseNumber; - private final String description; - - public CaseStudy(String caseNumber, String description) { - this.caseNumber = caseNumber; - this.description = description; - } - - public String getCaseNumber() { - return caseNumber; - } - - public String getDescription() { - return description; - } +public record CaseStudy(String caseNumber, String description) { } diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/DeprecatedProduct.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/DeprecatedProduct.java index 0a617fc3..1b5f5839 100644 --- a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/DeprecatedProduct.java +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/DeprecatedProduct.java @@ -1,66 +1,18 @@ package com.apollographql.federation.compatibility.model; -import java.util.Map; -import org.jetbrains.annotations.NotNull; +public record DeprecatedProduct(String sku, String pkg, String reason, User createdBy) { -public class DeprecatedProduct { + public static DeprecatedProduct DEPRECATED_PRODUCT = new DeprecatedProduct("apollo-federation-v1", "@apollo/federation-v1", "Migrate to Federation V2"); - public static DeprecatedProduct DEPRECATED_PRODUCT = new DeprecatedProduct("apollo-federation-v1", "@apollo/federation-v1", "Migrate to Federation V2"); + public DeprecatedProduct(String sku, String pkg, String reason) { + this(sku, pkg, reason, User.DEFAULT_USER); + } - private final String sku; - private final String pkg; - private final String reason; - private final User createdBy; - - public DeprecatedProduct(String sku, String pkg) { - this.sku = sku; - this.pkg = pkg; - this.reason = null; - this.createdBy = User.DEFAULT_USER; - } - - public DeprecatedProduct(String sku, String pkg, String reason) { - this.sku = sku; - this.pkg = pkg; - this.reason = reason; - this.createdBy = User.DEFAULT_USER; - } - - public DeprecatedProduct(String sku, String pkg, String reason, User createdBy) { - this.sku = sku; - this.pkg = pkg; - this.reason = reason; - this.createdBy = createdBy; - } - - public String getSku() { - return sku; - } - - public String getPkg() { - return pkg; - } - - public String getReason() { - return reason; - } - - public User getCreatedBy() { - return createdBy; - } - - public static DeprecatedProduct resolveBySkuAndPackage(String sku, String pkg) { - if (DEPRECATED_PRODUCT.sku.equals(sku) && DEPRECATED_PRODUCT.pkg.equals(pkg)) { - return DEPRECATED_PRODUCT; - } else { - return null; - } - } - - public static DeprecatedProduct resolveReference(@NotNull Map reference) { - if (reference.get("sku") instanceof String sku && reference.get("package") instanceof String pkg) { - return resolveBySkuAndPackage(sku, pkg); - } - return null; + public static DeprecatedProduct resolveBySkuAndPackage(String sku, String pkg) { + if (DEPRECATED_PRODUCT.sku.equals(sku) && DEPRECATED_PRODUCT.pkg.equals(pkg)) { + return DEPRECATED_PRODUCT; + } else { + return null; } + } } diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/Inventory.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/Inventory.java index 7749f260..ee63f1c0 100644 --- a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/Inventory.java +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/Inventory.java @@ -1,34 +1,19 @@ package com.apollographql.federation.compatibility.model; -import static com.apollographql.federation.compatibility.model.DeprecatedProduct.DEPRECATED_PRODUCT; - import java.util.List; -import java.util.Map; -import org.jetbrains.annotations.NotNull; - -public class Inventory { - private final String id; - private final List deprecatedProducts; - - public Inventory(String id) { - this.id = id; - this.deprecatedProducts = List.of(DEPRECATED_PRODUCT); - } - - public String getId() { - return id; - } +import static com.apollographql.federation.compatibility.model.DeprecatedProduct.DEPRECATED_PRODUCT; - public List getDeprecatedProducts() { - return deprecatedProducts; - } +public record Inventory(String id, List deprecatedProducts) { - public static Inventory resolveReference(@NotNull Map reference) { - if (reference.get("id") instanceof String id && "apollo-oss".equals(id)) { - return new Inventory(id); - } + public Inventory(String id) { + this(id, List.of(DEPRECATED_PRODUCT)); + } - return null; + public static Inventory resolveById(String id) { + if ("apollo-oss".equals(id)) { + return new Inventory(id); } + return null; + } } diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/Product.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/Product.java index 12015b69..adef2b52 100644 --- a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/Product.java +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/Product.java @@ -1,121 +1,47 @@ package com.apollographql.federation.compatibility.model; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.jetbrains.annotations.NotNull; -public class Product { - - private static final Map PRODUCTS = Stream.of( - new Product("apollo-federation", "federation", "@apollo/federation", "OSS", List.of(ProductResearch.FEDERATION_STUDY)), - new Product("apollo-studio", "studio", "", "platform", List.of(ProductResearch.STUDIO_STUDY)) - ).collect(Collectors.toMap(Product::getId, product -> product)); - - private final String id; - private final String sku; - private final String pkg; - private final ProductVariation variation; - private final ProductDimension dimensions; - private final User createdBy; - - private final List research; - - public Product(String id) { - this.id = id; - this.sku = ""; - this.pkg = ""; - this.variation = new ProductVariation(""); - this.dimensions = new ProductDimension("small", 1, "kg"); - this.createdBy = User.DEFAULT_USER; - this.research = new ArrayList<>(); - } - - public Product(String id, String sku, String pkg, String variationId, List research) { - this.id = id; - this.sku = sku; - this.pkg = pkg; - this.variation = new ProductVariation(variationId); - this.dimensions = new ProductDimension("small", 1, "kg"); - this.createdBy = User.DEFAULT_USER; - this.research = research; - } - - public Product(String sku, String pkg) { - this.id = ""; - this.sku = sku; - this.pkg = pkg; - this.variation = new ProductVariation(""); - this.dimensions = new ProductDimension("small", 1, "kg"); - this.createdBy = User.DEFAULT_USER; - this.research = new ArrayList<>(); - } - - public Product(String sku, ProductVariation variation) { - this.id = ""; - this.pkg = ""; - this.sku = sku; - this.variation = variation; - this.dimensions = new ProductDimension("small", 1, "kg"); - this.createdBy = User.DEFAULT_USER; - this.research = new ArrayList<>(); - } - - public String getId() { - return id; - } - - public String getSku() { - return sku; - } - - public ProductDimension getDimensions() { - return dimensions; - } - - public String getPkg() { - return pkg; - } - - public ProductVariation getVariation() { - return variation; - } - - public User getCreatedBy() { - return createdBy; - } - - public List getResearch() { - return research; - } - - public static Product resolveById(String id) { - return PRODUCTS.get(id); - } - - public static Product resolveReference(@NotNull Map reference) { - if (reference.get("id") instanceof String productId) { - return PRODUCTS.get(productId); - } else { - String productSku = (String) reference.get("sku"); - if (reference.get("package") instanceof String productPackage) { - for (Product product : PRODUCTS.values()) { - if (product.getSku().equals(productSku) && product.getPkg().equals(productPackage)) { - return product; - } - } - } else if (reference.get("variation") instanceof HashMap productVariation) { - for (Product product : PRODUCTS.values()) { - if (product.getSku().equals(productSku) && product.getVariation().getId().equals(productVariation.get("id"))) { - return product; - } - } - } - } - - return null; - } +public record Product(String id, String sku, String pkg, ProductVariation variation, ProductDimension dimensions, User createdBy, List research) { + + private static final Map PRODUCTS = Stream.of( + new Product("apollo-federation", "federation", "@apollo/federation", "OSS", List.of(ProductResearch.FEDERATION_STUDY)), + new Product("apollo-studio", "studio", "", "platform", List.of(ProductResearch.STUDIO_STUDY)) + ).collect(Collectors.toMap(Product::id, product -> product)); + + public Product(String id, String sku, String pkg, String variationId, List research) { + this( + id, + sku, + pkg, + new ProductVariation(variationId), + new ProductDimension("small", 1, "kg"), + User.DEFAULT_USER, research + ); + } + + public static Product resolveById(String id) { + return PRODUCTS.get(id); + } + + public static Product resolveBySkuAndPackage(String sku, String pkg) { + for (Product product : PRODUCTS.values()) { + if (product.sku().equals(sku) && product.pkg().equals(pkg)) { + return product; + } + } + return null; + } + + public static Product resolveBySkuAndVariation(String sku, String variationId) { + for (Product product : PRODUCTS.values()) { + if (product.sku().equals(sku) && product.variation().id().equals(variationId)) { + return product; + } + } + return null; + } } diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/ProductDimension.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/ProductDimension.java index eac9b12a..0f1449aa 100644 --- a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/ProductDimension.java +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/ProductDimension.java @@ -1,25 +1,4 @@ package com.apollographql.federation.compatibility.model; -public class ProductDimension { - private final String size; - private final float weight; - private final String unit; - - public ProductDimension(String size, float weight, String unit) { - this.size = size; - this.weight = weight; - this.unit = unit; - } - - public String getSize() { - return size; - } - - public float getWeight() { - return weight; - } - - public String getUnit() { - return unit; - } +public record ProductDimension(String size, float weight, String unit) { } diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/ProductResearch.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/ProductResearch.java index f4e96f64..d134e8cf 100644 --- a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/ProductResearch.java +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/ProductResearch.java @@ -1,45 +1,20 @@ package com.apollographql.federation.compatibility.model; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import org.jetbrains.annotations.NotNull; -public class ProductResearch { - public static final ProductResearch FEDERATION_STUDY = new ProductResearch(new CaseStudy("1234", "Federation Study")); - public static final ProductResearch STUDIO_STUDY = new ProductResearch(new CaseStudy("1235", "Studio Study")); - public static final List RESEARCH_LIST = List.of(FEDERATION_STUDY, STUDIO_STUDY); - - private final CaseStudy study; - private final String outcome; - - public ProductResearch(CaseStudy study) { - this.study = study; - this.outcome = null; - } - - public ProductResearch(CaseStudy study, String outcome) { - this.study = study; - this.outcome = outcome; - } - - public CaseStudy getStudy() { - return study; - } - - public String getOutcome() { - return outcome; - } - - public static ProductResearch resolveReference(@NotNull Map reference) { - if (reference.get("study") instanceof HashMap caseStudy) { - if (caseStudy.get("caseNumber") instanceof String caseNumber) { - return RESEARCH_LIST.stream() - .filter(research -> research.study.getCaseNumber().equals(caseNumber)) - .findAny() - .orElse(null); - } - } - return null; - } +public record ProductResearch(CaseStudy study, String outcome) { + public static final ProductResearch FEDERATION_STUDY = new ProductResearch(new CaseStudy("1234", "Federation Study")); + public static final ProductResearch STUDIO_STUDY = new ProductResearch(new CaseStudy("1235", "Studio Study")); + public static final List RESEARCH_LIST = List.of(FEDERATION_STUDY, STUDIO_STUDY); + + public ProductResearch(CaseStudy study) { + this(study, null); + } + + public static ProductResearch resolveByCaseNumber(String caseNumber) { + return RESEARCH_LIST.stream() + .filter(research -> research.study.caseNumber().equals(caseNumber)) + .findAny() + .orElse(null); + } } diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/ProductVariation.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/ProductVariation.java index 6b5a647e..e839f567 100644 --- a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/ProductVariation.java +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/ProductVariation.java @@ -1,13 +1,4 @@ package com.apollographql.federation.compatibility.model; -public class ProductVariation { - private final String id; - - public ProductVariation(String id) { - this.id = id; - } - - public String getId() { - return id; - } -} \ No newline at end of file +public record ProductVariation(String id) { +} diff --git a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/User.java b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/User.java index 6f91e083..0b7fca46 100644 --- a/compatibility/src/main/java/com/apollographql/federation/compatibility/model/User.java +++ b/compatibility/src/main/java/com/apollographql/federation/compatibility/model/User.java @@ -1,59 +1,42 @@ package com.apollographql.federation.compatibility.model; -import java.util.Map; -import org.jetbrains.annotations.NotNull; - public class User { - public static User DEFAULT_USER = new User("support@apollographql.com"); - - private final String email; - private final String name; - private Integer totalProductsCreated; - - private int yearsOfEmployment; - - public User(String email) { - this.email = email; - this.totalProductsCreated = 1337; - this.name = "Jane Smith"; - } - - public String getEmail() { - return email; - } - - public String getName() { - return name; - } - - public Integer getTotalProductsCreated() { - return totalProductsCreated; - } - - public void setTotalProductsCreated(Integer totalProductsCreated) { - this.totalProductsCreated = totalProductsCreated; - } - - public int getYearsOfEmployment() { - return yearsOfEmployment; - } - - public void setYearsOfEmployment(int yearsOfEmployment) { - this.yearsOfEmployment = yearsOfEmployment; - } - - public static User resolveReference(@NotNull Map reference) { - if (reference.get("email") instanceof String email) { - final User user = new User(email); - if (reference.get("totalProductsCreated") instanceof Integer totalProductsCreated) { - user.setTotalProductsCreated(totalProductsCreated); - } - if (reference.get("yearsOfEmployment") instanceof Integer yearsOfEmployment) { - user.setYearsOfEmployment(yearsOfEmployment); - } - return user; - } - return null; - } + public static User DEFAULT_USER = new User("support@apollographql.com"); + + private final String email; + private final String name; + private Integer totalProductsCreated; + + private int yearsOfEmployment; + + public User(String email) { + this.email = email; + this.totalProductsCreated = 1337; + this.name = "Jane Smith"; + } + + public String getEmail() { + return email; + } + + public String getName() { + return name; + } + + public Integer getTotalProductsCreated() { + return totalProductsCreated; + } + + public void setTotalProductsCreated(Integer totalProductsCreated) { + this.totalProductsCreated = totalProductsCreated; + } + + public int getYearsOfEmployment() { + return yearsOfEmployment; + } + + public void setYearsOfEmployment(int yearsOfEmployment) { + this.yearsOfEmployment = yearsOfEmployment; + } } diff --git a/compatibility/src/main/resources/application.yml b/compatibility/src/main/resources/application.yml index afeee5f2..acc79679 100644 --- a/compatibility/src/main/resources/application.yml +++ b/compatibility/src/main/resources/application.yml @@ -3,5 +3,10 @@ spring: name: federation-jvm-compatibility graphql: path: / + graphiql: + enabled: true + schema: + printer: + enabled: true server: port: 4001 diff --git a/compatibility/src/main/resources/graphql/schema.graphqls b/compatibility/src/main/resources/graphql/schema.graphqls index 73e2fa3e..a132952e 100644 --- a/compatibility/src/main/resources/graphql/schema.graphqls +++ b/compatibility/src/main/resources/graphql/schema.graphqls @@ -1,22 +1,22 @@ extend schema - @link( - url: "https://specs.apollo.dev/federation/v2.5", - import: [ - "@composeDirective", - "@extends", - "@external", - "@inaccessible", - "@interfaceObject", - "@key", - "@override", - "@provides", - "@requires", - "@shareable", - "@tag" - ] - ) - @link(url: "https://myspecs.dev/myCustomDirective/v1.0", import: ["@custom"]) - @composeDirective(name: "@custom") +@link( + url: "https://specs.apollo.dev/federation/v2.5", + import: [ + "@composeDirective", + "@extends", + "@external", + "@inaccessible", + "@interfaceObject", + "@key", + "@override", + "@provides", + "@requires", + "@shareable", + "@tag" + ] +) +@link(url: "https://myspecs.dev/myCustomDirective/v1.0", import: ["@custom"]) +@composeDirective(name: "@custom") directive @custom on OBJECT @@ -58,14 +58,14 @@ type ProductDimension @shareable { unit: String @inaccessible } -extend type Query { +type Query { product(id: ID!): Product deprecatedProduct(sku: String!, package: String!): DeprecatedProduct @deprecated(reason: "Use product query instead") } -type User @extends @key(fields: "email") { +type User @key(fields: "email") { averageProductsCreatedPerYear: Int @requires(fields: "totalProductsCreated yearsOfEmployment") - email: ID! @external + email: ID! name: String @override(from: "users") totalProductsCreated: Int @external yearsOfEmployment: Int! @external