Skip to main content

Building reactive Spring API (CRUD) with Spring Webflux and reactive PostgreSQL (Step-By-Step)

Why reactive programming in Spring?

In Spring 5.0, spring added another parallel web-stack to the existing servlet based MVC web-stack. This new stack is fully reactive, non-blocking, and based on the project reactor library
Now the question is why a new stack? Non-blocking code doesn't block any threads and hence it can scale with very few threads. This lets developers take advantage of multi-core, modern processors—handling huge numbers of concurrent requests.  With this, you can satisfy more concurrent users with fewer microservice instances.

All the way reactive:

When we build reactive we need to make sure that we use all the libraries in the stack which are non-blocking. If code is doing any blocking operation anywhere in sequence then we will lose the advantage of using reactive stack. Sping has added various libraries to support this complete stack. We are going to use Spring Webflux and R2DBC here.


Building a Rest API using spring boot and PostgreSQL:

here, we are going to build a reactive REST (CRUD) API step-by-step, using the spring WebFlux and PostgreSQL database.
We will follow the below 4 steps:
  1.  Create a Customer table in the local PostgreSQL database.
  2.  Using Spring Initializer to build a base Spring Boot Project with required dependencies
  3.  Import the project in IDE (I will be using IntelliJ IDEA) and setup database properties. 
  4.  Write a code:
    •  Write a model class.
    •  Write a spring repository interface.
    •  Write a Rest Controller and all CRUD operations
    •  Test the code using the rest client.
If you are more of a video person, you can check the video here or you can continue reading the blog:


Step 1: Setup a local database

I have PostgreSQL locally running, I will be connecting to it using SQL client and will run the following queries to create a customer table.
create table customer (id serial primary key, name text);
insert into customer(name) values("foo");
insert into customer(name) values("bar");

Step 2: Spring Initializer

Now the next step is to use a spring initializer to generate basic spring boot application code with required dependencies. Go to https://start.spring.io/ - and generate a project with the following dependencies. 
  • Spring Reactive Web - This will add reactive web-stack.
  • Spring data R2DBC - Reactive relational database connectivity.
  • PostgreSQL Driver - Since we want to connect the PostgreSQL database.
  • Lombok - to reduce boilplate code (getter, setter, constructor etc.)


this will generate a zip file we need to extract it to some workspace folder.

Step 3: Import the project folder into IDE like Intellij IDEA

Now, let's import the project into IDE, now if we try to run the SpringBootApplication class it will fail now. We need to add the following properties to the application.properties file to make it work. These will basically point to a locally running the postgreSQL database.

spring.r2dbc.url=r2dbc:postgresql://localhost/postgres
spring.r2dbc.username=postgres
spring.r2dbc.password=changeme

Step 4: Write the code.

The first step is to create a model class that matched the customer table we created in the database. we will create a class like below with Spring data annotation of @Table on class and @id and @Column  for respective fields. we are also using Lombok annotation @Data which will automatically generate boilerplate( constructor, getter, setter, toString, hashcode, and equals) code for us.

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
@Table
@Data
public class Customer {
    @Id
    private Integer id;
    @Column
    private String name;
}


Now we need to create the ReactiveCrudRepository interface.

import com.example.reactivepostgresdemo.model.Customer;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;

public interface CustomerRepository extends ReactiveCrudRepository {

}

Once we have a repository we will use @RestController to create a controller class and inject the repository into it. Then we will implement all CRUD operations with @GetMapping @PostMapping @PutMapping and @DeleteMapping spring annotations.

import com.example.reactivepostgresdemo.model.Customer;
import com.example.reactivepostgresdemo.repo.CustomerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/customer")
public class CustomerController {

    @Autowired
    CustomerRepository repository;

    @GetMapping
    public Flux getCustomers(){
        return repository.findAll();
    }

    @GetMapping("/{id}")
    public Mono getCustomer(@PathVariable Integer id){
        return repository.findById(id);
    }
    
    @PostMapping
    public Mono createCustomer(@RequestBody Customer customer){
       return  repository.save(customer);
    }
    
    @PutMapping("/{id}")
    public Mono updateCustomer(@RequestBody Customer customer, @PathVariable Integer id){
        return repository.findById(id)
                        .map((c) -> {
                            c.setName(customer.getName());
                            return c;
                        }).flatMap( c -> repository.save(c));

    }

    @DeleteMapping("/{id}")
    public Mono deleteCustomer(@PathVariable Integer id){
        return repository.deleteById(id);
    }
}

Comments

Popular posts from this blog

Java 8 Optional Class: Why and When to use?

If you have developed any project Java, or if you have been maintaining enterprise application written in java, you must have encounter NullPointerException at some point in your programming life. They are a pain! I have encountered many production bugs which were because of NullPointerException and so should many of you who have been working in Java for some time. However, we do not know if anything that we could do here as NullPointerExceptions are a side effect of using 'null' reference which is very useful in representing an absence of value.  Null reference was first invented by Tony Hoare in 1965 while developing language Algol W. It was subsequently added to other languages. Tony Hoare himself called the invention of null reference  a billion-dollar mistake! Source: https://en.wikipedia.org/wiki/Null_pointer Problems with Null reference

Where is the favicon edit option in new blogger (2020)?

Favicon edit option on the new blogger 2020? In an earlier version of the blogger, there was an option to edit favicon from a layout view. However now in new blogger UI that doesn't seem to be a case! If you go to the layout page you will see that the favicon gadget is missing. In new blogger, It has been moved under overall Settings, so now if you want to edit the favicon you need to go to Settings, In settings in under the Basic section, you will see the Favicon link, click it. Clicking it will take to the Configure Favicon page, where you can upload a square image for your favicon. Once saved you will start seeing it on your browser.' Happy blogging! :)