英文:
graphql servlet not started with graphql-java-tools (schema files not found?)
问题
根据 graphql-java-kickstart/graphql-java-tools
文档,当项目添加依赖 com.graphql-java-kickstart:graphql-spring-boot-starter
并自动扫描 .graphqls
模式文件时,应该会创建一个 'graphql' 端点。
您有以下依赖项:
...
<spring-boot.version>2.3.3.RELEASE</spring-boot.version>
<graphql.version>7.0.1</graphql.version>
<graphql-java-tools.version>6.2.0</graphql-java-tools.version>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- graphql -->
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>${graphql.version}</version>
</dependency>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphiql-spring-boot-starter</artifactId>
<version>${graphql.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>${graphql-java-tools.version}</version>
</dependency>
模式定义如下:
在 query.graphqls
中:
type Query {
user(username: String!)
users: [User]
}
在 user.graphqls
中:
type User {
userId: Number!
username: String!
}
对应的 GraphQLQueryResolver 代码如下:
@Component
public class UserQueryResolver implements GraphQLQueryResolver {
private final UserRepository userRepository;
public UserQueryResolver(UserRepository userRepository) {
this.userRepository = userRepository;
}
public Iterable<User> users() {
return this.userRepository.findAll();
}
public User user(String username) {
return this.userRepository.findByUsername(username).orElseThrow();
}
}
public interface UserRepository extends JpaRepository<User, Integer> {
Optional<User> findByUsername(String username);
}
根据文档说明:
如果将
graphql-spring-boot-starter
作为依赖项添加到引导应用程序中,并且应用程序中存在一个GraphQLSchema
bean,则该 servlet 将在/graphql
处可访问。
当在类路径上找到支持的
graphql-java
模式库时,也可以自动创建 GraphQL 模式。
根据这些条件,graphql-java-tools
库应该会自动创建一个模式:
所有的
GraphQLResolver
和GraphQLScalar
bean,以及一个类型为SchemaParserDictionary
的 bean(用于提供所有其他类),将被用于创建GraphQLSchema
。类路径中命名为*.graphqls
的任何文件都将用于提供模式定义。
但是,尽管您认为已经满足了所有条件,访问 localhost:8080/graphql
时会得到 404 错误。需要注意的是,localhost:8080/graphiql
是可用的,但无法加载模式,显示如下错误:
{
"timestamp": "2020-09-15T12:22:21.748+00:00",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/graphql"
}
您漏掉了什么呢?
英文:
So according to the graphql-java-kickstart/graphql-java-tools a 'graphql' endpoint should become available when the dependency 'com.graphql-java-kickstart:graphql-spring-boot-starter' is added to the project and .graphqls schema files are scanned automatically.
I have the following dependencies:
...
<spring-boot.version>2.3.3.RELEASE</spring-boot.version>
<graphql.version>7.0.1</graphql.version>
<graphql-java-tools.version>6.2.0</graphql-java-tools.version>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- graphql -->
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>${graphql.version}</version>
</dependency>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphiql-spring-boot-starter</artifactId>
<version>${graphql.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>${graphql-java-tools.version}</version>
</dependency>
A schema definition:
in query.graphqls:
type Query {
user(username: String!)
users: [User]
}
in user.graphqls:
type User {
userId: Number!
username: String!
}
And a GraphQLQueryResolver for that:
@Component
public class UserQueryResolver implements GraphQLQueryResolver {
private final UserRepository userRepository;
public UserQueryResolver(UserRepository userRepository) {
this.userRepository = userRepository;
}
public Iterable<User> users() {
return this.userRepository.findAll();
}
public User user(String username) {
return this.userRepository.findByUsername(username).orElseThrow();
}
}
public interface UserRepository extends JpaRepository<User, Integer> {
Optional<User> findByUsername(String username);
}
According to the documentation:
>The servlet becomes accessible at /graphql if graphql-spring-boot-starter added as a dependency to a boot application and a GraphQLSchema bean is present in the application. Check out the simple example for the bare minimum required.
>A GraphQL schema can also be automatically created when a supported graphql-java schema library is found on the classpath.
The graphql-java-tools library should automatically create a schema, under these conditions:
> All GraphQLResolver and GraphQLScalar beans, along with a bean of type SchemaParserDictionary (to provide all other classes), will be used to create a GraphQLSchema. Any files on the classpath named *.graphqls will be used to provide the schema definition. See the Readme for more info.
I think I have everything it needs, but navigating to localhost:8080/graphql
gives a 404.
N.B.: localhost:8080/graphiql
works, but it cannot load the schema. It says:
{
"timestamp": "2020-09-15T12:22:21.748+00:00",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/graphql"
}
What am I missing?
答案1
得分: 0
显然应用程序无法找到任何JpaRepositories,因为SpringBootApplication的启动类位于com.package.some.app,而repositories位于com.package.some.domain.repositories。组件扫描器仅扫描具有包名*com.package.som.app.*的组件。
英文:
Apparently the application could not find any JpaRepositories, because the SpringBootApplication starter class was located in com.package.some.app while the repositories were in com.package.some.domain.repositories. The Component scanner was only scanning components with package com.package.som.app.*
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论