In my last blog, I have discussed the main basic components of the microservice architecture. In this blog, we will discuss about some implementation techniques of the microservice architecture using Java and node-js technologies. I have worked on one project which converts currency from one format to other.
Below diagram will describe the structure of the application. Zuul Gateway has an inbuilt Ribbon load balancer. Zuul Gateway is the entry point for all the clients and it connects with Eureka Server to get the location of deployed microservice instances. All the node-js microservices below registered themselves with Eureka Server using Client Side Discovery pattern.
Architecture Diagram of Microservice Implementation :
In this application we are using different microservices which are listed below with description:
1. User Microservice :
User microservice is written in node.js and is used to create users and to fetch user's information. It is also used as metadata service because we can create exchange data from this microservice also.
2. Forex Microservice :
Forex microservice is also written in node.js and is used to set the value of one currency against another currency. We can also get the value of one currency against another one.
3. Currency Conversion Microservice :
Currency conversion microservice is also written in node.js and is used to convert the value of one currency into another currency value. To convert the value it will first fetch the value of one currency against another one from Forex microservice and then do the manipulation to show the converted value. In this case, one microservice(Currency Microservice) calls another microservice(Forex microservice) and it is done by using Feign Client.
Feign Client: If you want to call any method of another application in our application then you have to do either rest or soap request. Currently, rest is used mostly due to its flexible nature. To do rest call to other application you have to use rest-template in which we have programmatically build proper URL of the target with all the URL parameters and then pass it to a method of rest-template to fetch the data. To do this developer has to take care of everything rather than focus on the business logic of the application.
To overcome this issue, Netflix provides an abstraction over the REST API calls in which developers don’t have to bother about the internal working of REST APIs. The developer has to only define interface against the rest API and then the original request will be constructed by Spring itself. It hides the internal working of REST APIs and developers have now more time to focus on business logic. Request encoding and response decoding are also provided by Netflix Feign Client. We have to only provide the serviceId of the microservice and then Feign on the fly provide the implementation of the defined interface by using the declarative principle to call another microservice. Feign ask the Eureka discovery about the actual location of requested microservice on the basis of provided service-id and call the actual instance with the desired URL. @FeignClient annotation is used on the interface which takes service-id as a parameter.
How to implement Feign Client in Java:
1. You have to first add Feign dependency in your project pom.xml like
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
2. Add @EnableFeignClients in the main class of the project which let the project know that Feign will be used and enable the project to scan the Feign related annotations.
3. Then you have to define an interface annotated with @FeignClient which take service-id of another microservice as the parameter for which call is made. In this interface, Methods are defined with a type of request with annotation @RequestMapping.
Example :
@FeignClient(name="forex-service") public interface ForexClient { @RequestMapping(method = RequestMethod.GET, value = "/currency-exchange/from/{from}/to/{to}") public ResponseEntity convertCurrency( @PathVariable(value = "from") String from, @PathVariable(value = "to") String to ); }
In above code snippet Feign will provide the implementation of the interface on runtime but for this Feign has to know beforehand about microservice which he has to call. That is why service-id is provided with @FeignClient annotation. Feign connect with Eureka server to get the actual host location of that microservice using service-id and then call the actual instance with URL provided in @RequestMapping annotation.
4. Atlast we have to autowire the interface defined above into required controller or service to inject the implementation of the Interface at runtime and call the interface method. Example:
@RestController public class CurrencyConversionController { @Autowired ForexClient forexClient; @GetMapping("/currency-converter/from/{from}/to/{to}/quantity/{quantity}") public CurrencyConversionBean convertCurrency( @PathVariable String from, @PathVariable String to, @PathVariable BigDecimal quantity) { try { ResponseEntity responseEntity = forexClient.convertCurrency(from,to); }catch (Exception ex){ ex.printStackTrace(); } ......... } }
How to implement Feign Client in Nodejs :
Below are the steps to implement Feign Client in nodejs :
We will use the feignjs module and its client feign-request to implement the Feign in node-js.
1. To install both use the below commands :
npm install feignjs
npm install feignjs-client
There are multiple feign clients :
feignjs-request - Request module for nodejs
feignjs-jquery - JQuery module for nodejs
feignjs-node - Node module for nodejs - use http of nodejs
feignjs-xhr - XHR module for nodejs which use plain xhr.
But we will use feignjs-request because it is more suitable for our case. We will discuss other clients in upcoming blogs.
1. To install it use the command below :
npm install feignjs-request
2. Import feign in your required file using below syntax :
import feign = require('feignjs');
import FeignRequest = require('feignjs-request');
3. Define Apis in a declarative manner for microservices which we call using Feign using below syntax :
var apiDescription = {
saveValue : {
method : 'POST',
uri : '/createExchange'
},
getAllValue : {
method : 'get',
uri : '/getAllExchangeValues'
};
These are the apis of the the other microservices which we have to call to fetch data using Feign.
4. Instantiate feign client using the below syntax :
var client = feign.builder()
.client(new FeignRequest()).target(apiDescription, 'url');
url - URL of the another microservice to which call will be made.
5. Make an actual call to required microservice :
Client declared above has now methods with their endpoints to make calls. Syntax for invoking the methods is given below :
Syntax :
client.method(
[path-parameters],
[body/query/post-parameter-object],
[callback-function]
);
Example:
client.saveValue({ 'conversionMultiple':req.body.conversionMultiple,
'currencyFrom':req.body.currencyFrom,
'currencyTo':req.body.currencyTo},
{Xtoken:token}
).then(function(result, error){
if(error){
res.send(JSON.stringify(error));
}else{
res.json(result);
}
});
In method call, we have passed the path-parameters and one body object required for the call.
Result will be rendered as json into response object and in case of error, an error message will be sent as string format.
In this way, we can implement Feign both in java and nodejs.
We will discuss how to register microservices with Eureka in nodejs and other stuff also.
Thanks
Shiv Kumar