graphql-spring-boot-starter + dataloader demo

网上的graphql使用dataloader的demo大都是kotlin加上gradle的,
搜不到能用的maven构建的java的demo,很难受:(

因为是dataloader的demo,所以就只有查询的功能,没有新增修改的功能,
主要就是findAllBooks,先查book,再查author,如果不用dataloader,会发生n+1问题,现在使用了dataloader,查author的时候,是收集了bookList里面每个book的authorId,然后最后汇总查询的。

代码如下:

maven依赖如下,都是找的当前最高版本的maven依赖

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>

<groupId>com.graphql-java</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>5.0.2</version>

<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>5.2.4</version>

<groupId>com.graphql-java</groupId>
<artifactId>graphiql-spring-boot-starter</artifactId>
<version>5.0.2</version>

GraphqlApplication.java

@SpringBootApplication
public class GraphqlApplication {
    public static void main(String[] args) {
        SpringApplication.run(GraphqlApplication.class, args);
    }
}

schema.graphqls

type Author {
    id: Long!
    firstName: String
    lastName: String
}
type Book {
    id: Long!
    title: String!
    isbn: String!
    pageCount: Int
    author: Author
}

root.graphqls

type Query {
    findAllBooks: [Book]!
}
type Mutation {
}

Query.java,

@Component
public class Query implements GraphQLQueryResolver {
    public List<Book> findAllBooks() {
        return BookRepo.findAll();
    }
}

Mutation.java, mutation什么功能都没有实现

@Component
public class Mutation implements GraphQLMutationResolver {
}

BookResolver.java

@Component
public class BookResolver implements GraphQLResolver<Book> {
    public CompletableFuture<Author> getAuthor(Book book, DataFetchingEnvironment environment) {
        //应该从environment中获取AuthorDataLoader的,但是environment里面暂时没找到authorLoader,所以变通了一下,使用了一个全局变量的dataloader
        return AuthorDataLoader.INSTANCE.load(book.getAuthorId());
    }
}

AuthorResolver.java

@Component
public class AuthorResolver implements GraphQLResolver<Author> {
}

AuthorRepo.java

public class AuthorRepo {
    public static Map<Long, Author> authorMap = new HashMap<>();
    static {
        authorMap.put(1L, new Author(1L, "zhi", "chi"));
        authorMap.put(2L, new Author(2L, "lu", "xun"));
    }
    public static List<Author> findAllById(List<Long> idList) {
        List<Author> authorList = new ArrayList<>();
        for (Long id : idList) {
            authorList.add(authorMap.get(id));
        }
        return authorList;
    }
}

BookRepo.java

public class BookRepo {
    public static Map<Long, Book> bookMap = new HashMap<>();
    static {
        bookMap.put(1L, new Book(1L, "成功学", "1234", 56, 1L));
        bookMap.put(2L, new Book(2L, "失败时成功之母", "1234778", 65, 2L));
    }
    public static List<Book> findAll() {
        return new ArrayList(bookMap.values());    }
}

AuthorDataLoader.java

public class AuthorDataLoader extends DataLoader<Long, Author> {
    public static AuthorDataLoader INSTANCE = new AuthorDataLoader();
    public AuthorDataLoader() {
        super((BatchLoader) keys -> CompletableFuture.supplyAsync(() -> AuthorRepo.findAllById(keys)),
                DataLoaderOptions.newOptions().setCachingEnabled(false));
    }
}

把dataloader配置到GraphQL环境中,GraphQLConfig

@Configuration
public class GraphQLConfig {
    @Bean
    public Instrumentation instrumentation() {
        DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry();
        dataLoaderRegistry.register("author", DataLoaderFact.getBatchLoader());
        DataLoaderDispatcherInstrumentation dispatcherInstrumentation
                = new DataLoaderDispatcherInstrumentation(dataLoaderRegistry);
        return new ChainedInstrumentation(Arrays.asList(
                dispatcherInstrumentation,
                new MaxQueryComplexityInstrumentation(100),
                new MaxQueryDepthInstrumentation(10)
        ));
    }
}

整个项目跑起来,

输入:
{
  findAllBooks { id, title, author { firstName } }
}
输出:
{
  "data": {
    "findAllBooks": [
      {
        "id": 1,
        "title": "成功学",
        "author": {
          "firstName": "zhi"
        }
      },
      {
        "id": 2,
        "title": "失败时成功之母",
        "author": {
          "firstName": "lu"
        }
      }
    ]
  }
}
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容