2

I have multiple artifacts (applications) deployed on different hosts (let's call them A, B, and C for simplicity) and I am currently looking for some kind of integration pattern, because I need to reduce the number of calls to the backend, so that I don't need separate calls to A, B and C, but rather one call to D which collects all the information and returns it to the client. I think of it as some kind of aggregator application.

I have read Sam Newman's book about Microservices and I am trying to implement something which is in accordance to the pattern "Backend for frontends", which means that every channel (mobile, web) has its own RESTful interface. He also talks about internal calls, but not about implementation details.

I use Java (RestEasy) for all applications, and I thought about using Retrofit for sending internal calls, which could solve some of my problems. Are there any other frameworks I should review?

Moreover, I would like to have some kind of automatic re-routing in place and I don't know if this is the way to go. I try to explain it by an example: there is an endpoint GET /customer/username/sometool/instructions which can be consumed by verified users only. If a customer is not verified, the endpoint should return information about the upgrade which could be retrieved by calling GET /customer/username/verification. So I thought about different options:

  1. /customer/username/sometool/instructions returns an exception, the exception mapper reads the errorcode (something like "customer not verified") and exception mapper knows that it has to collect the information from /customer/username/verification -> downside: exception mapper will become almighty over time
  2. /customer/username/sometool/instructions checks if customer is verified already, and if not it calls /customer/username/verification and collects the information -> downside: adds logic to instructions endpoint that does not really belong to instructions
  3. an aggregator module that works with annotations which are intercepted before the MessageResponseWriter is invoked. Something like: @OnFailure(errorCode="notverified" invoke="/customer/username/verification") -> downside: again, aggregator will become almighty

How do you think this should be implemented?

migrated from stackoverflow.com May 2 '17 at 9:38

This question came from our site for professional and enthusiast programmers.

  • You can rely on Event driven Architecture in addition to your microservices deployment. Where all the micro-services are connected by Cloud Bus using Spring Cloud Api (Pivotal, Aws, Azure) by registering with discovery services like Eureka Services and create an Event layer (Which will serve as a caching layer as well) and Send push notifications to your microservices through a topic (Preferably kafka topic). – Praveen Kumar K S May 2 '17 at 9:31
  • I think the key word from @Praveen's answer is 'caching'. Don't aggregate, just make sure you use caching to reduce load on the back end. – Richard May 2 '17 at 10:03
  • Why is it important to reduce calls in exceptional situations? – Erik Eidt May 2 '17 at 14:19
  • I will create a proof of concept using Apache Kafka. If i got you right, there is a gateway service, which collaborates with the underlying microservices by emitting events (topics) which are subscribed by certain microservices. I can image how this works if the underlying service needs to be notified only, but not how it works if the gateway needs to wait for the different parts of information. Or is this (orchestration) an antipattern already? – Daniel May 2 '17 at 16:56
  • @ErikEidt because we don't want to send consecutive calls from mobile devices to the backend, because of the delay which would be caused. Neither do we want to send multiple calls simultaneously (to collect the information from different endpoints) – Daniel May 2 '17 at 17:00
2

It sounds like the pattern you are looking for is API Gateway. Sometimes also called "Edge" or "EdgeService". It can be used to as a single entrypoint to your cluster and to aggregate service call results. Other use cases include central authentication and/or authorization as well as routing, monitoring and resiliency.

Some people only route external calls through a gateway, others route also internal calls through the gateway.

Here some technologies to look into:

Zuul from the Netflix stack. You have write a filter for aggregation.

Amazon API gateway - If you are running on AWS (very convenient if you use Lambda).

Kong.

1

A pattern for your 1st requirement to reduce the calls to the backend (A,B&C) is not as much an integration pattern but usually called 'Facade', which simply means that there's one easy to understand interface that provides operations that make sense for a given client, like a mobile app. That facade internally can then orchestrate calls to other modules or systems (A,B&C) in order to fulfil it's duties. You might also find this often called a Mediator, which in addition to the simple facade fulfils mapping from and into different data structures (client vs. server side structures).

Since you want to use a REST API you should not implement logic for client authentication on the server but on the client side. The Restful server API interface means it does not care for state on the server, i.e. does not know if a client is authenticated or not unless the client passes information in that indicates that, like a token or secret etc. The routing in the error case should be implemented at client level. There's a lot of Angular2 examples out there that show this kind of implementations.

Your fear of a error mapper becoming too mighty are not really valid if you implement the client in a modular fashion, i.e. different controllers that are responsible for sending/receiving information for a portion of the app. They should have a very explicit error management and since they're just responsible for certain aspects of the app should not grow too excessively.

I hope that helps you a bit starting with your system!

Regards, Lars

  • Hi Lars, thanks for your answer. I thought about avoiding orchestration in favour of choreography. But I do see what you mean - I will try to use an event-driven approach for this. oAuth2.0 authentication is already in place. – Daniel May 3 '17 at 7:24
0

I want to warn you against data sharing via events. Very soon you'll cease realizing who is an owner of any given piece of data. The single source of truth for your data will inevitably get vague.

Event-driven architecture uses events to notify other services what happened, so they can start their own processes. Events were never meant for data transmitting. Very often it means that service boundaries are wrong. Though I realize that your question is about frontends, you'll probably find the post stressing my point a useful read.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.