3

This is a follow-up question to my issue outlined here.

The Gateway serves as an entry point to the application, to which every request from the client is made. The gateway then allocates the request to the responsible microservices and also handles authentication.

In this case the gateway listens for HTTP POST /bok and notifies the Microservice A to create a book. Thus Microservice A ist responsible for managing and storing everything about the book entity.


The following pseudo-code is a simplified implementation of this architecture:

Queue Communication queue communication

Gateway

router.post('/book', (req, res) => {
  queue.publish('CreateBook', req.body);
  queue.consume('BookCreated', (book) => {
    const user = getUserFromOtherMicroService(book.userId);
    res.json({ book, user });
  });
});

Microservcie A

queue.consume('CreateBook', (payload) => {
  const book = createBook(payload);
  eventStore.insert('BookCreated', book);
  const createdBook = updateProjectionDatabase(book);
  queue.publish('BookCreated', createdBook);
})

But I am not quite sure about this because of the following reasons:

  1. The listener for consuming BookCreated in the Gateway will be recreated every time a user requests to create a new book
  2. What if 2 users simultaneously create a book and the wrong book will be returned?
  3. I don't know how to fetch additional data (e.g. getUserFromOtherMicroService)

That's why I though about implementing this architecture:

Direct and Queue Communication direct communication

Gateway

router.post('/book', async (req, res) => {
  const book = await makeHttpRequest('microservice-a/create-book', req.body);
  const user = await makeHttpRequest('microservice-b/getUser', book.userId);
  res.json({ book, user });
});

Microservice A

router.post('/create-book', (req, res) => {
  const book = createBook(req.body);
  eventStore.insert('BookCreated', book);
  const createdBook = updateProjectionDatabase(book);
  queue.publish('BookCreated', createdBook);
  res.json(createdBook);
})

But I am also not really sure about this implementation because:

  1. Don't I violate CQRS when I return the book after creation? (because I should only return OK or ERROR)
  2. Isn't it inefficient to make another HTTP request in a microservices system?
Florian Ludewig
  • 4,338
  • 11
  • 71
  • 137
  • i am bit confused to get what does gateway means here. normally gateway is api gateway or any application that can work as gateway. can you please explain what exactly are you trying to achieve? infact a business case you are trying to resolve? what each microservice you think will be doing? – Imran Arshad Jun 18 '19 at 21:05
  • I am sorry for the confusion, I've added a few lines at the top :) – Florian Ludewig Jun 19 '19 at 05:57
  • I think the issue here is the role of the gateway. It seems like the "gateway" in your case is a custom application that handles the orchestration and communication logic (i.e. publishing and consuming to/from the appropriate topics). Maybe you should try replacing the "gateway" in your diagram to a "Microservice", that may help you with deciding which is a better approach. – Seth Jun 19 '19 at 05:57
  • And if I would do this, which approach (1 or 2) would I take? – Florian Ludewig Jun 19 '19 at 05:59
  • I also forgot, that gateway should handle authentication – Florian Ludewig Jun 19 '19 at 06:09

1 Answers1

1

Based on the comments above .

Approach 1

In this case your api gateway will be used to drop the message in the queue. This approach is more appropriate if your process is going to take long time and you have a queue workers sitting behind to pick up the messages and process. But your client side has to poll to get the results. Say you are looking for airline ticket . You drop the message. Your get an ID to poll. Your client will keep on polling until the results are available.

But in this case you will have a challenge , as you drop the message how you are going to generate the ID that client would poll ? Do you assign the ID to message at Gateway and drop in the queue and return the same ID for the client to poll to get result ? again this approach is good for web/worker kind of scenario.

Approach 2

Since Your API gateway is custom application that would handle the authentication and redirect the request to respective service. Your Microsvc A would create book and publish the event and your Microservice B and C would be using it . Your Gateway will wait for the Microservice A to return response with ID (or event metadata of newly created object) of book that is created so you don't poll for it later and client has it. If you want you can have additional information from other microservices you can fetch at this time and can send aggregated response.

For any data that is available in Microservice A,B,C you will be getting via Gateway. Make sure your gateway is highly available.

Hope that helps . Let me know if you have any questions !

Imran Arshad
  • 3,794
  • 2
  • 22
  • 27
  • Alright, that makes total sense! What about CQRS... is it okay to return the newly created object? – Florian Ludewig Jun 19 '19 at 06:45
  • 1
    Do you have some reason to use CQRS? it's an awesome pattern but it has its own complexity. yes you can retunrn object with http staus code 201 created – Imran Arshad Jun 19 '19 at 06:49
  • You're probably right... it just adds unnecessary complexity. I may come back to you for further help, thanks! – Florian Ludewig Jun 19 '19 at 06:51
  • no worries. i am using CQRS. unless you have very specific reason then use it. else it could turn out to be anti pattern for your system – Imran Arshad Jun 19 '19 at 06:56