{"id":36,"date":"2020-09-13T10:54:48","date_gmt":"2020-09-13T10:54:48","guid":{"rendered":"http:\/\/localhost\/?p=36"},"modified":"2020-10-03T10:38:47","modified_gmt":"2020-10-03T10:38:47","slug":"how-to-create-restful-api-with-springboot-2-spring-data-jpa-and-hibernate-with-mysql-as-database","status":"publish","type":"post","link":"https:\/\/ranjeshviswa.com\/?p=36","title":{"rendered":"Create a REST API with Spring Boot"},"content":{"rendered":"\r\n<p>Spring Boot is an open source Java -based framework, used to build stand-alone and production ready spring applications.<\/p>\r\n<p>In this article, we will show you how to build simple REST API from scratch using Spring Boot 2.2.9, Spring Data JPA\/Hibernate with MySQL as database.<\/p>\r\n<h2>Requirement<\/h2>\r\n<p>We need to create a simple REST API\u00a0 to create, update, delete and get Users and its corresponding\u00a0 purchased Orders.<\/p>\r\n<h2>Maven dependencies<\/h2>\r\n<pre>&lt;dependencies&gt;<br \/>    &lt;!--Web-Basic dependencies--&gt;<br \/>    &lt;dependency&gt;<br \/>        &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br \/>        &lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;<br \/>    &lt;\/dependency&gt;<br \/><br \/>    &lt;!--Spring Data JPA--&gt;<br \/>    &lt;dependency&gt;<br \/>        &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br \/>        &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;\/artifactId&gt;<br \/>    &lt;\/dependency&gt;<br \/><br \/>    &lt;!--MYSQL --&gt;<br \/>    &lt;dependency&gt;<br \/>        &lt;groupId&gt;mysql&lt;\/groupId&gt;<br \/>        &lt;artifactId&gt;mysql-connector-java&lt;\/artifactId&gt;<br \/>    &lt;\/dependency&gt;<br \/><br \/>    &lt;!--Model mapper --&gt;<br \/>    &lt;dependency&gt;<br \/>        &lt;groupId&gt;org.modelmapper&lt;\/groupId&gt;<br \/>        &lt;artifactId&gt;modelmapper&lt;\/artifactId&gt;<br \/>        &lt;version&gt;2.3.2&lt;\/version&gt;<br \/>    &lt;\/dependency&gt;<br \/><br \/>    &lt;!--Spring Boot test--&gt;<br \/>    &lt;dependency&gt;<br \/>        &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br \/>        &lt;artifactId&gt;spring-boot-starter-test&lt;\/artifactId&gt;<br \/>        &lt;scope&gt;test&lt;\/scope&gt;<br \/>        &lt;exclusions&gt;<br \/>            &lt;exclusion&gt;<br \/>                &lt;groupId&gt;junit&lt;\/groupId&gt;<br \/>                &lt;artifactId&gt;junit&lt;\/artifactId&gt;<br \/>            &lt;\/exclusion&gt;<br \/>        &lt;\/exclusions&gt;<br \/>    &lt;\/dependency&gt;<br \/><br \/>    &lt;!--Junit 5--&gt;<br \/>    &lt;dependency&gt;<br \/>        &lt;groupId&gt;org.junit.jupiter&lt;\/groupId&gt;<br \/>        &lt;artifactId&gt;junit-jupiter-api&lt;\/artifactId&gt;<br \/>        &lt;scope&gt;test&lt;\/scope&gt;<br \/>    &lt;\/dependency&gt;<br \/>    &lt;dependency&gt;<br \/>        &lt;groupId&gt;org.junit.jupiter&lt;\/groupId&gt;<br \/>        &lt;artifactId&gt;junit-jupiter-engine&lt;\/artifactId&gt;<br \/>        &lt;scope&gt;test&lt;\/scope&gt;<br \/>    &lt;\/dependency&gt;<br \/><br \/>    &lt;!-- In Memory database useful for unit testing--&gt;<br \/>    &lt;dependency&gt;<br \/>        &lt;groupId&gt;com.h2database&lt;\/groupId&gt;<br \/>        &lt;artifactId&gt;h2&lt;\/artifactId&gt;<br \/>        &lt;scope&gt;test&lt;\/scope&gt;<br \/>    &lt;\/dependency&gt;<br \/><br \/>&lt;\/dependencies&gt;<\/pre>\r\n<h2>Three Layers of Rest Service<\/h2>\r\n<h3><img loading=\"lazy\" class=\"alignnone size-full wp-image-96\" src=\"http:\/\/ranjeshviswa.com\/wp-content\/uploads\/2020\/09\/RestAPIImage.png\" alt=\"\" width=\"554\" height=\"98\" \/><\/h3>\r\n<h3>Controller Layer<\/h3>\r\n<p>It is top most layer and it receives request from client and invokes service layer. The result from service layer is processed and response is sent back to client.<\/p>\r\n<h3>Service Layer<\/h3>\r\n<p>It is middle layer and is called by Controller layer. It does business operation and calls lowermost data layer.<\/p>\r\n<h3>Data \/ Persistence \/ Repository Layer<\/h3>\r\n<p>This layer does all interaction\u00a0 with underlying database.<\/p>\r\n<h2>Create Data \/ Persistence \/ Repository Layer<\/h2>\r\n<p>Implementing persistence \/data layer in Spring is very simple and is two step process.<\/p>\r\n<h3>1. Create Entity Class for User and Order<\/h3>\r\n<pre>@Entity(name = \"users\")<br \/>public class User implements Serializable {<br \/><br \/>    private static final long serialVersionUID = -465L;<br \/><br \/>    @Id<br \/>    @GeneratedValue<br \/>    private Long id;<br \/><br \/>    @Column(nullable = false, length = 50)<br \/>    private String firstName;<br \/><br \/>    @Column(nullable = false, length = 50)<br \/>    private String lastName;<br \/><br \/>    @Column(nullable = false, length = 120)<br \/>    private String email;<br \/><br \/>    @Column(nullable = false, length = 50)<br \/>    private String firstLineOfAddress;<br \/><br \/>    @Column(length = 50)<br \/>    private String secondLineOfAddress;<br \/><br \/>    @Column(nullable = false, length = 50)<br \/>    private String town;<br \/><br \/>    @Column(nullable = false, length = 10)<br \/>    private String postCode;<br \/>    \/\/ Getters and Setters(Omitted for brevity)<br \/>}<\/pre>\r\n<pre>@Entity(name = \"orders\")<br \/>public class Order implements Serializable {<br \/><br \/>    private static final long serialVersionUID = -466L;<br \/><br \/>    @Id<br \/>    @GeneratedValue<br \/>    private Long id;<br \/><br \/>    @Column(nullable = false, length = 120)<br \/>    private String description;<br \/><br \/>    @Column(nullable = false, length = 120)<br \/>    private long priceInPence;<br \/><br \/>    @Column(nullable = false)<br \/>    private boolean completedStatus = false;<br \/><br \/>    @ManyToOne(fetch = FetchType.LAZY, optional = false)<br \/>    @JoinColumn(name = \"user_id\", nullable = false)<br \/>    @OnDelete(action = OnDeleteAction.CASCADE)<br \/>    @JsonIgnore<br \/>    private User user;<br \/>    \/\/ Getters and Setters(Omitted for brevity)<br \/>}<\/pre>\r\n<p>Above annotations are basically JPA annotations.<br \/><code class=\"ir jm jn jo ja b\"><strong class=\"gz ia\">@Entity(name = \u201cusers\u201d)<\/strong><\/code><strong class=\"gz ia\">\u00a0<\/strong>tells that data contained in class will be stored in database table \u201cusers\u201d<br \/><code class=\"ir jm jn jo ja b\"><strong class=\"gz ia\">@Column(nullable = false, length = 50)<\/strong><\/code>\u00a0Indicates column name used in database table. Length indicates permitted column length in table.<br \/>Nullable indicates if the column in table can be null or not. Because every user may not have second line of address, we made this field nullable<br \/>Domain objects are sometimes stored in http-session for caching\/optimisation purpose, hence making the object\u00a0<code class=\"ir jm jn jo ja b\"><strong class=\"gz ia\">Serializable<\/strong><\/code>\u00a0is a good practice.<br \/><code class=\"ir jm jn jo ja b\"><strong class=\"gz ia\">serialVersionUID<\/strong><\/code><strong class=\"gz ia\">\u00a0<\/strong>is usually very big long number.<\/p>\r\n<p><code class=\"ir jm jn jo ja b\"><strong class=\"gz ia\">@ManyToOne(fetch = FetchType.LAZY, optional = false)<\/strong><\/code>\u00a0indicates User to Order is many to one mapping, which means a user can have zero<br \/>or many orders. But one order can belong to one user only.<br \/><code class=\"ir jm jn jo ja b\"><strong class=\"gz ia\">@JoinColumn(name = \u201cuser_id\u201d, nullable = false)<\/strong><\/code>\u00a0indicates Order table will have user_id column which will reference id of users table<br \/><code class=\"ir jm jn jo ja b\"><strong class=\"gz ia\">@OnDelete(action = OnDeleteAction.CASCADE)<\/strong><\/code>\u00a0indicates that parent user row is deleted in users table, corresponding order row will also<br \/>be deleted in the orders table<br \/><code class=\"ir jm jn jo ja b\"><strong class=\"gz ia\">@JsonIgnore<\/strong><\/code>\u00a0is used to hide the field, when order is serialised into json response body , which is sent to client. We don\u2019t want user details in<br \/>order response body<\/p>\r\n<h3>2. Create Repository Interface for User and Order<\/h3>\r\n<pre>@Repository<br \/>public interface UserRepository extends CrudRepository&lt;User, Long&gt; {<br \/>    Optional&lt;User&gt; findByEmail(String email);<br \/>}<\/pre>\r\n<pre>@Repository<br \/>public interface OrderRepository extends CrudRepository&lt;Order, Long&gt; {<br \/>    Optional&lt;Order&gt; findByIdAndUserId(Long id, Long userId);<br \/>    List&lt;Order&gt; findAllByUser(User user);<br \/>}<\/pre>\r\n<p id=\"d113\" class=\"gx gy dm gz b ha hv hc hd he hw hg hh hi hx hk hl hm hy ho hp hq hz hs ht hu de cf\" data-selectable-paragraph=\"\">Spring will automatically implement above interface.<\/p>\r\n<p id=\"62e9\" class=\"gx gy dm gz b ha hv hc hd he hw hg hh hi hx hk hl hm hy ho hp hq hz hs ht hu de cf\" data-selectable-paragraph=\"\"><code class=\"ir jm jn jo ja b\"><strong class=\"gz ia\">@Repository<\/strong><\/code> is Spring annotation to indicate that it is data layer.<\/p>\r\n<p id=\"78c4\" class=\"gx gy dm gz b ha hv hc hd he hw hg hh hi hx hk hl hm hy ho hp hq hz hs ht hu de cf\" data-selectable-paragraph=\"\"><code class=\"ir jm jn jo ja b\"><strong class=\"gz ia\">findByEmail<\/strong><\/code> finds User by its email field.<\/p>\r\n<p id=\"76ad\" class=\"gx gy dm gz b ha hv hc hd he hw hg hh hi hx hk hl hm hy ho hp hq hz hs ht hu de cf\" data-selectable-paragraph=\"\"><code class=\"ir jm jn jo ja b\"><strong class=\"gz ia\">findByIdAndUserId<\/strong><\/code><strong class=\"gz ia\">\u00a0<\/strong>returns order by OrderId and UserId<\/p>\r\n<p id=\"d1f3\" class=\"gx gy dm gz b ha hv hc hd he hw hg hh hi hx hk hl hm hy ho hp hq hz hs ht hu de cf\" data-selectable-paragraph=\"\"><code class=\"ir jm jn jo ja b\"><strong class=\"gz ia\">findAllByUser<\/strong><\/code>\u00a0returns order by user<\/p>\r\n<h2>Create Service Layer<\/h2>\r\n<p>It s good practice to implement service layer by \u201cprogramming to interface\u201d principle.<\/p>\r\n<h3>Service Interface<\/h3>\r\n<pre>public interface UserService {<br \/>    User createUser(User user);<br \/>    User updateUser(Long id, User user);<br \/>    User patchUpdateUser(Long id, User user);<br \/>    User getUserById(Long id);<br \/>    List&lt;User&gt; getUsers();<br \/>    void deleteUser(Long id);<br \/>}<br \/><br \/><\/pre>\r\n<pre>public interface OrderService {<br \/>    Order createOrder(Long userId, Order order);<br \/>    Order updateOrder(Long userId, Long orderId, Order order);<br \/>    Order patchUpdateOrder(Long userId, Long orderId, Order order);<br \/>    Order getOrder(Long userId, Long orderId);<br \/>    List&lt;Order&gt; getAllOrdersByUserId(Long userId);<br \/>    void deleteOrder(Long userId, Long orderId);<br \/>}<\/pre>\r\n<h3>Service Implementation<\/h3>\r\n<pre>@Service<br \/>public class UserServiceImpl implements UserService {<br \/><br \/>    @Autowired<br \/>    private UserRepository userRepository;<br \/><br \/>    @Override<br \/>    public User getUserById(Long id) {<br \/><br \/>        Optional&lt;User&gt; maybeUser = userRepository.findById(id);<br \/>        return maybeUser.orElseThrow(() -&gt; new RuntimeException(\"User not found\"));<br \/>    }<br \/><br \/>    @Override<br \/>    public User createUser(User user) {<br \/><br \/>        userRepository.findByEmail(user.getEmail())<br \/>                .ifPresent(p -&gt; {<br \/>                    throw new RuntimeException(\"User with email \" + p.getEmail() + \" already exists \");<br \/>                });<br \/>        return userRepository.save(user);<br \/><br \/>    }<br \/><br \/>    @Override<br \/>    public User updateUser(Long id, User user) {<br \/>        User userFound = userRepository.findById(id).orElseThrow(() -&gt; new RuntimeException(\"User not found\"));<br \/><br \/>        userFound.setFirstName(user.getFirstName());<br \/>        userFound.setLastName(user.getLastName());<br \/>        userFound.setEmail(user.getEmail());<br \/>        userFound.setFirstLineOfAddress(user.getFirstLineOfAddress());<br \/>        userFound.setSecondLineOfAddress(user.getSecondLineOfAddress());<br \/>        userFound.setTown(user.getTown());<br \/>        userFound.setPostCode(user.getPostCode());<br \/><br \/>        return userRepository.save(userFound);<br \/>    }<br \/><br \/>    @Override<br \/>    public User patchUpdateUser(Long id, User user) {<br \/>        User userFound = userRepository.findById(id).orElseThrow(() -&gt; new RuntimeException(\"User not found\"));<br \/><br \/>        ModelMapper modelMapper = new ModelMapper();<br \/>        \/\/copy only non null values<br \/>        modelMapper.getConfiguration().setSkipNullEnabled(true).setMatchingStrategy(MatchingStrategies.STRICT);<br \/><br \/>        modelMapper.map(user, userFound);<br \/><br \/>        return userRepository.save(userFound);<br \/>    }<br \/><br \/>    @Override<br \/>    public void deleteUser(Long id) {<br \/>        User userFound = userRepository.findById(id).orElseThrow(() -&gt; new RuntimeException(\"User not found\"));<br \/>        userRepository.delete(userFound);<br \/>    }<br \/><br \/>    @Override<br \/>    public List&lt;User&gt; getUsers() {<br \/>        Iterable&lt;User&gt; userIterable = userRepository.findAll();<br \/>        return StreamSupport.stream(userIterable.spliterator(), false)<br \/>                .collect(Collectors.toList());<br \/>    }<br \/>}<\/pre>\r\n<pre>@Service<br \/>public class OrderServiceImpl implements OrderService {<br \/><br \/>    @Autowired<br \/>    private OrderRepository orderRepository;<br \/><br \/>    @Autowired<br \/>    private UserRepository userRepository;<br \/><br \/>    @Override<br \/>    public Order createOrder(Long userId, Order order) {<br \/>        User user = userRepository.findById(userId)<br \/>                .orElseThrow(() -&gt; new RuntimeException(\"User with id \" + userId + \" Not found\"));<br \/><br \/>        order.setUser(user);<br \/><br \/>        return orderRepository.save(order);<br \/>    }<br \/><br \/>    @Override<br \/>    public Order getOrder(Long userId, Long orderId) {<br \/><br \/>        return orderRepository.findByIdAndUserId(orderId, userId)<br \/>                .orElseThrow(() -&gt; new RuntimeException(\"User with id \" + userId + \" and order id \" + orderId + \" Not found\"));<br \/>    }<br \/><br \/>    @Override<br \/>    public List&lt;Order&gt; getAllOrdersByUserId(Long userId) {<br \/><br \/>        User user = userRepository.findById(userId)<br \/>                .orElseThrow(() -&gt; new RuntimeException(\"User with id \" + userId + \" Not found\"));<br \/><br \/>        return orderRepository.findAllByUser(user);<br \/><br \/>    }<br \/><br \/>    @Override<br \/>    public Order updateOrder(Long userId, Long orderId, Order order) {<br \/>        Order orderFound = orderRepository.findByIdAndUserId(orderId, userId)<br \/>                .orElseThrow(() -&gt; new RuntimeException(\"User with id \" + userId + \" and order id \" + orderId + \" Not found\"));<br \/><br \/>        orderFound.setDescription(order.getDescription());<br \/>        orderFound.setPriceInPence(order.getPriceInPence());<br \/><br \/>        return orderRepository.save(orderFound);<br \/>    }<br \/><br \/>    @Override<br \/>    public Order patchUpdateOrder(Long userId, Long orderId, Order order) {<br \/><br \/>        Order orderFound = orderRepository.findByIdAndUserId(orderId, userId)<br \/>                .orElseThrow(() -&gt; new RuntimeException(\"User with id \" + userId + \" and order id \" + orderId + \" Not found\"));<br \/><br \/>        if (order.getDescription() != null)<br \/>            orderFound.setDescription(order.getDescription());<br \/><br \/>        if (order.getPriceInPence() != 0)<br \/>            orderFound.setPriceInPence(order.getPriceInPence());<br \/><br \/>        return orderRepository.save(orderFound);<br \/><br \/>    }<br \/><br \/>    @Override<br \/>    public void deleteOrder(Long userId, Long orderId) {<br \/>        Order order = orderRepository.findByIdAndUserId(orderId, userId)<br \/>                .orElseThrow(() -&gt; new RuntimeException(\"User with id \" + userId + \" and order id \" + orderId + \" Not found\"));<br \/>        orderRepository.delete(order);<br \/>    }<br \/>}<\/pre>\r\n<h2>Create Controller Layer<\/h2>\r\n<h3>User Controller<\/h3>\r\n<pre>@RestController<br \/>@RequestMapping(\"\/api\/users\")<br \/>public class UserController {<br \/><br \/>    @Autowired<br \/>    private UserService userService;<br \/><br \/>    @GetMapping(\"\/{id}\")<br \/>    public User getUser(@PathVariable Long id) {<br \/><br \/>        return userService.getUserById(id);<br \/>    }<br \/><br \/>    @GetMapping()<br \/>    public List&lt;User&gt; getAllUsers() {<br \/>        return userService.getUsers();<br \/>    }<br \/><br \/>    @PostMapping<br \/>    public ResponseEntity&lt;User&gt; createUser(@RequestBody User user) {<br \/>        User createdUser = userService.createUser(user);<br \/>        return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);<br \/>    }<br \/><br \/>    @PutMapping(\"\/{id}\")<br \/>    public User updateUser(@PathVariable Long id, @RequestBody User user) {<br \/>        return userService.updateUser(id, user);<br \/>    }<br \/><br \/>    @PatchMapping(\"\/{id}\")<br \/>    public User patchUpdateUser(@PathVariable Long id, @RequestBody User user) {<br \/>        return userService.patchUpdateUser(id, user);<br \/>    }<br \/><br \/>    @DeleteMapping(\"\/{id}\")<br \/>    public ResponseEntity&lt;?&gt; deleteUser(@PathVariable Long id) {<br \/>        userService.deleteUser(id);<br \/>        return ResponseEntity.status(HttpStatus.NO_CONTENT).build();<br \/>    }<br \/><br \/>}<\/pre>\r\n<h3>Order Controller<\/h3>\r\n<pre>@RestController<br \/>@RequestMapping(\"\/api\/users\")<br \/>public class OrderController {<br \/><br \/>    @Autowired<br \/>    private OrderService orderService;<br \/><br \/>    @PostMapping(\"\/{userId}\/orders\")<br \/>    public ResponseEntity&lt;Order&gt; createOrder(@PathVariable Long userId, @RequestBody Order order) {<br \/><br \/>        Order createdOrder = orderService.createOrder(userId, order);<br \/>        return ResponseEntity.status(HttpStatus.CREATED).body(createdOrder);<br \/>    }<br \/><br \/>    @GetMapping(\"\/{userId}\/orders\/{orderId}\")<br \/>    public Order getOrder(@PathVariable Long userId, @PathVariable Long orderId) {<br \/><br \/>        return orderService.getOrder(userId, orderId);<br \/>    }<br \/><br \/>    @PutMapping(\"\/{userId}\/orders\/{orderId}\")<br \/>    public Order updateOrder(@PathVariable Long userId, @PathVariable Long orderId, @RequestBody Order order) {<br \/>        return orderService.updateOrder(userId, orderId, order);<br \/>    }<br \/><br \/>    @PatchMapping(\"\/{userId}\/orders\/{orderId}\")<br \/>    public Order patchUpdateOrder(@PathVariable Long userId, @PathVariable Long orderId, @RequestBody Order order) {<br \/>        return orderService.patchUpdateOrder(userId, orderId, order);<br \/>    }<br \/><br \/>    @GetMapping(\"\/{userId}\/orders\")<br \/>    public List&lt;Order&gt; getAllOrders(@PathVariable Long userId) {<br \/>        return orderService.getAllOrdersByUserId(userId);<br \/>    }<br \/><br \/>    @DeleteMapping(\"\/{userId}\/orders\/{orderId}\")<br \/>    public ResponseEntity&lt;?&gt; deleteOrder(@PathVariable Long userId, @PathVariable Long orderId) {<br \/>        orderService.deleteOrder(userId, orderId);<br \/>        return ResponseEntity.status(HttpStatus.NO_CONTENT).build();<br \/>    }<br \/>}<\/pre>\r\n<h2>Build and Run application<\/h2>\r\n<pre>mvn spring-boot:run<\/pre>\r\n<h2>Test API manually\u00a0<\/h2>\r\n<p>We can test REST API manually with Postman . Following shows sample request and responses for various operations<\/p>\r\n<h3>Post User<\/h3>\r\n<p>http:\/\/localhost:8080\/api\/users<\/p>\r\n<p>Request Body<\/p>\r\n<pre>{<br \/>   \"firstName\":\"Steve\",<br \/>   \"lastName\":\"Rob\",<br \/>   \"email\":\"steverob@test.com\",<br \/>   \"firstLineOfAddress\":\"111 Pinewood Grove\",<br \/>   \"secondLineOfAddress\":\"Commercial street\",<br \/>   \"town\":\"London\",<br \/>   \"postCode\":\"W7 8AG\"<br \/>}<\/pre>\r\n<p>Response<\/p>\r\n<pre><br \/>{<br \/>   \"id\": 44,<br \/>   \"firstName\":\"Steve\",<br \/>   \"lastName\":\"Rob\",<br \/>   \"email\":\"steverob@test.com\",<br \/>   \"firstLineOfAddress\":\"111 Pinewood Grove\",<br \/>   \"secondLineOfAddress\":\"Commercial street\",<br \/>   \"town\":\"London\",<br \/>   \"postCode\":\"W7 8AG\"<br \/>}<\/pre>\r\n<h3>Get User<\/h3>\r\n<p>http:\/\/localhost:8080\/api\/users\/44<\/p>\r\n<p>Response<\/p>\r\n<pre>{<br \/>   \"id\": 44,<br \/>   \"firstName\":\"Steve\",<br \/>   \"lastName\":\"Rob\",<br \/>   \"email\":\"steverob@test.com\",<br \/>   \"firstLineOfAddress\":\"111 Pinewood Grove\",<br \/>   \"secondLineOfAddress\":\"Commercial street\",<br \/>   \"town\":\"London\",<br \/>   \"postCode\":\"W7 8AG\"<br \/>}<\/pre>\r\n<h3>Put User<\/h3>\r\n<p>http:\/\/localhost:8080\/api\/users\/44<\/p>\r\n<p>Request Body<\/p>\r\n<pre>{<br \/>   \"firstName\":\"Steveupdated\",<br \/>   \"lastName\":\"Robupdated\",<br \/>   \"email\":\"steverob@test.com\",<br \/>   \"firstLineOfAddress\":\"111 Pinewood Grove\",<br \/>   \"secondLineOfAddress\":\"Commercial street\",<br \/>   \"town\":\"London\",<br \/>   \"postCode\":\"W7 8AG\"<br \/>}<\/pre>\r\n<p>Response<\/p>\r\n<pre>{<br \/>   \"id\": <strong>44<\/strong>,<br \/>   \"firstName\":\"Steveupdated\",<br \/>   \"lastName\":\"Robupdated\",<br \/>   \"email\":\"steverob@test.com\",<br \/>   \"firstLineOfAddress\":\"111 Pinewood Grove\",<br \/>   \"secondLineOfAddress\":\"Commercial street\",<br \/>   \"town\":\"London\",<br \/>   \"postCode\":\"W7 8AG\"<br \/>}<\/pre>\r\n<h3>Patch User<\/h3>\r\n<p>http:\/\/localhost:8080\/api\/users\/44<\/p>\r\n<p>Request Body<\/p>\r\n<pre>{<br \/>   \"firstName\":\"SteveupdatedAgain\",<br \/>   \"lastName\":\"RobupdatedAgain\"<br \/>}<\/pre>\r\n<p>Response<\/p>\r\n<pre>{<br \/>   \"id\": <strong>44<\/strong>,<br \/>   \"firstName\":\"SteveupdatedAgain\",<br \/>   \"lastName\":\"RobupdatedAgain\",<br \/>   \"email\":\"steverob@test.com\",<br \/>   \"firstLineOfAddress\":\"111 Pinewood Grove\",<br \/>   \"secondLineOfAddress\":\"Commercial street\",<br \/>   \"town\":\"London\",<br \/>   \"postCode\":\"W7 8AG\"<br \/>}<\/pre>\r\n<h3>Post Order<\/h3>\r\n<p>http:\/\/localhost:8080\/api\/api\/users\/44\/orders<\/p>\r\n<p>Request Body<\/p>\r\n<pre>{<br \/>  \"description\":\"Awesome phone\",<br \/>  \"priceInPence\":<strong class=\"ja ia\">1200<\/strong>,<br \/>  \"completedStatus\": <strong class=\"ja ia\">false<\/strong><br \/>}<\/pre>\r\n<p>Response<\/p>\r\n<pre class=\"ib ic id ie if ix iy cl\"><span id=\"687a\" class=\"cf iz gg dm ja b eo jb jc s jd\" data-selectable-paragraph=\"\">{<br \/><\/span><span id=\"3500\" class=\"cf iz gg dm ja b eo je jf jg jh ji jc s jd\" data-selectable-paragraph=\"\">   \"id\": <strong class=\"ja ia\">45<\/strong>,<br \/><\/span><span id=\"4021\" class=\"cf iz gg dm ja b eo je jf jg jh ji jc s jd\" data-selectable-paragraph=\"\">   \"description\":\"Awesome phone\",<br \/>   \"priceInPence\":<strong class=\"ja ia\">1200<\/strong>,<br \/>   \"completedStatus\": <strong class=\"ja ia\">false<\/strong><br \/>}<\/span><\/pre>\r\n<h3>Get Order<\/h3>\r\n<p>http:\/\/localhost:8080\/api\/users\/44\/orders\/45<\/p>\r\n<p>Response<\/p>\r\n<pre class=\"ib ic id ie if ix iy cl\"><span id=\"da3c\" class=\"cf iz gg dm ja b eo jb jc s jd\" data-selectable-paragraph=\"\">{<br \/><\/span><span id=\"32c1\" class=\"cf iz gg dm ja b eo je jf jg jh ji jc s jd\" data-selectable-paragraph=\"\">   \"id\": <strong class=\"ja ia\">45<\/strong>,<br \/><\/span><span id=\"5d01\" class=\"cf iz gg dm ja b eo je jf jg jh ji jc s jd\" data-selectable-paragraph=\"\">   \"description\":\"Awesome phone\",<br \/>   \"priceInPence\":<strong class=\"ja ia\">1200<\/strong>,<br \/>   \"completedStatus\": <strong class=\"ja ia\">false<\/strong><br \/>}<br \/><\/span><\/pre>\r\n<h3 class=\"ib ic id ie if ix iy cl\"><span id=\"5d01\" class=\"cf iz gg dm ja b eo je jf jg jh ji jc s jd\" data-selectable-paragraph=\"\">Complete Source Code Location<\/span><\/h3>\r\n<p>https:\/\/github.com\/ranjesh1\/spring-boot2-rest-order-services.git<\/p>\r\n<h2>Unit Tests<\/h2>\r\n<p class=\"entry-title\">Creating unit tests are described in another post &#8216;<a href=\"https:\/\/ranjeshviswa.com\/?p=121\">Unit Testing with Spring Boot Application<\/a>&#8216;<\/p>\r\n","protected":false},"excerpt":{"rendered":"<p>Spring Boot is an open source Java -based framework, used to build stand-alone and production ready spring applications. In this article, we will show you how to build simple REST API from scratch using Spring Boot 2.2.9, Spring Data JPA\/Hibernate with MySQL as database. Requirement We need to create a simple REST API\u00a0 to create, &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/ranjeshviswa.com\/?p=36\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Create a REST API with Spring Boot&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":38,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2,8,3,4],"tags":[],"_links":{"self":[{"href":"https:\/\/ranjeshviswa.com\/index.php?rest_route=\/wp\/v2\/posts\/36"}],"collection":[{"href":"https:\/\/ranjeshviswa.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ranjeshviswa.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ranjeshviswa.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ranjeshviswa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=36"}],"version-history":[{"count":22,"href":"https:\/\/ranjeshviswa.com\/index.php?rest_route=\/wp\/v2\/posts\/36\/revisions"}],"predecessor-version":[{"id":141,"href":"https:\/\/ranjeshviswa.com\/index.php?rest_route=\/wp\/v2\/posts\/36\/revisions\/141"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ranjeshviswa.com\/index.php?rest_route=\/wp\/v2\/media\/38"}],"wp:attachment":[{"href":"https:\/\/ranjeshviswa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=36"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ranjeshviswa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=36"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ranjeshviswa.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=36"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}