random12524345
random12524345

Reputation: 99

How to setup multiple Graphql files while using spring boot?

I am trying to use a graphql file per object in a project and am unsure how to set them up properly. I keep receiving an error, I have looked over many GitHub repos but haven't found anything that fixes it. I seems like it thinks both movie and theater should have the createUser methods but I am not sure why.

 Caused by: com.coxautodev.graphql.tools.FieldResolverError: No method found with any of the following signatures (with or without graphql.schema.DataFetchingEnvironment as the last argument), in priority order:
  com.****.****.resolvers.mutations.MovieMutation.createUser(~name, ~username, ~password)
  com.****.****.resolvers.mutations.MovieMutation.getCreateUser(~name, ~username, ~password)
  com.****.****.resolvers.mutations.TheaterMutation.createUser(~name, ~username, ~password)
  com.****.****.resolvers.mutations.TheaterMutation.getCreateUser(~name, ~username, ~password)

Here are my current files:

users.graphqls

schema {
    query: Query
    mutation: Mutation
}

type User {
    id: ID
    name: String
    username: String
    password: String
}

type Query {
    users: [User]
}

type Mutation {
    createUser(name: String!, username: String!, password: String!): User!
    updateUser(id: ID!, name: String!, username: String!, password: String!): User!
    deleteUser(id: ID!): Boolean
}

theaters.graphqls

type Theater {
    id: ID
    name: String
    location: String
}

extend type Query {
    theaters: [Theater]
}

extend type Mutation {
    createTheater(name: String!, location: String!): Theater!
    updateTheater(id: ID!, name: String!, location: String!): Theater!
    deleteTheater(id: ID!): Boolean
}

movies.graphqls

type Movie {
    id: ID
    title: String
    length: Int
}

extend type Query {
    movies: [Movie]
}

extend type Mutation {
    createMovie(title: String!, length: Int!): Movie!
    updateMovie(id: ID!, title: String!, length: Int!): Movie!
    deleteMovie(id: ID!): Boolean
}

All my repositories look like this:

MovieRepository.java

import com.****.****.models.Movie;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MovieRepository extends JpaRepository<Movie, Long> {
}

All my Queries look like this

import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import com.****.****.models.Movie;
import com.****.****.repositories.MovieRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@RequiredArgsConstructor
public class MovieQuery implements GraphQLQueryResolver {

    private final MovieRepository movieRepository;

    public List<Movie> movies() {
        return movieRepository.findAll();
    }
}

and here is my service

MovieService.java

import com.****.****.models.Movie;
import com.****.****.repositories.MovieRepository;
import javassist.NotFoundException;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Service
@AllArgsConstructor
public class MovieService {

    private MovieRepository movieRepository;

    @Transactional
    public Movie createMovie(String title, int length) {
        Movie movie = new Movie();
        movie.setTitle(title);
        movie.setLength(length);
        movieRepository.save(movie);
        return movie;
    }

    @Transactional(readOnly = true)
    public List<Movie> movies(){
        return movieRepository.findAll();
    }

    @Transactional
    public boolean deleteById(long id) {
        movieRepository.deleteById(id);
        return true;
    }

    @Transactional
    public Movie updateMovie(long id, String title, int length) throws NotFoundException {
        Optional<Movie> optionalMovie = movieRepository.findById(id);

        if (optionalMovie.isPresent()) {
            Movie movie = optionalMovie.get();

            if (title != null) {
                movie.setTitle(title);
            }
            if(length > 0) {
                movie.setLength(length);
            }

            movieRepository.save(movie);
            return movie;
        }

        throw new NotFoundException("No found movie to update!");
    }
}

MovieMutation.java

import com.coxautodev.graphql.tools.GraphQLMutationResolver;
import com.****.****.models.Movie;
import com.****.****.service.MovieService;
import javassist.NotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MovieMutation implements GraphQLMutationResolver {

    @Autowired
    private MovieService movieService;

    public Movie createMovie(String title, int length) {
        return movieService.createMovie(title, length);
    }

    public boolean deleteMovie(long id) {
        movieService.deleteById(id);
        return true;
    }

    public Movie updateMovie(long id, String title, int length) throws NotFoundException {
        return movieService.updateMovie(id, title, length);
    }
}

TheaterMutation.java

import com.coxautodev.graphql.tools.GraphQLMutationResolver;
import com.****.****.models.Theater;
import com.****.****.service.TheaterService;
import javassist.NotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class TheaterMutation implements GraphQLMutationResolver {

    @Autowired
    private TheaterService theaterService;

    public Theater createTheater(String name, String location) {
        return theaterService.createTheater(name, location);
    }

    public boolean deleteTheater(long id) {
        theaterService.deleteById(id);
        return true;
    }

    public Theater updateTheater(long id, String name, String location) throws NotFoundException {
        return theaterService.updateTheater(id, name, location);
    }
}

Upvotes: 3

Views: 2468

Answers (1)

D. Lawrence
D. Lawrence

Reputation: 949

Your initial mutation is defined like that:

type Mutation {
    createUser(name: String!, username: String!, password: String!): User!
    updateUser(id: ID!, name: String!, username: String!, password: String!): User!
    deleteUser(id: ID!): Boolean
}

The important line to take into account to understand the problem here is createUser(name: String!, username: String!, password: String!): User!.

Your error message should be therefore self-explanatory. Graphql is trying to resolve a method with the following signature createUser(~name, ~username, ~password) in any of your registered GraphQLMutationResolver. However, he cannot find it and therefore fails to start.

You must add this method somewhere. In fact, you should add implementations for all these methods. I recommend doing the following:

import com.coxautodev.graphql.tools.GraphQLMutationResolver;
import javassist.NotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class DefaultMutation implements GraphQLMutationResolver {

    public User createUser(String name, String username, String password) {
        // Implement your logic here
    }

    public User updateUser(String id, String name, String username, String password) {
        // Implement your logic here
    }

    public Boolean deleteUser(String id) {
        // Implement your logic here
    }    
}

Upvotes: 1

Related Questions