test pagination, and groupedKey query

This commit is contained in:
renxiaoyin 2023-03-29 10:56:09 +08:00
parent 11e4d575b0
commit 673d3b1291
6 changed files with 136 additions and 21 deletions

View File

@ -39,6 +39,10 @@
<groupId>com.netflix.graphql.dgs</groupId>
<artifactId>graphql-dgs-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.graphql.dgs</groupId>
<artifactId>graphql-dgs-pagination</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.graphql.dgs.codegen</groupId>
<artifactId>graphql-dgs-codegen-client-core</artifactId>
@ -90,6 +94,11 @@
</schemaPaths>
<generateBoxedTypes>true</generateBoxedTypes>
<writeToFiles>true</writeToFiles>
<typeMapping>
<ExtentConnection>
<![CDATA[graphql.relay.SimpleListConnection<Extent>]]>
</ExtentConnection>
</typeMapping>
</configuration>
</plugin>
</plugins>

View File

@ -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);
}
}

View File

@ -11,9 +11,7 @@ import com.netflix.graphql.dgs.context.DgsContext;
import org.dataloader.BatchLoaderEnvironment;
import org.dataloader.MappedBatchLoaderWithContext;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;
@ -21,20 +19,20 @@ import java.util.stream.Collectors;
/**
* Showcase the query:
* query Shops {
* shops {
* shopId
* baseShopInfo {
* shopId
* shopName
* shopStatus
* }
* expandData: extendElements (typeNameFilter: "TypeA"){
* attId,code,type,value
* }
* expandData2: extendElements(typeNameFilter: "TypeB"){
* attId,code,type,value
* }
* }
* shops {
* shopId
* baseShopInfo {
* shopId
* shopName
* shopStatus
* }
* expandData: extendElements (typeNameFilter: "TypeA"){
* attId,code,type,value
* }
* expandData2: extendElements(typeNameFilter: "TypeB"){
* attId,code,type,value
* }
* }
* }
*/
@DgsDataLoader(name = DgsConstants.SHOP.ExtendElements)
@ -48,13 +46,42 @@ public class ExtendElementDataLoaderWithMappedKeys implements MappedBatchLoaderW
@Override
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(() -> {
// 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));
return null;
List<CompletableFuture<Map<Integer, List<ExtendElement>>>> futures = new ArrayList<>();
for (List<ExtendElementQueryKey> groupedKeys : queryMap.values()) {
Set<Integer> shopIds = groupedKeys.stream().map(ExtendElementQueryKey::getId).collect(Collectors.toSet());
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)));
}
}

View File

@ -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();
}

View File

@ -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()
);
}
}

View File

@ -13,6 +13,7 @@ type Shop{
shopId: Int
baseShopInfo:BaseShopInfo
extendElements(typeNameFilter: String): [ExtendElement]
extents(current: Int!,size: Int!): [Extent]
}
type BaseShopInfo{
@ -28,6 +29,15 @@ type ExtendElement{
value: String
}
# for Paging
type Extent @connection{
attId: Int
code:String
type : String
value: String
}
#scalar DateTime
directive @skipcodegen on FIELD_DEFINITION
directive @uppercase on FIELD_DEFINITION
directive @connection on OBJECT