类型为FieldUndefined的验证错误:类型为“查询”的字段“注册”未定义
我是GrapQL的新手。我正在尝试将其与Spring
Boot配合使用。我可以成功进行查询,它正在返回我需要的数据,但是现在我想使用突变。我需要在他注册时在数据库中添加一个用途。
这是我的schema.graphqls文件:
type Token { token: String
}
type Register {
message: String
}
type User {
username: String!
firstName: String!
lastName: String!
password: String!
role: String!
}
type Query {
login(username: String, password: String): Token
}
type Mutation {
register(input: RegisterUserInput!): Register
}
input RegisterUserInput {
username: String!
firstName: String!
lastName: String!
password: String!
role: String!
}
schema {
query: Query
mutation: Mutation
}
如您所见,寄存器是Mutation类型的,与Query一样添加到架构中。但是由于某种原因,它似乎没有进入Mutation,它只是试图在Query中查找类型。
这是我的控制器:
@Autowired private UserService userService;
/**
* Login the user and return generated token
* @param query
* @return String token
*/
@PostMapping("/login")
public ResponseEntity<Object> login(@RequestBody String query){
ExecutionResult executionResult = userService.getGraphQL().execute(query);
// Check if there are errors
if(!executionResult.getErrors().isEmpty()){
return new ResponseEntity<>(executionResult.getErrors().get(0).getMessage(), HttpStatus.UNAUTHORIZED);
}
return new ResponseEntity<>(executionResult, HttpStatus.OK);
}
/**
* Create new user and save him to database
* @param mutation
* @return String message
*/
@PostMapping("/register")
public ResponseEntity<Object> register(@RequestBody String mutation){
ExecutionResult executionResult = userService.getGraphQL().execute(mutation);
// Check if there are errors
if(!executionResult.getErrors().isEmpty()){
return new ResponseEntity<>(executionResult.getErrors().get(0).getMessage(), HttpStatus.UNAUTHORIZED);
}
return new ResponseEntity<>(executionResult, HttpStatus.OK);
}
正如我所说的,登录工作正常,但是注册返回了我在标题中提到的错误。
我的服务等级:
@Value("classpath:graphql-schema/schema.graphqls") Resource resource;
private GraphQL graphQL;
@Autowired
private LoginDataFetcher loginDataFetcher;
@Autowired
private RegisterDataFetcher registerDataFetcher;
@PostConstruct
public void loadSchema() throws IOException{
// Get the schema
File schemaFile = resource.getFile();
// Parse schema
TypeDefinitionRegistry typeDefinitionRegistry = new SchemaParser().parse(schemaFile);
RuntimeWiring runtimeWiring = buildRuntimeWiring();
GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, runtimeWiring);
graphQL = GraphQL.newGraphQL(graphQLSchema).build();
}
private RuntimeWiring buildRuntimeWiring() {
return RuntimeWiring.newRuntimeWiring()
.type("Query", typeWiring ->
typeWiring
.dataFetcher("login", loginDataFetcher))
.type("Mutation", typeWiring ->
typeWiring
.dataFetcher("register", registerDataFetcher))
.build();
}
public GraphQL getGraphQL() {
return graphQL;
}
我的LoginDataFetcher:
@Autowired private AppUserRepository appUserRepository;
private JwtGenerator jwtGenerator;
public LoginDataFetcher(JwtGenerator jwtGenerator) {
this.jwtGenerator = jwtGenerator;
}
@Override
public TokenDAO get(DataFetchingEnvironment dataFetchingEnvironment) {
String username = dataFetchingEnvironment.getArgument("username");
String password = dataFetchingEnvironment.getArgument("password");
AppUser appUser = appUserRepository.findByUsername(username);
// If user is not foung
if(appUser == null){
throw new RuntimeException("Username does not exist");
}
// If the user is fount check passwords
if(!appUser.getPassword().equals(password)){
throw new RuntimeException("Incorrect password");
}
// Generate the token
String token = jwtGenerator.generate(appUser);
return new TokenDAO(token);
}
RegisterDataFetcher:
@Autowired private AppUserRepository appUserRepository;
@Override
public RegisterDAO get(DataFetchingEnvironment dataFetchingEnvironment) {
String username = dataFetchingEnvironment.getArgument("username");
String firstName = dataFetchingEnvironment.getArgument("firstName");
String lastName = dataFetchingEnvironment.getArgument("lastName");
String password = dataFetchingEnvironment.getArgument("password");
String role = dataFetchingEnvironment.getArgument("role");
AppUser appUser = appUserRepository.findByUsername(username);
// Check if username exists
if(appUser != null){
throw new RuntimeException("Username already taken");
}
AppUser newAppUser = new AppUser(username, password, role, firstName, lastName);
// Save new user
appUserRepository.save(newAppUser);
return new RegisterDAO("You have successfully registered");
}
我在控制台中遇到的错误:
graphql.GraphQL : Query failed to validate : '{ register(username: "user", firstName: "Bla", lastName: "Blabla", password: "password", role: "DEVELOPER") {
message
}
}'
感谢您的帮助。
回答:
我根据得到的答案像这样更改了架构文件:
query UserQuery{ login(username: String, password: String){
token
}
}
mutation UserMutation{
register(input: RegisterUserInput) {
message
}
}
input RegisterUserInput {
username: String!
firstName: String!
lastName: String!
password: String!
role: String!
}
schema {
query: UserQuery
mutation: UserMutation
}
但是现在我得到这个错误:
解决类型“查询”时不存在操作类型“ UserQuery”解决类型“突变”时不存在操作类型“ UserMutation”
那么,现在有什么问题呢?我该如何进行这项工作?
回答:
您是在告诉GraphQL您正在请求查询,而实际上register
是一个Mutation。编写GraphQL请求时,语法通常遵循以下格式进行查询:
query someOperationName { login {
# other fields
}
}
编写突变时,您只需指定以下内容即可:
mutation someOperationName { register {
# other fields
}
}
您可以省略操作名称,尽管包括它是一种很好的做法。您可能会看到以下格式的示例:
{ someQuery {
# other fields
}
}
在这种情况下,操作 名称 和操作 类型
(查询与突变)都将保留。这仍然是一个有效的请求,因为GraphQL只是假设您的意思是query
您省略了操作类型。从规格:
如果文档仅包含一个操作,则该操作可能未命名或以简写形式表示,从而省略了查询关键字和操作名称。
因此,在您的请求中,GraphQL假定register
是一个查询,而实际上是一个突变,并且结果将返回错误。
同样,在编写请求时,最好同时包含操作名称和查询/变异关键字。
以上是 类型为FieldUndefined的验证错误:类型为“查询”的字段“注册”未定义 的全部内容, 来源链接: utcz.com/qa/416353.html