Creating Movie repository and controller classes

You have mapped the Movie and Person entities in the data domain. Now you need a Movie repository interface and controller class to access the movies in the database.

Movie repository interface

Start by creating a new file called MovieRepository.java in the src/main/java/com/example/appspringdata directory, choose interface as the type, and extend it to match the following:

java
import org.springframework.data.neo4j.repository.Neo4jRepository;

interface MovieRepository extends Neo4jRepository<Movie, String> {
}

Spring Data provides repository extensions for many of its supported projects. They include methods and functionality specifically designed and optimized for the data store. In this case, you extend the Neo4jRepository interface. The first type parameter is the domain class that the repository will be working with, and the second type parameter is the type of the identifier for that domain class. In this case, the Movie domain class is the entity you want to return and the String type is its identifier.

Spring Data Neo4j also implements a few standard methods, such as save, findById, findAll, and deleteById. This is why you don’t need to define queries and methods to start out. You will see how to define custom implementations later in this course.

Moving on to the controller class, you will expose the query results with an API.

Movie controller class

Open the src/main/java/com/example/appspringdata directory and create a new class file called MovieController.java. Then add code for the following:

  1. Add @RestController and @RequestMapping("/movies") annotations above the class definition.

  2. Just inside the class, inject the repository interface with a field called movieRepo.

  3. Create a constructor and inject the repository.

  4. Define two methods to handle GET requests:

    • The first method (name it findAllMovies) will handle requests to the main (/movies) endpoint and return a list of movies, calling the movieRepo.findAll() method.

    • The second method (name it findMovieById) will handle requests to the /{movieId} endpoint and return a single movie, calling the movieRepo.findById(movieId) method.

Completed code is available below to check your own work.

Click to reveal the completed MovieController class code
java
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@RestController
@RequestMapping("/movies")
public class MovieController {
    private final MovieRepository movieRepo;

    public MovieController(MovieRepository movieRepo) {
        this.movieRepo = movieRepo;
    }

    @GetMapping
    Iterable<Movie> findAllMovies() {
        return movieRepo.findAll();
    }

    @GetMapping("/{movieId}")
    Optional<Movie> findMovieById(@PathVariable String movieId) {
        return movieRepo.findById(movieId);
    }
}

You created a standard Spring MVC controller class, annotating it with @RestController to handle requests and responses and @RequestMapping to handle requests at the /movies endpoint. Injecting the repository interface allows access to call any repository methods, with the constructor taking a MovieRepository instance as a parameter. This is called dependency injection and is a standard practice in Spring applications.

You defined two methods to handle requests. The first method is annotated with @GetMapping and will handle requests to the /movies endpoint. It calls one of the out-of-the-box methods that Spring provides, the derived findAll method and returns a list of movies. The second method will handle requests to the /movies/{movieId} endpoint, including a path variable in the URL for a distinct movie id. It calls the derived findById method on the repository (passing in the path variable value) and returns the results.

Check Your Understanding

1. Spring derived methods

What is the reason you did not define queries and methods in the MovieRepository interface?

  • ❏ You don’t need to access the database.

  • ❏ You can’t define queries and methods in the repository interface.

  • ✓ Spring provides a few derived methods out-of-the-box (findAll, findById, save, deleteById).

Hint

Methods such as findAll, findById, save, and deleteById are often standard across implementations, so Spring Data provides them out-of-the-box, avoiding boilerplate redundancy. Side note: Custom implementations can also be defined when needed.

Solution

The answer is that Spring provides a few derived methods out-of-the-box (such as findAll, findById, etc). This is why you don’t need to define queries and methods to start out because Spring Data implements them by default.

Summary

In this lesson, you created a repository interface and controller class to access Movie entities.

Next, you will run the application and test it out.