boot spring 怎么执行hql_spring-boot 中使用graphql的正确姿势

方飞鸣
2023-12-01

在spring-boot中使用graphql

首先构建spring-boot项目,pom.xml文件中加入

com.graphql-java-kickstart

graphql-java-tools

5.4.0

com.graphql-java

graphql-spring-boot-starter

5.0.2

com.graphql-java

graphiql-spring-boot-starter

5.0.2

接着定义graphql的schema,在resources目录下任意位置的*.graphqls文件都会被扫描到,作为graphql 的schema。

这里在resources下先建一个文件夹/graphql,建立schema文件

schema.graphqls

type Query {

user(nickname: String): User

users: [User]

article(title: String!): Article

}

type Mutation {

addUser(mail: String!, nickname: String!, password: String!): User

addArticle(title: String!, content: String!, authorId: String!): Article

}

type User {

id: String!

mail: String!

nickname: String!

password: String!

description: String

}

type Article {

id: String!

author: User!

title: String!

content: String!

createBy: String

thumbUp: Int

}

Resolver 和数据类

GraphQL Java Tools可以将schema中定义的类型的属性与java对象的属性或方法对应起来。即上面的User类型,可以使用一个类与之对应

public class User {

@Id

private String id;

private String nickname;

private String mail;

private String password;

private String description;

// 构造器,getter和setter

}

但是在Article类型中author的属性是User,我们该如何解决呢?

这时我们可以使用一个GraphQLResolver指定某个类型的解析

@Component

public class ArticleResolver implements GraphQLResolver {

private final UserRepository userRepository;

public ArticleResolver(UserRepository userRepository) {

this.userRepository = userRepository;

}

public User author(Article article) {

return userRepository.findById(article.getAuthorId()).get();

}

}

指定Article类型的解析方式,其中标量类型可以直接从Aritcle的java类属性中获取,所以不必写方法,对于author这个属性,其类型为User,我们指定author()方法进行解析。

那么到底type Article {...}schema里面的属性怎么解析呢?是与数据类进行映射,还是与resolver中的方法进行映射?

官网上给出了映射的优先级:

首先是resolver

method 属性名(...)

method is属性名(...)

method get属性名(...)

method getField属性名(...)

其次是Data Class(即与类型对应的java类)

method 属性名(...)

method is属性名(...)

method get属性名(...)

method getField属性名(...)

field 属性名

所以首先在ArticleResolver中查找author的映射,找不到的属性则一致向下找到属性的java类的get方法/属性本身。

另外,要给Query和Mutation至少创建一个Resolver

@Component

public class QueryResolver implements GraphQLQueryResolver {

private final UserRepository userRepository;

private final ArticleRepository articleRepository;

public QueryResolver(UserRepository userRepository, ArticleRepository articleRepository) {

this.userRepository = userRepository;

this.articleRepository = articleRepository;

}

public Article article(String title) {

return articleRepository.findArticleByTitle(title);

}

public User user(String nickname) {

return userRepository.findUserByNickname(nickname);

}

public List users() {

return userRepository.findAll();

}

}

@Component

public class MutationResolver implements GraphQLQueryResolver, GraphQLMutationResolver {

private final ArticleRepository articleRepository;

private final UserRepository userRepository;

private final BCryptPasswordEncoder encoder;

public MutationResolver(ArticleRepository articleRepository, UserRepository userRepository, BCryptPasswordEncoder encoder) {

this.articleRepository = articleRepository;

this.userRepository = userRepository;

this.encoder = encoder;

}

public User addUser(String mail, String nickname, String password) {

if(userRepository.findUserByNickname(nickname) != null){

return null;

}

return userRepository.save(User.builder()

.nickname(nickname)

.mail(mail)

.password(encoder.encode(password))

.build());

}

public Article addArticle(String title, String content, String authorId) {

if(!userRepository.findById(authorId).isPresent()){

return null;

}

return articleRepository.save(Article.builder()

.authorId(authorId)

.title(title)

.content(content)

.createBy(new Date())

.thumbUp(0)

.build());

}

}

这里使用mongodb存储数据。

运行,在http://localhost:8080/graphiql 中进行操作

 类似资料: