The ultimate Spring Boot Rest API beginners guide Part 2 - Implementation
<- Back to The ultimate Spring Boot REST API beginners guide Part 1
This part of The ultimate Spring Boot REST API beginners guide will deal with coding. We'll first create a class Item that contains fields id and name. Id field will be auto-generated so we put appropriate annotations there. We should also generate getters and setters for these fields.
Model
package com.example.demo.model;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Item implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Controller
The Controller is intended for client communication. It contains endpoint definitions. It's important that this class is annotated with @RestController. You'll see that methods are annotated with @GetMapping or @PostMapping - they represent HTTP methods you should use to access these endpoints. These annotations contain also the URL to your service.
If you're not familiar with Spring, @Autowired annotation will be new to you. It's used to implicitly inject the dependency object.
package com.example.demo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.model.Item;
import com.example.demo.service.ItemService;
import javassist.NotFoundException;
@RestController
public class ItemController {
@Autowired
ItemService itemService;
@GetMapping("/api/items")
public List<Item> getAllItems() {
return itemService.getAllItems();
}
@PostMapping("/api/items")
public Item createItem(@RequestBody Item item) {
return itemService.createItem(item);
}
@GetMapping("/api/items/{id}")
public Item getItemById(@PathVariable(name = "id") Long id) throws NotFoundException {
return itemService.findItemById(id);
}
}
Service
ItemService class will have @Service annotation which is used to annotate classes on the service layer. We'll inject the repository class here and call its methods.
package com.example.demo.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.demo.model.Item;
import com.example.demo.repository.ItemRepository;
import javassist.NotFoundException;
@Service
public class ItemService {
@Autowired
ItemRepository itemRepository;
public List<Item> getAllItems() {
return itemRepository.findAll();
}
public Item createItem(Item item) {
return itemRepository.save(item);
}
public Item findItemById(Long id) throws NotFoundException {
return itemRepository.findById(id)
.orElseThrow(() -> new NotFoundException("Item with id " + id + " not found."));
}
}
Repository
Repository is intended for database communication and it needs to be annotated with @Repository. If you extend JpaRepository, you'll have a lot of things that are already implemented and you can usually write just a name of method, that follows certain rules and you don't need to add specific queries (for example findByName(String name) will search database for row containing provided name). In case that your query is too complicated for this,
package com.example.demo.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.demo.model.Item;
@Repository
public interface ItemRepository extends JpaRepository<Item, Long> {
}
In properties, we mostly set up the database communication params. The most important is spring.datasource.url that represents the URL of the database. spring.datasource.username and spring.datasource.password are self-explanatory. You should also specify spring.jpa.properties.hibernate.dialect and spring.jpa.hibernate.ddl-auto that will tell your app if there's something to be done with the database before application start (e.g. should it delete the database and create it again, just update it with new changes on entities, or do something else). The complete reference for Spring Data JPA could be found here.
A detailed tutorial on Spring application.properties params could be found here.
spring.datasource.url= jdbc:mysql://localhost:3306/itemsdb?useSSL=false
spring.datasource.username= testuser
spring.datasource.password= test123.
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.show_sql = true
spring.jpa.properties.hibernate.format_sql= true
spring.jpa.properties.hibernate.type= trace
spring.jpa.show-sql= true
spring.jpa.hibernate.ddl-auto= update
Run this application with right-click on the project -> Run as... -> Spring Boot application. The application will run on default port 8080 if it's not configured otherwise. One of the ways to change default Spring Boot port is to add parameter server.port= yourPort in application.properties. Use Postman to test your newly created endpoints. If you're not sure how Postman works, check out the video guide at the end of this article.
Project code is available on gitHub.
If you missed some step in this tutorial, there is a complete video guide.