Okay, So next up, we're going to look at using Rabbitmq as our transport mechanism to communicate
between our microservices.
Now, of course, right now we know that we're using the TCP transport mechanism.
However, there are also some downsides to using the TCP transport opposed to an asynchronous messaging
transport like Rabbitmq.
Now, to actually show the disadvantage of using the TCP microservice, let's go to the payments microservice
and in the payments controller, when we receive the request to create a chards, let's immediately
throw a dummy error here so that we will always throw an error and never actually create the charge.
And then let's go ahead and open up Postman to create a reservation to see what happens.
So in Postman, I'll launch a request at the auth slash login root first with a created user to obtain
a JWT and then we'll go ahead and execute an a request to create a reservation.
So this is the typical payload that we would have to create a reservation.
Now, of course, we're getting back a 500 internal server error because when the reservations microservice
tried to reach out to the payment service, we can see that it threw an error here and the reservation
service immediately failed.
So this is showing the problem with the TCP microservice.
There's no way to retry any sort of failed messages in our system, and our messages can't be queued
up one behind one another.
So if we have a massive influx of messages into our system, our system can become overloaded and we
can't respond gracefully.
If we need to retry a message, we immediately throw this error and then this payments request is never
retried because there's nowhere to actually save that message.
Now, using an asynchronous microservice like Rabbitmq, we have the idea of a queue that is introduced
so a queue will hold our messages until they're ready to be processed.
So if there's a large backlog of messages, we can handle them one at a time.
And additionally, if we fail to process a message, we can put it back on the queue and keep trying
until potentially this error is resolved and we don't actually lose that message.
So that's the big difference with something like Rabbitmq.
Let's go ahead and implement it now to see how we can take advantage of these asynchronous benefits.
So as I've done in previous lectures, we're going to have the completed portion of this in a new branch
called Rabbitmq.
So if you want to see the completed code in Rabbitmq, you can just check out this branch and follow
along there.
I'll be working off of the main branch to start and we can integrate Rabbitmq off of the main branch.
Firstly, we're going to go ahead and install some new dependencies.
So let's go ahead and NPM install amp, shp lib and then amp shp connection manager.
Now, since we're using Nestjs microservice library, it's going to be very easy to swap out our transport
layer without having to change any of our underlying code, which is going to be great.
So let's start off by going to our Docker compose where we can define a new service to actually run
a rabbitmq cluster that we can connect to from our application.
So let's go ahead and define a new Rabbitmq service underneath our Mongo service.
And this will be the image of Rabbitmq, which is going to be the official Rabbitmq image from Docker
Hub.
And then for the ports, we're going to expose the default port on Rabbitmq five, six, seven two on
our local host machine of 5672.
So now when we start up our Docker compose, we will start up this rabbitmq image that we can connect
to.
Let's go ahead and get started with our auth microservice.
That will change over to Rabbitmq.
We'll open up the Main.ts in the auth service and we'll go ahead and change the transport out for our
MQ.
And now we need to specify a new set of options.
So instead of a host and port, we're now going to provide an array of URLs which is going to be the
different brokers that we want to connect to.
In our case we only have one, so we will use the config service to get or throw, which will throw
an error if this environment variable is not found and we will look for the rabbitmq Uri.
So this is the connection string.
And then we need to specify the actual name of the queue that we're going to be using in this service
and then others will be able to produce messages too.
So this queue is where the messages will go to to be consumed from in this service.
And if any messages need to be retried, they will be put back on this queue.
So let's go ahead and specify the name of auth to specify the auth queue.
Next up, we can update our dot m file in the auth service to have this new Rabbitmq Uri.
So let's go ahead and add it underneath our MongoDB Uri.
We'll add the Rabbitmq Uri which will be equal to Amqp colon slash slash Rabbitmq the name of our Docker
compose service.
And then the port of five, 672.
And that's all we have to do to switch out for Rabbitmq In our auth controller, we still use the same
decorators to extract data because of this platform agnostic way that Nestjs implements its microservices.
This will still work just as it did before.
Next up, let's go to the notification Service where we can refactor the main.ts in the same way we
can actually just copy out this options from connect microservice in auth and in the Notification service.
We'll paste this in, we'll change out the name to notifications instead.
Well then go ahead and update the env as well to have that rabbitmq uri.
So let's go ahead and just copy it over from the dot env and auth.
Next up we'll go into our payment service and do the same thing there.
So we'll copy the options from connect Microservice and swap it out in the main.ts.
We'll call this queue the payment queue and then in our dot env we will provide the Rabbitmq connection
string, which again I'll copy over and paste it in.
Now in the payment service we also have to go back into the payments module where we're registering
our clients module to connect to the notification service.
We have to specify that the transport layer has changed to MQ and then we need to specify the options
here to connect to the notification service.
So this will be the just the same as the Main.ts.
So let's go ahead into our notifications Main.ts and copy these options where we get the Rabbitmq connection
string and the name of the queue that we want to produce to.
So in this case we know it's notifications and then we'll provide a type to our config service here
to make the type happy.
And now all that's left is to go to the reservation service and update our reservations module client
modules where we're registering the auth service and the payments service.
We're going to go ahead and change out the transport layer as we've done before and then we'll paste
in our familiar options to connect to the Rabbitmq cluster and the queue name.
So the queue name here will be auth and we'll provide that.
This is a string and let's go ahead and do the same thing for payments.
This is very easy to do.
Rabbitmq Paste in our options, change this to a string and make sure our queue name is payments.
Now lastly, we also have to add the Rabbitmq Uri to our EMF file in the reservation service.
So let's go ahead and copy one of our existing ones and paste it in so that our reservation service
can connect to the Rabbitmq cluster.
So now, without having to change any of our underlying code, we already have moved all of our services
over to Rabbitmq.
We're producing messages to rabbitmq queues that will be consumed and we don't have to do anything else.
So let's go ahead and rerun our project.
So in order for our images to download the latest Rabbitmq dependencies, we can run Docker, compose
up and make sure you run dash, dash, build so that your images get rebuilt with the new dependencies
required.
So once your images have rebuilt, you can see that our containers are starting up.
And importantly, we have the rabbitmq image that has also started and is listening for TCP connections
and 5672.