I am planning to create a microservice aplication with a dedicated service for dealing with data (mostly a Mongodb based service). I am wondering if there is a way using which my other microservices will be able to communicate with this service to make use of the shared data. Is it possible with JHipster API Gateway ? If not how can I achieve this. I dont want to keep multiple copies of the same data within each microservice.
Because microservices are distributed and microservices communicate with each other by inter-service communication on network level. Each microservice has its own instance and process. Therefore, services must interact using an inter-service communication protocols like HTTP, gRPC or message brokers AMQP protocol.
One microservice can easily expose a REST endpoint for other microservices to call it. Integration via RESTful endpoints is typically implemented when a microservice needs to call another and receive an immediate (synchronous) response.
A Kafka-centric microservice architecture uses an application setup where microservices communicate with each other using Kafka as an intermediary. This is achievable thanks to Kafka's publish-subscribe approach for handling record writing and reading.
The JHipster microservices architecture works in the following way: A gateway is a JHipster-generated application (using application type microservice gateway when you generate it) that handles Web traffic, and serves an Angular/React application.
Microservices are a type of JHipster application, that have no front-end (the Angular front-end must be generated on a gateway), and which work with the JHipster Registry to be configured, discovered, and managed.
JHipster Registry starts on port 8761 by default. In a new terminal window, navigate to jhipster-microservices-example/blog and run ./mvnw to start the blog application and open http://localhost:8080 in your favorite browser. The first thing you’ll notice is a dapper-looking fellow explaining how you can sign in or register.
The JHipster Registry is an essential piece of the microservice architecture. It ties all the other components together and enables them to communicate with each other. The Microservice Application contains the back-end code. Once running it will expose the API for the domain it is concerned with.
You can also use Feign clients with JHipster.
Annotate your SpringBootApplication
with @EnableFeignClients
...
import org.springframework.cloud.openfeign.EnableFeignClients;
...
@SpringBootApplication
@EnableConfigurationProperties({LiquibaseProperties.class, ApplicationProperties.class})
@EnableDiscoveryClient
@EnableFeignClients
public class MyApp {
...
}
Create a Feign client in your microservice
...
import org.springframework.cloud.openfeign.FeignClient;
...
@FeignClient("another-service")
public interface AnotherClient {
@RequestMapping(method = RequestMethod.GET, value = "/api/another")
List<AnotherDTO> getAll();
}
Inject the Feign client with @Autowired
and call it. It should be ready to use.
@RestController
@RequestMapping("/api")
public class MyResource {
...
@Autowired
private AnotherClient anotherClient;
...
@GetMapping("/another")
@Timed
public List<AnotherDTO> getAll() {
log.debug("REST request to get all");
return anotherClient.getAll();
}
}
For us, it worked without implementing a ClientHttpRequestInterceptor
and setting a JWT token.
You can register your microservices to the same registry and then they can call each other.
UPDATE : Here is how I made it work. In the microservice consuming the data one, use RestTemplate with the current user's jwt-token in the Authorization-header for the API calls :
@Component
public class AuthenticateClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
String token = SecurityUtils.getCurrentUserJWT();
httpRequest.getHeaders().add("Authorization","Bearer "+token);
return clientHttpRequestExecution.execute( httpRequest, bytes );
}
}
My custom restTemplate using ClientHttpRequestInterceptor for adding token in header.
@Configuration
public class CustomBean {
@Autowired
AuthenticateClientHttpRequestInterceptor interceptor;
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(Collections.singletonList(interceptor));
return restTemplate;
}
}
And in the resource controller where your are making the call for data:
@RestController
@RequestMapping("/api")
public class DataResource {
@Autowired
RestTemplate restTemplate;
@PostMapping("/hello")
@Timed
public ResponseEntity<Hello> createHello(@RequestBody Hello Hello) throws URISyntaxException {
//The name your data micro service registrated in the Jhipster Registry
String dataServiceName = "data_micro_service";
URI uri = UriComponentsBuilder.fromUriString("//" + dataServiceName + "/api/datas")
.build()
.toUri();
//call the data microservice apis
List<Data> result = restTemplate.getForObject(uri, Data[].class);
return ResponseEntity.created(new URI("/api/hellos/" + result.getId()))
.headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, result.getId().toString()))
.body(result);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With