Creating a RESTful web service
In Spring Boot, all the HTTP requests are handled by controller classes. To be able to create a RESTful web service, first, we have to create a controller class. We will create our own Java package for our controller:
- Activate the root package in the Eclipse Project Explorer and right-click. Select New | Package from the menu. We will name our new package com.packt.cardatabase.web:
- Next, we will create a new controller class in a new web package. Activate the com.packt.cardatabase.web package in the Eclipse project explorer and right-click. Select New | Class from the menu. We will name our class CarController:
- Now, your project structure should look like the following screenshot:
If you create classes in a wrong package accidentally, you can drag and drop the files between packages in the Eclipse Project Explorer. Sometimes, the Eclipse Project Explorer view might not be rendered correctly when you make some changes. Refreshing the project explorer helps (Activate Project Explorer and press F5).
- Open your controller class in the editor window and add the @RestController annotation before the class definition. See the following source code. The @RestController annotation identifies that this class will be the controller for the RESTful web service:
package com.packt.cardatabase.web;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CarController {
}
- Next, we add a new method inside our controller class. The method is annotated with the @RequestMapping annotation, which defines the endpoint that the method is mapped to. Following, you can see the sample source code. In this example, when a user navigates to the /cars endpoint, the getCars() method is executed:
package com.packt.cardatabase.web;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CarController {
@RequestMapping("/cars")
public Iterable<Car> getCars() {
}
}
The getCars() method returns all the car objects, which are then marshalled to JSON objects by Jackson library.
By default, @RequestMapping handles all the HTTP method (GET, PUT, POST, and more) requests. You can define which method is accepted with the following @RequestMapping("/cars", method=GET) parameter. Now, this method handles only GET requests from the /cars endpoint.
- To be able to return cars from the database, we have to inject our CarRepository into the controller. Then, we can use the findAll() method that the repository provides to fetch all cars. The following source code shows the controller code:
package com.packt.cardatabase.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.packt.cardatabase.domain.Car;
import com.packt.cardatabase.domain.CarRepository;
@RestController
public class CarController {
@Autowired
private CarRepository repository;
@RequestMapping("/cars")
public Iterable<Car> getCars() {
return repository.findAll();
}
}
- Now, we are ready to run our application and navigate to localhost:8080/cars. We can see that there is something wrong, and the application seems to be in an infinite loop. That happens due to our one-to-many relationship between the car and owner tables. So, what happens in practice—first, the car is serialized, and it contains an owner that is then serialized, and that, in turn, contains cars that are then serialized... and so on. To avoid this, we have to add the @JsonIgnore annotation to the cars field in the Owner class:
// Owner.java
@OneToMany(cascade = CascadeType.ALL, mappedBy="owner")
@JsonIgnore
private List<Car> cars;
- Now, when you run the application and navigate to localhost:8080/cars , everything should go as expected and you will get all the cars from the database in JSON format, as shown in the following screenshot:
We have done our first RESTful web service, which return all the cars. Spring Boot provides a much more powerful way of creating RESTful Web Services and this is investigated in the next topic.