Spring cloud config

Overview: In this tutorial, we will cover the basics of Spring cloud config server and client, where you will set up your cloud config server and access configuration through client services.

What is Spring cloud config?

Spring cloud config provides server and client side support for externalized configuration a distributed system.

Why Spring cloud config?

External configuration is the basic need of almost any application. Now we are leaving in the microservices world, that need external configuration more often. Almost every individual application has some external and dynamic properties that keep updating based on the environment or some period of time.  In case of the massive size of services, it is hard to manage or left with creating a custom solution for it.

The dilemma is how we can make our application to adopt dynamic changes more often without investing time into it and with zero downtime. Here spring cloud config comes into the picture. It will help a user to manage their external properties from multiple sources like git, local file system etc. Transfer data into encrypted form and lot more.

How it works?

Screen Shot 2018-08-26 at 9.22.06 PM.png

Above diagram, you can see multiple services that get configuration from config server where config server sync with GIT or any other VCS to get new changes.

Let’s create a simple application, that will take a message from the config server and return through the endpoint.

Implementation of spring cloud config server:

Now I’m going to visit  spring initializer page to generate demo project, where I’ve included dependencies of spring ‘web’ and ‘config server’.

Once project imported into IDE, enable config server with ‘@EnableConfigServer’ annotation

@SpringBootApplication
@EnableConfigServer
public class DemoApplication {

   public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
   }
}

In this example, I’m using local git  for demo purpose

#mkdir cloud-config
#git init
#touch config-client-demo.properties
#vi config-client-demo.properties 
message=Hello World
//wq (write and quite vi editor)
#git add config-client-demo.properties
#git commit -m "initial config"

By default, config server starts on port 8080 as spring boot application.

Here is config server application.properties

server.port=8888
spring.cloud.config.server.git.uri=${HOME}/Desktop/cloud-config

server.port: We use this property to define server port if you do not define it will set 8080 as a default port. Here I’m using the same machine for client and server so one of the port needs to be updated.

spirng.cloud.config.server.git.uri: We define this property to fetch configuration detail from git repository.

Implementation of client application:

Now I’m again going to generate a template application using spring initializer where included ‘web’, ‘client config’ and ‘actuator’ as dependencies. Here ‘actuator’ help us to refresh configuration.

Below is message controller that return message and that message came from config properties, you will notice @RefreshScope annotation that helps to refresh configuration.

@RestController
@RefreshScope
public class MessageRestController {

    @Value("${message}")
    private String message;

    @GetMapping("/message")
    String getMessage() {
        return this.message;
    }
}

Then rename your ‘applcation.properties‘ file to ‘bootstrap.properties‘ and include below config,  I’ve defined application name(name of application should accurate to fetch specific data), Configuration URI(which your config server URL that holds properties details) and expose all actuator endpoint that by default disabled

spring.application.name=config-client-demo
spring.cloud.config.uri=http://localhost:8888

management.endpoints.web.exposure.include=*

spring.application.name: Accurate name of the configuration file that defined on config server.

spring.cloud.config.uri: Base url of config server

management.endpoints.web.exposure.include: By default actuator’s most features are disabled so use a wildcard to enable all. That actually not needed in case of production.

Run your application and you will see below message.

GET http://localhost:8080/message

Response :
Hello world

Let’s update the properties file, I’m going to update ‘Hello World’ to ‘Hello Test’

#vi config-client-demo.properties
message= Hello Test
...
#git add config-client-demo.properties
#git commit -m "update message"
//Once file updated then 'refresh' configuration

Once you included the @RefreshScope annotation that will expose endpoint for you to refresh application, check below.

POST http://localhost:8080/actuator/refresh

Now again hit your message API

GET http://localhost:8080/message
Response:
Hello Test

checkout example at git

Conclusion: We can use spring cloud config to any kind of application for external, distributed and centralized configuration server. There is no limitation of technology and programming languages. You can apply spring cloud config in other languages as well.

Hope you like this tutorial.

 

Advertisements

Relational to NoSQL database

Hey Everyone,

