test pagination, and groupedKey query
This commit is contained in:
parent
11e4d575b0
commit
673d3b1291
9
pom.xml
9
pom.xml
|
|
@ -39,6 +39,10 @@
|
||||||
<groupId>com.netflix.graphql.dgs</groupId>
|
<groupId>com.netflix.graphql.dgs</groupId>
|
||||||
<artifactId>graphql-dgs-spring-boot-starter</artifactId>
|
<artifactId>graphql-dgs-spring-boot-starter</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.netflix.graphql.dgs</groupId>
|
||||||
|
<artifactId>graphql-dgs-pagination</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.netflix.graphql.dgs.codegen</groupId>
|
<groupId>com.netflix.graphql.dgs.codegen</groupId>
|
||||||
<artifactId>graphql-dgs-codegen-client-core</artifactId>
|
<artifactId>graphql-dgs-codegen-client-core</artifactId>
|
||||||
|
|
@ -90,6 +94,11 @@
|
||||||
</schemaPaths>
|
</schemaPaths>
|
||||||
<generateBoxedTypes>true</generateBoxedTypes>
|
<generateBoxedTypes>true</generateBoxedTypes>
|
||||||
<writeToFiles>true</writeToFiles>
|
<writeToFiles>true</writeToFiles>
|
||||||
|
<typeMapping>
|
||||||
|
<ExtentConnection>
|
||||||
|
<![CDATA[graphql.relay.SimpleListConnection<Extent>]]>
|
||||||
|
</ExtentConnection>
|
||||||
|
</typeMapping>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.longfor.bff_netflix.datafetchers;
|
||||||
|
|
||||||
|
import com.longfor.DgsConstants;
|
||||||
|
import com.longfor.bff_netflix.services.ExtentService;
|
||||||
|
import com.longfor.types.Extent;
|
||||||
|
import com.netflix.graphql.dgs.DgsComponent;
|
||||||
|
import com.netflix.graphql.dgs.DgsData;
|
||||||
|
import com.netflix.graphql.dgs.DgsDataFetchingEnvironment;
|
||||||
|
import graphql.relay.Connection;
|
||||||
|
import graphql.relay.DefaultConnectionCursor;
|
||||||
|
import graphql.relay.DefaultPageInfo;
|
||||||
|
import graphql.relay.SimpleListConnection;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@DgsComponent
|
||||||
|
public class ExtentDataFetcher {
|
||||||
|
private final ExtentService extentService;
|
||||||
|
|
||||||
|
public ExtentDataFetcher(ExtentService extentService) {
|
||||||
|
this.extentService = extentService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@DgsData(parentType = DgsConstants.SHOP.TYPE_NAME, field = DgsConstants.SHOP.Extents)
|
||||||
|
public List<Extent> extents(DgsDataFetchingEnvironment dfe){
|
||||||
|
Integer current = dfe.getExecutionStepInfo().getArgument("current");
|
||||||
|
Integer size = dfe.getExecutionStepInfo().getArgument("size");
|
||||||
|
List<Extent> extents = this.extentService.extents();
|
||||||
|
return extents;
|
||||||
|
//
|
||||||
|
// return new SimpleListConnection<>(extents).get(dfe);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,9 +11,7 @@ import com.netflix.graphql.dgs.context.DgsContext;
|
||||||
import org.dataloader.BatchLoaderEnvironment;
|
import org.dataloader.BatchLoaderEnvironment;
|
||||||
import org.dataloader.MappedBatchLoaderWithContext;
|
import org.dataloader.MappedBatchLoaderWithContext;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.CompletionStage;
|
import java.util.concurrent.CompletionStage;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
@ -21,20 +19,20 @@ import java.util.stream.Collectors;
|
||||||
/**
|
/**
|
||||||
* Showcase the query:
|
* Showcase the query:
|
||||||
* query Shops {
|
* query Shops {
|
||||||
* shops {
|
* shops {
|
||||||
* shopId
|
* shopId
|
||||||
* baseShopInfo {
|
* baseShopInfo {
|
||||||
* shopId
|
* shopId
|
||||||
* shopName
|
* shopName
|
||||||
* shopStatus
|
* shopStatus
|
||||||
* }
|
* }
|
||||||
* expandData: extendElements (typeNameFilter: "TypeA"){
|
* expandData: extendElements (typeNameFilter: "TypeA"){
|
||||||
* attId,code,type,value
|
* attId,code,type,value
|
||||||
* }
|
* }
|
||||||
* expandData2: extendElements(typeNameFilter: "TypeB"){
|
* expandData2: extendElements(typeNameFilter: "TypeB"){
|
||||||
* attId,code,type,value
|
* attId,code,type,value
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
@DgsDataLoader(name = DgsConstants.SHOP.ExtendElements)
|
@DgsDataLoader(name = DgsConstants.SHOP.ExtendElements)
|
||||||
|
|
@ -48,13 +46,42 @@ public class ExtendElementDataLoaderWithMappedKeys implements MappedBatchLoaderW
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletionStage<Map<ExtendElementQueryKey, List<ExtendElement>>> load(Set<ExtendElementQueryKey> set, BatchLoaderEnvironment environment) {
|
public CompletionStage<Map<ExtendElementQueryKey, List<ExtendElement>>> load(Set<ExtendElementQueryKey> set, BatchLoaderEnvironment environment) {
|
||||||
|
// groupBy arguments, so the query will hold the same argument with different shopId
|
||||||
|
Map<ExtendElementQueryArgument, List<ExtendElementQueryKey>> queryMap = set.stream().collect(Collectors.groupingBy(ExtendElementQueryKey::getArguments));
|
||||||
|
|
||||||
|
CompletableFuture<Map<ExtendElementQueryKey, List<ExtendElement>>> completableFuture = CompletableFuture.supplyAsync(() -> {
|
||||||
|
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
List<CompletableFuture<Map<Integer, List<ExtendElement>>>> futures = new ArrayList<>();
|
||||||
// groupBy arguments, so the query will hold the same argument with different shopId
|
for (List<ExtendElementQueryKey> groupedKeys : queryMap.values()) {
|
||||||
Map<ExtendElementQueryArgument, List<ExtendElementQueryKey>> queryMap = set.stream().collect(Collectors.groupingBy(ExtendElementQueryKey::getArguments));
|
Set<Integer> shopIds = groupedKeys.stream().map(ExtendElementQueryKey::getId).collect(Collectors.toSet());
|
||||||
return null;
|
ExtendElementQueryArgument argument = groupedKeys.get(0).getArguments();
|
||||||
|
CompletableFuture<Map<Integer, List<ExtendElement>>> future = CompletableFuture.supplyAsync(() ->
|
||||||
|
fetchExtendElements(shopIds.stream().collect(Collectors.toList()), argument)
|
||||||
|
);
|
||||||
|
futures.add(future);
|
||||||
|
}
|
||||||
|
List<Map<Integer, List<ExtendElement>>> elementResult = futures.stream().map(CompletableFuture::join).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// rebuild querykey->result map
|
||||||
|
Map<ExtendElementQueryKey, List<ExtendElement>> mappedElements = new HashMap<>();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (List<ExtendElementQueryKey> groupedKeys : queryMap.values()) {
|
||||||
|
Map<Integer, List<ExtendElement>> result = elementResult.get(i++);
|
||||||
|
for (ExtendElementQueryKey key : groupedKeys) {
|
||||||
|
mappedElements.put(key, result.getOrDefault(key.getId(), new ArrayList<>()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mappedElements;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
return completableFuture;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Integer, List<ExtendElement>> fetchExtendElements(List<Integer> ids, ExtendElementQueryArgument argument) {
|
||||||
|
List<ExtendElement> extendElementList =
|
||||||
|
ids.stream().map(id -> ExtendElement.newBuilder().attId(id).type(argument.getType()).build()).collect(Collectors.toList());
|
||||||
|
List<ExtendElement> finalExtendElementList = extendElementList.stream().filter(t -> !t.getType().equals("TypeB")).collect(Collectors.toList());
|
||||||
|
return finalExtendElementList.stream().collect(Collectors.toMap(ExtendElement::getAttId, t -> Arrays.asList(t)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.longfor.bff_netflix.services;
|
||||||
|
|
||||||
|
import com.longfor.types.Extent;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ExtentService {
|
||||||
|
List<Extent> extents();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.longfor.bff_netflix.services.impl;
|
||||||
|
|
||||||
|
import com.longfor.bff_netflix.services.ExtentService;
|
||||||
|
import com.longfor.types.Extent;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ExtentServiceImpl implements ExtentService {
|
||||||
|
@Override
|
||||||
|
public List<Extent> extents() {
|
||||||
|
return Arrays.asList(
|
||||||
|
Extent.newBuilder().attId(1).type("TypeA").code("A").value("A").build(),
|
||||||
|
Extent.newBuilder().attId(2).type("TypeB").code("B").value("B").build(),
|
||||||
|
Extent.newBuilder().attId(3).type("TypeC").code("C").value("C").build(),
|
||||||
|
Extent.newBuilder().attId(4).type("TypeA").code("A").value("A").build(),
|
||||||
|
Extent.newBuilder().attId(5).type("TypeB").code("B").value("B").build(),
|
||||||
|
Extent.newBuilder().attId(6).type("TypeC").code("C").value("C").build(),
|
||||||
|
Extent.newBuilder().attId(7).type("TypeA").code("A").value("A").build(),
|
||||||
|
Extent.newBuilder().attId(8).type("TypeB").code("B").value("B").build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,7 @@ type Shop{
|
||||||
shopId: Int
|
shopId: Int
|
||||||
baseShopInfo:BaseShopInfo
|
baseShopInfo:BaseShopInfo
|
||||||
extendElements(typeNameFilter: String): [ExtendElement]
|
extendElements(typeNameFilter: String): [ExtendElement]
|
||||||
|
extents(current: Int!,size: Int!): [Extent]
|
||||||
}
|
}
|
||||||
|
|
||||||
type BaseShopInfo{
|
type BaseShopInfo{
|
||||||
|
|
@ -28,6 +29,15 @@ type ExtendElement{
|
||||||
value: String
|
value: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# for Paging
|
||||||
|
type Extent @connection{
|
||||||
|
attId: Int
|
||||||
|
code:String
|
||||||
|
type : String
|
||||||
|
value: String
|
||||||
|
}
|
||||||
|
|
||||||
#scalar DateTime
|
#scalar DateTime
|
||||||
directive @skipcodegen on FIELD_DEFINITION
|
directive @skipcodegen on FIELD_DEFINITION
|
||||||
directive @uppercase on FIELD_DEFINITION
|
directive @uppercase on FIELD_DEFINITION
|
||||||
|
directive @connection on OBJECT
|
||||||
Loading…
Reference in New Issue