首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类型FieldUndefined的验证错误:类型'Query‘中的字段'register’未定义

类型FieldUndefined的验证错误:类型'Query‘中的字段'register’未定义
EN

Stack Overflow用户
提问于 2018-02-25 08:02:42
回答 1查看 23.3K关注 0票数 7

我是GrapQL的新手。我正试着把它和弹力靴一起使用。我可以成功地进行查询,它返回了我需要的数据,但我想现在使用突变。当他注册时,我需要向数据库添加一个用途。

这是我的schema.graphqls文件:

代码语言:javascript
复制
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
}

因此,正如您所看到的,寄存器是突变类型,它是按查询方式添加到模式中的。但由于某些原因,它看起来不会发生突变,它只是试图在查询中找到类型。

这是我的控制器:

代码语言:javascript
复制
@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);
}

正如我所说的,登录工作正常,但注册返回了我在标题中提到的错误。

我的服务类:

代码语言:javascript
复制
@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:

代码语言:javascript
复制
@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:

代码语言:javascript
复制
@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");
    }

我在控制台中看到的错误:

代码语言:javascript
复制
graphql.GraphQL                          : Query failed to validate : '{
    register(username: "user", firstName: "Bla", lastName: "Blabla", password: "password", role: "DEVELOPER") {
        message
    }
}'

谢谢你的帮助。

更新

根据我得到的答案,我像这样修改了我的模式文件:

代码语言:javascript
复制
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
}

但是现在我得到了这个错误:

解析类型“”query“”时不存在操作类型“”UserQuery“”。解析类型“”query“”时不存在操作类型“”UserMutation“

那么现在的问题是什么呢?我怎么才能让它工作呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-25 10:58:52

您告诉GraphQL您正在请求一个查询,而实际上register是一个突变。编写GraphQL请求时,查询语法通常遵循以下格式:

代码语言:javascript
复制
query someOperationName {
  login {
    # other fields
  }
}

在编写突变时,您只需简单地指定:

代码语言:javascript
复制
mutation someOperationName {
  register {
    # other fields
  }
}

您可以省略操作名称,但最好将其包括在内。您可能会看到以下格式的示例:

代码语言:javascript
复制
{
  someQuery {
    # other fields
  }
}

在这种情况下,操作名称和操作类型(查询与突变)都被省略了。这仍然是一个有效的请求,因为当您去掉操作类型时,GraphQL只是假设您指的是query。从规范中:

如果文档只包含一个操作,则该操作可以是未命名的,也可以用速记形式表示,这将省略查询关键字和操作名称。

因此,在您的请求中,GraphQL假设register是一个查询,而实际上它是一个突变,并返回一个错误作为结果。

同样,在编写请求时,最好始终同时包含操作名称和查询/突变关键字。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48968896

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档