Today I’m going to share you the other experience that I’ve struggled with. I know after reading this post most of you will relate your issues with my experience and you will find a new way to deal with them.

The pain of relational database in a small project where you no need of transaction support and also not defined any complex relationship between the multiple entities.  We are very habitual with relation database we always trying to go with them. But here I’m trying to stop you, first check NoSQL, if they not meet your requirement. Then go with relational one. I know that first think clicked in your mind.

“Nikesh, who the hell are you stopping me to meet my first love(Maybe 🙂 )”.

Yes, I agree replacing the first love is pretty difficult but try to do new affair that may make your life cool. 🙂

Let me explain!!

What is NoSQL?

NoSql is basically a database used to manage huge sets of unstructured data, where data is not stored in a tabular relation like a relational database.

Why NoSQL?

A traditional database prefers more predictable and structured data. The technologies are increasing and we want to automate everything, in such situations we want to gather all type of data to be more predictable. Every time getting structural data is a bit difficult. Many times we need to deal with such situations where we need to store unstructured data. Here comes NoSQL as a savior.

NoSQL as per name says NOT ONLY SQL that comes with lots of more added benefit. It provides a completely new way then the Relational DB to deal with data. Managing any type of data is very simple in NoSQL then relational.

Types of NoSQL database

  • Document type: In this database, the key is paired with a complex data structured called as Document. Example: MongoDB
  • Graph stores: This types of a database is usually used to store networked data. Where we can relate data based on some existing data. Example: Neo4J
  • Key-Value stores: These are the simplest NoSql database. In this database each record store with a unique key to identify it. Example: Aerospike
  • Wide column-stores: This type of database store large data set. Example: Cassandra.

Let’s see one of the use cases (using MongoDB and MySQL):

Imagin that we have beer store database that holds beer store basic information, like beer style, beer type, and beer store addresses.

Let’s see a basic schema design in case of the relational database.

Here I have created beer_store table that holds store names then created address table that holds beer store addresses (one store can be available in multiple places)  along with country and city table. then I’ve defined beer_style and beer_type that provided by the beer stores. then defined many to many relationships between beer type and beer_store and the same in case of beer_style and beer store also.

Screen Shot 2018-04-15 at 9.06.53 PM.png

Now same beer store we can achieve in case of NoSQL (JSON-like documents). below schema.

There is two way you can design your NoSQL schema.

  1. You can store all the data into the same collection. but there is some disadvantage when some data repeat multiple times.
  2. You can store a reference to data little bit similar to SQL.

Here to avoiding confusion, I’ve separated few tables where information is fixed and that will repeat in case of another beer store record.

beer_store

Screen Shot 2018-04-15 at 2.47.28 PM.png

and other tables that hold values and references

beer_style

Screen Shot 2018-04-15 at 4.32.42 PM.png

beer_type

Screen Shot 2018-04-15 at 4.33.26 PM.png

country

Screen Shot 2018-04-15 at 2.51.41 PM.png

Query Example SQL VS NoSQL

#SQL

select * from beer_store;
//output
+------------+-------------+
| pkstore_id | name        |
+------------+-------------+
|          1 | Magic Beer  |
|          2 | Beerland    |
|          3 | Uptown Beer |
+------------+-------------+

#NoSQL

db.beer_store.find()
//output
{
	"_id" : ObjectId("5ad31853e5ce6fe732eb7300"),
	"name" : "The Beera",
	"address" : [
		{
			"address1" : "sec 4",
			"address2" : "shastri cercle",
			"city" : "jaipur",
			"country" : "India"
		}
	],
	"beerType" : [
		"Ales",
		"Lagers"
	],
	"beerStyle" : [
		"Amber",
		"Blonde"
	]
}
{
	"_id" : ObjectId("5ad4bfa2b20cf32e1fa3cb6d"),
	"name" : "BeerLand",
	"address" : [
		{
			"address1" : "sec 4",
			"address2" : "hiran magri",
			"city" : "udaipur",
			"country" : "India"
		}
	],
	"beerType" : [
		"Ales",
		"Lagers"
	],
	"beerStyle" : [
		"Amber",
		"Blonde"
	]
}

