Skip to content

Commit

Permalink
chore: update compatibility project to use latest Spring integrations (
Browse files Browse the repository at this point in the history
…#410)

Update to use Java records and latest [Spring GraphQL
integrations](https://docs.spring.io/spring-graphql/reference/federation.html).
  • Loading branch information
dariuszkuc authored Jun 7, 2024
1 parent a787bdc commit 28e1065
Show file tree
Hide file tree
Showing 19 changed files with 256 additions and 430 deletions.
2 changes: 1 addition & 1 deletion compatibility/gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
graphql-java.version = 21.1
graphql-java.version=21.1
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -25,24 +15,12 @@ public FederatedTracingInstrumentation federatedTracingInstrumentation() {
}

@Bean
public GraphQlSourceBuilderCustomizer federationTransform() {
return builder -> builder.schemaFactory((registry, wiring) ->
Federation.transform(registry, wiring)
.fetchEntities(env ->
env.<List<Map<String, Object>>>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();
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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<String, String> 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();
}
}
Original file line number Diff line number Diff line change
@@ -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<String, String> study) {
return ProductResearch.resolveByCaseNumber(study.get("caseNumber"));
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
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;
import org.springframework.graphql.server.WebGraphQlResponse;
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<WebGraphQlResponse> 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<WebGraphQlResponse> 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);
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
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;
}
}
}
Original file line number Diff line number Diff line change
@@ -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) {
}
Original file line number Diff line number Diff line change
@@ -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<String, Object> 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;
}
}
}
Loading

0 comments on commit 28e1065

Please sign in to comment.