Above both SQL and NoSQL query requested for beer_store but as per both are different way persisted result return based on it.

Same NoSQL response we can achieve with relation database but for this, we have to do multiple joins, subqueries and inbuilt JSON converter.

Conclusion: Relation database has their own importance like supporting the ACID properties. they are well organized.  But many cases NoSQL appreciable, like when we do search operation, sorting operation filtering on one-to-many and many-to-many relationships. 

Hope you like this. Thanks for reading 🙂

 

Install spring boot application on linux

Today most of the people prefer to deploy the standalone application and easy to manageable instead of doing too much overhead or get expert advice on it to manage a specific web server for rest application.

dilemma: When we have a standalone jar there are few minor hacks we have to do this with it. like, configure log path, start with a specific promised user. run it with standalone process instead of inline execution.

A fully executable jar can be executed like any other executable binary or it can be registered with ‘systemd‘.  This makes it very easy to install and manage spring boot applications in common production environments.

#systemd: systemd is system and service manager for linux operating system. When run as the first process on boot (as PID 1), it acts as init system that brings up and maintains userspace services. it is a replacement of ‘Unix system v’ and BSD (Berkeley Software Distribution) init system. for more detail #man systemd

Assume that you have a linux server that has Java installed, now place your executable spring boot jar file in a /opt/apps/ directory

Now create a app.service file in a /etc/systemd/system
directory and execute below command also make sure your permission before creating a file at a particular location
#vi /etc/systemd/system/app.service

and paste script

[Unit]
Description=sample application
After=syslog.target

[Service]
User=appUser
ExecStart=/opt/apps/app.jar
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

now save above script using “:wq” for more detail check vi editor helps(#man vi)

let’s enable service

#systemctl enable app.service
(check #man systemctl for more detail.)

once service enables now you can start, stop and check status of your service.

#systemctl start app.service
#systemctl stop app.service

Hope you like this. Thanks for reading 🙂

Delegates in Kotlin

Hi Everyone,

Today we gonna discuss delegates in kotlin.

The Delegation pattern has proven to be a good alternative to implementation inheritance, and kotlin supports it natively requiring zero boilerplate code.

Property delegates don’t have to implement any interface, but they have to provide a getValue() and setValue() function.

let’s see an example, that mention in Kotlin ref docs. going to define Delegate class with getValue and setValue function.

class Delegate {

    operator fun getValue(thisRef : Any?, property : KProperty<*>) : String
    {
        return "${thisRef?.javaClass?.name}, thank you for delegating '${property.name}' to me!"
    }

    operator fun setValue(thisRef : Any?, property : KProperty<*>,value : String)
    {
        println("$value has been assigned to '${property.name}' in ${thisRef?.javaClass?.name}.")
    }
}

now creating another class.

class Example {
     var p : String by Delegate()
}

call Example class

fun main(args : Array)
{
    var example = Example()
    println(example.p)
    example.p = "delegate world"
}
//output:

com.delegated.Example, thank you for delegating 'p' to me!
delegate world has been assigned to 'p' in com.delegated.Example.

kotlin provides few delegated properties build into the language – Lazy properties, Observable properties, and properties storing in the map.

Lazy Properties: lazy is a function that takes a lambda and returns and returns an instance of Lazy which can serve as a delegate.

let’s create an example class.

class Example {
     val lazyValue: String by lazy {
          println("computed!") 
          "Hello"
     }
}
fun main(args : Array)
{
    println(example.lazyValue)
}
//output:
computed!
Hello

Observable properties: Observable takes two arguments: the initial value and a handle for modifications. the handler gets called every time we assign the property. it has three parameters: a property being assigned to, the old value and the new one.

let’s create an example class

class Example {
     
     var name: String by Delegates.observable("") {
          prop, old, new ->
          println("$old -> $new")
     }
}
fun main(args : Array)
{
    var example = Example()

    example.name = "first"
    example.name = "second"
}
//output:
 -> first
first -> second

Properties storing in the map: One common use case is storing the values of properties in a map. This comes up often in applications like parsing JSON or doing other “dynamic” things. In this case, you can use the map instance itself as the delegate for a delegated property.

let’s create an example class.

class User(val map: Map<String, Any?>) {
    val name:String by map
    val age: Int by map
}
fun main(args : Array)
{
    var user = User(mapOf("name" to "Ritesh pathak", "age" to 23))
    println(user.name)
    println(user.age)
}
//output:
Ritesh pathak
27

Ref – Kotlin docs.

Hope you like this. Thanks for reading 🙂

Sealed class in kotlin

Hi Everyone,

Today we gonna discuss Sealed class in kotlin, Sealed is a new class type that introduced by kotlin.

Sealed class –  Sealed classes are used for representing restricted class hierarchies when a value can have one of the types from a limited set.

whereas a subclass of a sealed class can have multiple instances which can contain state.

there are few rules that make a class as a sealed

  1. To declare a sealed class you have to put ‘sealed’ modifier before the name of the class.
  2. A sealed class is abstract by itself, it cannot be instantiated directly and can have abstract members.
  3. Sealed classes are not allowed to have non-private constructors
  4. A sealed class can have subclasses, but all of them must be declared in the same file as the sealed class itself. but that classes which extend subclasses of a sealed class can be placed anywhere, not necessarily in the same file.

Let’s see the example as per kotlin reference doc

sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
class Multi(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()

above we define sealed class Expr and there other classes that extend Expr

The key benefit of using sealed classes comes into play when you use them with WHEN expression. If its possible to verify that the statement covers all cases, you don’t need to add an else clause to the statement.if you remove any of the cases it will throw compile time error.

fun eval(expr: Expr): Double = when(expr) {
    is Const -> expr.number
    is Sum -> eval(expr.e1) + eval(expr.e2)
    is Multi -> eval(expr.e1) * eval(expr.e2)
    NotANumber -> Double.NaN
// the `else` clause is not required because we've covered all the cases
}

 

let’s create other class that extends Multi class, here we can place Multi class child into other files.

class ArrayMulti(val x: Expr, val y: Expr) : Multi(x,y)

Now you can also call ArrayMulti class in WHEN expression, but Expr immediate child(e.g Multi class) must be there.

let’s see an example.

fun eval(expr: Expr): Double = when(expr) {
    is Const -> expr.number
    is Sum -> eval(expr.e1) + eval(expr.e2)
    is ArrayMulti -> eval(expr.e1) * eval(expr.e2)
    is Multi -> eval(expr.e1) * eval(expr.e2)
    NotANumber -> Double.NaN
// the `else` clause is not required because we've covered all the cases
}

Hope you like this. Thanks for reading 🙂

Data class in Kotlin

Hi Everyone,

Hope you like my earlier post on Kotlin (Java to kotlin part-1, java to kotlin part-2 and spring 5 reactive application using kotlin).

Kotlin has introduced many features,  in this post we will focus on data class.

 data –  A type of class that mainly use for hold a data. in such class, some standard functionality and utility functions are often mechanically derivable from the data.  we called data class in kotlin.

In case of data class compiler automatically derives the following members from all properties declared in the primary constructor:

#equals()/hashCode() pair.
# toString()
# componentN() functions corresponding to the properties in their order of declaration.
# copy() function

data classes have to fulfill the requirements:

# The primary constructor needs to have at least one parameters.
# All primary constructor parameters need to be marked as val or var.
# Data classes cannot be abstract, open, sealed or inner.
# (before 1.1) Data classes may only implement interface

let see the example of data class.

Now we are going to create a class with data prefix and define a primary parameterized constructor.

data class Customer(var id: Int,var name: String,var email : String)
//or you can define with default value
data class Customer(var id: Int,var name: String="",var email : String="test@gmail.com")

In the next step, we will be going to instantiate our customer class and print the customer object by using toString method.

var customer = Customer(1,"Nikesh","test@nikeshpathak.com")
println(customer.id)
println(customer.name)
println(customer.email)
println(customer.toString())

output:
1
Nikesh
test@nikeshpathak.com
Customer(id=1, name=Nikesh, email=test@nikeshpathak.com)

Now we will compare customer object using the equals method.

var customer = Customer(1,"Nikesh","test@nikeshpathak.com")
var customer1 = Customer(1,"Nikesh","test@nikeshpathak.com")
println(customer.equals(customer1))
customer1 = Customer(1,"Ritesh","test@nikeshpathak.com")
println(customer.equals(cus=tomer1))

output:
true
false

Note – Structural equality is checked by the equal/==  operation and referential equality is checked by the === operation.

We can Copy one object in another by using copy method.

var customer = Customer(1,"Nikesh","test@nikeshpathak.com")
var customer1 = customer.copy(2,"Ritesh")
println(customer1.id)
println(customer1.name)
println(customer1.email)

output:
2
test@nikeshpathak.com
Ritesh

using componentN (Destructuring declarations)

val (_,name,email) = customer

above syntax is called a destructuring declaration. A destructuring declaration creates multiple variables at once. we have declared two new variables name and email and can use them independently.

println(name)
println(email)

let’s take look example.

var customer = Customer(1,"Nikesh","test@nikeshpathak.com")
val (_,name,email) = customer
// println(id)
println(name)
println(email)

output:
Nikesh
test@nikeshpathak.com

Ref – Kotlin docs

Thanks for reading 🙂

Java to Kotlin part -2

Hello Everyone,

In this post, we will see object-oriented syntex and features in Kotlin. for other basic detail please visit the part-1 tutorial to make yourself comfortable.

let’s jump into code!

#using class

Java

class Customer {
}

Kotlin

class Customer {
}
//or if the class has no body then curley braces can be omitted
class Customer

 

#using constructor including primary and secondary 

Java

class Customer {

    String name;

    Customer() {}

    Customer(String name)
    {
        //TODO
    }
}

Kotlin

class Customer() {

    lateinit var name: String

    constructor(name: String) : this()
    {
        //TODO
    }
}

#using instance of class

Java

Customer customer = new Customer();
//or
Customer customer1 = new Customer("Test");

Kotlin

val customer  = Customer()
//or
val customer1 = Customer("Test")

#using inheritance 

Java

public class Base {

    Base(int p)
    {
        //TODO
    }
}
public class Derived extends Base{

    Derived(int p) {
        super(p);
    }
}

Kotlin

open class Base(p: Int)
class Derived(p: Int) : Base(p)

#using method overriding

Java

public class Base {

   final void v() {}
   void nv() {}
}
public class Derived extends Base{

    @Override
    void nv() {
        super.nv();
    }
}

Kotlin

open class Base {
    open fun v() {}
    fun nv() {}
}
class Derived() : Base() {
    override fun v() {}
}

#using static methods

Java

class Customer {

   static String name = "Test";
}

Kotlin

class Customer {

    companion object {
         var name : String = "Test"
    }
}

 

Thanks for reading 🙂

Java to kotlin part -1

Hello Everyone,

The purpose of this post to teach you kotlin syntax and new features based upon your current knowledge of java.

Kotlin is a statically-typed programming language that runs on the Java virtual machine and also can be compiled to JavaScript source code or use the LLVM compiler infrastructure. Its primary development is from a team of JetBrains programmers based in Saint Petersburg, Russia. As of Android studio, 3.0 kotlin is a fully supported programming language as well you can also write a server-side application in kotlin. you can also use kotlin to write build script in the gradle build system.

The best things you can directly use Java classes and library into kotlin and vice-versa

so let’s jump into code.

# print hello world

Java

public static void main(String[] args) {

    System.out.println("Hello World!");
}

Kotlin

fun main(args : Array)
{
    println("Hello World!")
}

# using variable 

Java

public static void main(String[] args) {

    final int a =1;
    final int b = 2;
    final int c;
    c = 3;
    int d =4;

    System.out.println(String.format("a = %d, b = %d, c = %d, d = %d", a, b, c, d));
}

Kotlin

fun main(args : Array)
{
    val a: Int = 1  // immediate assignment
    val b = 2   // `Int` type is inferred
    val c: Int  // Type required when no initializer is provided
    c = 3       // deferred assignment
    var d = 4  //Mutable variable
    println("a = $a, b = $b, c = $c, d = $d")
}

#using function with return and no parameter 

Java

public String message()
{
    return "Hello World";
}

Kotlin

fun message() : String
{
    return "Hello World"
}

#using function with void type and parameter 

Java

public void message(String message)
{
    System.out.println(message);
}

Kotlin

fun message(message : String) : Unit
{
    println("Hello World")
}

//or

fun message(message : String)
{
    println("Hello World")
}

#using conditional expression

Java

public int maxValue(int a, int b)
{
    if(a > b){
        return a;
    }else {
        return b;
    }
}

Kotlin

fun maxValue(a: Int, b: Int): Int {
    if (a > b) {
        return a
    } else {
        return b
    }
}

#using switch case(in case of kotlin we can using ‘when’)

Java

switch (args)
{
    case 1:
        System.out.println("One");
        break;
    case 2:
        System.out.println("Two");
        break;
        default:
           System.out.println("args is not 1 or 2");

}

Kotlin

when(args){
    1 -> println("One")
    2 -> println("Two")
    else -> {
        println("args is not 1 or 2")
    }
}

#using for loop

Java

String[] arrays = {"Apple", "Mango", "Orange"};
for(int i=0;i<arrays.length;i++)
{
    System.out.println(String.format("item at %d is %s",i,arrays[i]));
}

Kotlin

val items = arrayOf("Apple","Mango","Orange");
for (index in items.indices)
{
    println("item at $index is ${items[index]}")
}

#using while loop

Java

String[] arrays = {"Apple", "Mango", "Orange"};
int index = 0;
while(index < arrays.length)
{
    System.out.println(String.format("item at %d is %s",index,arrays[index]));
    index++;
}

Kotlin

val items = arrayOf("Apple","Mango","Orange");
var index =0
while (index < items.size)
{
    println("item at $index is ${items[index]}")
    index++
}

#using lambda

Java

String[] strArray =  {"Avocado","Mango","Apple","Orange","banana","Guava"};
List fruits = Arrays.asList(strArray);
fruits.stream().filter(s->s.startsWith("A")).sorted().map(s->s.toUpperCase())
        .forEach(s->{
            System.out.println(s);
        });

Kotlin

val fruits = arrayOf("Avocado","Mango","Apple","Orange","banana","Guava")
 fruits.filter { it.startsWith("a") }.sortedBy { it }.
         map { it.toUpperCase() }.forEach{ println(it)}

#using null values and checking for null

Java

public Integer parseInt(String str)
{
    try {
        return Integer.parseInt(str);
    }catch(NumberFormatException ex)
    {
        return null;
    }
}

Kotlin

fun parseInt(str: String) : Int?
{
    return str.toIntOrNull()
}
//incase if you call parseInt method with null input
fun parseInt(str: String?) : Int?
{
    return str?.toIntOrNull()
}

#using type checks

Java

public Integer getStringLength(Object obj)
{
    if(obj instanceof String)
    {
        return ((String) obj).length();
    }

    return null;
}

Kotlin

fun getStringLength(obj: Any): Int? {
    if (obj is String) {
        // `obj` is automatically cast to `String` in this branch
        return obj.length
    }

    // `obj` is still of type `Any` outside of the type-checked branch
    return null
}

Ref –  Kotlin docs

Part-2

Thanks for reading 🙂

Spring 5 reactive web application using kotlin

Spring has introduced webFlux new reactive web framework to support reactive programming.

Reactive programming?

“Reactive programming is about processing an asynchronous stream of data items, where applications react to the data items as they occur. A stream of data is essentially a sequence of data items occurring over time. This model is more memory efficient because the data is processed as streams, as compared to iterating over the in-memory data” (define at Oracle docs) .

For example, in an imperative programming setting, a = b +c would mean that a is being assigned the result of  b + c in the instant the expression is evaluated , and letter the values of b and/or c can be changed with no effect on the value of a, However, in reactive programming, the valud of a is automatically updated whenever the values of b and/or  c changes, without the program having to re-execute the sentence a= b + c to determine the presently assigned value of a (click here for more detail) .

Prerequisites :

Kotlin
Spring boot
Spring 5 webFlux and Reactive basic(RxJava or Project Reactor)
Spring data
Gradle

let generate spring boot template from Spring Initializr

Screen Shot 2017-11-26 at 11.13.34 AM

now import the generated project in your IDE and create Customer data class, check below example:-

Screen Shot 2017-11-26 at 11.35.48 AM

git link

@Document applied at the class level to indicate this class is a candidate for mapping to the database. You can specify the name of the collection where the database will be stored.

@Field applied at a variable level to define column name.

data class is specialized for hold data.

then created ‘Repository’ class look like below.

Screen Shot 2017-11-26 at 10.09.42 AM

git link

above class, I’ve extended ReactiveMongoReposiotry instead of MongoRepository because we are using Reactive features like Mono and Flux.

once ‘CustomerRepo’ repository classes created then create a handler for it, below code sample.

Screen Shot 2017-11-26 at 10.08.20 AM

git link

ServerRequest and ServerResponse introduce in spring 5, we can extract request param, path variable, header information and body details from ServerRequest.

Mono is a specialized Publisher that emits at most one item and then optionally terminates with an onComplete signal or an onError signal. click here for more detail.

Flux is a standard ‘Publisher’ representing an asynchronous sequence of 0 to N emitted items, optionally terminated by either a completion signal or an error. Thus, the possible values of a flux are a value, a completion signal, or an error. As in the Reactive Streams spec, these 3 types of signal translate to calls to a downstream object’s ‘onNext’, ‘onComplete’ or ‘onError’ methods. click here for more detail.

now we have handler and repository we need to expose endpoint, there is the magic of webFlux, you not need to create a separate class for it also get a ride from so much boilerplate, see below snippet.

Screen Shot 2017-11-26 at 10.07.39 AM

git link

Let me explain line by line,

@Configuration annotation indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime.

@EnableReactiveMongoRepositories annotation is for Spring boot to enable reactive mongo repositories. if no base package is configured, in the case of spring boot application it is by default enable if you have include starter library.

@Bean is a method-level annotation and a direct analog of the XML element. The annotation supports most of the attributes offered by.

RouterFunction Central entry point to Spring’s functional web framework. Exposes routing functionality, such as to create a RouterFunction given a RequestPredicate and HandlerFunction, and to do further subroutine on an existing routing function.

HandlerFunction  Incoming HTTP requests are handled by a HandlerFunction, which is essentially a function that takes a ServerRequest and returns a Mono
let’s test whatever we have written, see below code snippet.

Screen Shot 2017-11-28 at 4.59.39 AM

git link

By default Spring webFulx include asynchronous natty server.

@RunWith(SpringRunner::class) Indicates that the class should use Spring’s JUnit facilities.

@SpringBootTest provides the following features over and above the regular Spring TestContext Framework,

  • Uses SpringBootContextLoader as the default ContextLoader when no specific @ContextConfiguration(loader=…) is defined.
  • Automatically searches for a @SpringBootConfiguration when nested @Configuration is not used, and no explicit classes are specified.
  • Allows custom Environment properties to be defined using the properties attribute.
  • Provides support for different webEnvironment modes, including the ability to start a fully running container listening on a defined or random port.
  • Registers a TestRestTemplate bean for use in web tests that are using a fully running container.

WebTestClient Non-blocking, reactive client for testing web servers. It uses the reactive WebClient internally to perform requests and provides a fluent API to verify responses.

WebTestClient can connect to any server over an HTTP connection. It can also bind directly to WebFlux applications using mock request and response objects, without the need for an HTTP server.

Conclusion

There are lots more features provided by Spring 5 and project reactor, I’ve introduced very basic sample on it. sample source available on my github .