WEBVTT

00:00.320 --> 00:02.900
All right, so we refactored our JWT auth guard.

00:02.900 --> 00:07.430
Let's do the same thing for our reservations service now.

00:07.550 --> 00:13.850
So we'll go into our reservation service and this is going to follow a very similar pattern where currently

00:13.850 --> 00:16.040
we're calling out to the payment service.

00:16.070 --> 00:23.180
We're going to follow the same pattern we did in the auth guard to properly inject the payment service

00:23.180 --> 00:25.550
in this reservation service.

00:26.230 --> 00:37.060
So let's start off by making sure we implement on module init and then we'll declare this private payment

00:37.060 --> 00:42.340
service of type payments, service client.

00:42.550 --> 00:47.710
And now let's go ahead and change the injection token to be payment service name.

00:48.310 --> 00:55.600
I'll change the name to be client and the type to be client gRPC from Nestjs Microservices.

00:56.770 --> 01:03.880
Now, just as we've done before, we'll implement on module init and set this dot payment service equal

01:03.880 --> 01:08.380
to this dot client dot get service.

01:08.410 --> 01:16.180
I'll pass in the payment service client and we'll pass in the payments service name which we can see

01:16.180 --> 01:17.620
is payment service.

01:17.620 --> 01:21.580
Just a simple string which matches our proto definition.

01:21.940 --> 01:27.560
So just as we did in the auth guard, instead of calling dot send, we're actually going to call the

01:27.560 --> 01:34.040
method on the payment service, which will be create charge and we can get rid of the first argument.

01:34.070 --> 01:40.130
We'll simply just include all of the arguments that the Create charge method expects.

01:40.250 --> 01:47.030
Lastly, I'll go ahead and remove all of the unused imports and now our reservation service is properly

01:47.030 --> 01:49.220
refactored to utilize gRPC.

01:51.620 --> 01:59.090
All right, so it's time to actually configure our reservations module to set up gRPC and change from

01:59.090 --> 02:03.030
TCP to gRPC in our clients module.

02:03.050 --> 02:09.260
Let's go ahead and firstly change our transport to now be transport gRPC.

02:10.620 --> 02:13.020
And then our options are going to change.

02:13.020 --> 02:19.410
So instead of a host in port, we now need to specify the package that we want to connect to in our

02:19.410 --> 02:21.410
gRPC proto definition.

02:21.420 --> 02:29.610
So this is where we're going to use the auth package name constant exported from our OTS.

02:29.640 --> 02:34.410
Thanks to TS Proto, the package will automatically be exported as a const for us.

02:35.160 --> 02:42.300
Next up, we need to specify the proto path which is going to be the path to the proto file which our

02:42.300 --> 02:47.220
application will use to actually run our gRPC server.

02:47.220 --> 02:55.770
So to do this we're going to use the join function that we import from path up top.

02:57.170 --> 03:00.830
And now let's specify the path to our proto file.

03:00.830 --> 03:04.340
So the first argument will be the current directory name.

03:04.340 --> 03:11.390
And then from here we're going to go up three directories into proto slash author Proto.

03:11.540 --> 03:17.870
Now later on we're going to refactor our Docker file for our reservation service so that we actually

03:17.870 --> 03:25.100
copy over the necessary protos and that this path will be actually available when our container is running.

03:25.220 --> 03:31.970
Finally, we're going to specify a URL, which is going to be the URL to the actual auth service running

03:31.970 --> 03:32.990
on gRPC.

03:33.350 --> 03:37.730
So in our case we can actually get this from the config service.

03:37.760 --> 03:44.180
We'll call, get or throw and then call auth grpc URL.

03:44.690 --> 03:48.410
So now let's go into our M file for the reservations.

03:48.410 --> 03:55.910
And now instead of the auth host and port, we can change this to be the auth underscore gRPC underscore

03:55.940 --> 04:01.620
url and we'll set this equal to auth colon 5001.

04:01.620 --> 04:07.500
So auth will be the name of our Docker container which we know we set in our Docker compose, which

04:07.500 --> 04:15.030
is the host name of the container and the port here 5001 will be the default port that our gRPC server

04:15.030 --> 04:17.760
will be running on in each of our containers.

04:18.410 --> 04:23.000
So now we've correctly set up the auth service in the reservations module.

04:23.000 --> 04:25.880
Let's go ahead and do the same exact thing for the payment service.

04:25.880 --> 04:34.280
Now we'll change the transport to gRPC and let's go ahead and just copy the existing options we just

04:34.280 --> 04:36.890
set up and we'll paste this in.

04:36.920 --> 04:44.210
We just need to change the package name now to be the payments package name from App slash Common and

04:44.210 --> 04:48.380
then the path of the Proto will now be the payments dot proto.

04:49.220 --> 04:58.760
Finally, instead of the auth gRPC URL, we'll specify we want the payments gRPC URL and we'll add this

04:58.760 --> 05:02.930
to our move and replace it just like we did before.

05:03.080 --> 05:08.990
So now let's say that the payments gRPC URL will be equal to payments, which is the name of our Docker

05:08.990 --> 05:11.930
container on Port 5001.

05:12.860 --> 05:16.610
All right, so this is everything we have to do to configure our clients module.

05:16.610 --> 05:23.430
Let's now go inside of the Docker file where we're going to add the appropriate line to actually copy

05:23.430 --> 05:26.310
the proto from the root of our project.

05:26.310 --> 05:32.580
So we need these proto copied over into our Docker container so that they're available during runtime.

05:33.570 --> 05:35.130
So this is super easy to do.

05:35.160 --> 05:40.530
We'll just run a copy command and copy from proto to proto.

05:41.900 --> 05:45.020
So this is everything we have to do in the reservation service.

05:45.050 --> 05:54.140
Let's now go into the payments service where we will now refactor this to be compatible with our gRPC

05:54.170 --> 05:55.430
implementation.

05:55.700 --> 06:05.030
So firstly, in the payment service, let's declare a new private notifications service of type notification

06:05.030 --> 06:06.590
service client.

06:07.070 --> 06:15.590
And we'll also go ahead and refactor our constructor so that we're injecting the notifications service

06:16.220 --> 06:26.030
name from app slash common and we'll change the private read only client to a client gRPC from Nestjs

06:26.030 --> 06:27.380
Microservices.

06:27.560 --> 06:32.510
Next up, we need to refactor our call to create to the Stripe API.

06:32.540 --> 06:37.730
So right now we're just supplying the card object from the payments crate charge DTO.

06:37.760 --> 06:44.150
However, remember that we refactored this to be compatible with gRPC and actually changed expiration

06:44.150 --> 06:49.240
month and expiration year to be camel case instead of using underscores.

06:49.250 --> 06:52.560
So we need to map this back now in the service layer.

06:52.580 --> 07:00.140
So I'm going to set the card equal to an object and explicitly set all the properties on the card from

07:00.140 --> 07:01.940
the card itself.

07:01.940 --> 07:08.100
So first we have the card CVC, and we have the number from the card number.

07:08.120 --> 07:16.400
Now we're going to map the expiration underscore month to the card dot x month and x year said equal

07:16.400 --> 07:19.730
to card dot x year.

07:21.890 --> 07:27.890
So now we've properly mapped the DTO to what the Stripe API expects.

07:28.070 --> 07:32.570
So next up, we need to actually set the notification service.

07:32.570 --> 07:35.300
Now let's go ahead and do this directly in the method here.

07:35.300 --> 07:40.910
We can check to see if the notification service is not set.

07:40.940 --> 07:42.470
We'll go ahead and set it right now.

07:42.470 --> 07:51.080
So let's set the notification service equal to this dot client dot, get service, pass in the notification

07:51.080 --> 07:58.310
service client, and then we'll pass in the notification service name as the service that we want to

07:58.310 --> 08:00.710
get using the gRPC client.

08:00.830 --> 08:06.860
So now instead of emitting, which we cannot do with the gRPC client, we're directly going to call,

08:06.860 --> 08:12.920
notify email on this method and get rid of the first parameter and keep everything else.

08:13.850 --> 08:20.960
Additionally, this is still going to be a cold observable so that we need to actually subscribe to

08:20.960 --> 08:25.410
the return type if we want this to actually get executed.

08:25.410 --> 08:26.820
So let's go ahead and do that.

08:26.820 --> 08:33.090
We'll subscribe directly to the observable and just leave an empty function so that our function here

08:33.090 --> 08:37.170
still will get executed because we are subscribing to the observable.

08:37.380 --> 08:43.770
Now, I set the notification service like this opposed to using on module net because I wanted to show

08:43.770 --> 08:49.080
you that we can do this at runtime when the application is running and it doesn't always have to be

08:49.080 --> 08:52.410
done in on module init like we've done before.

08:52.680 --> 08:58.650
So finally we can go up to the top and remove some dependencies that we're no longer using.

08:58.650 --> 09:05.670
Now let's go into the payments module where we will refactor the register async call as we did before.

09:05.670 --> 09:12.060
So we're going to make sure we change the transport to be using gRPC and let's go ahead and change out

09:12.060 --> 09:13.140
our options.

09:13.140 --> 09:19.830
So firstly we'll have the proto path which will use Join again to help us out with finding the correct

09:19.830 --> 09:20.640
file.

09:20.640 --> 09:23.610
So we'll pass in the directory name as first argument.

09:24.640 --> 09:35.080
And now let's go up three directories to proto slash notifications dot proto to find the correct proto.

09:35.800 --> 09:42.640
Next for the package we're going to target the notifications package name from app slash common and

09:42.640 --> 09:53.350
then the url we will use config service dot get or throw and ask for the notifications grpc url.

09:53.590 --> 09:57.600
So let's go ahead and make sure we actually set this in our dot env.

09:57.610 --> 10:05.740
So instead of the notifications host and port, we'll use the notifications gRPC url and set this equal

10:05.740 --> 10:11.350
to notifications which is the name of our Docker container on port 5001.

10:12.650 --> 10:18.290
Okay, so now in the payments controller, we're going to use the decorators provided by Proto, which

10:18.290 --> 10:25.160
is going to make sure that Nestjs will know how to map incoming messages using gRPC to these actual

10:25.160 --> 10:25.940
methods.

10:25.940 --> 10:29.410
So previously we've utilized the message pattern decorator.

10:29.420 --> 10:36.680
However, we can get rid of this and just utilize the proto decorators which we will add now.

10:36.680 --> 10:44.690
So to do this we only need to add one decorator and that's going to be the payments service controller

10:44.690 --> 10:50.420
methods and we can change this import to be from app slash common.

10:51.380 --> 10:58.640
And now with just this one decorator Proto will automatically add all the necessary metadata to our

10:58.640 --> 11:04.370
functions in here so that when the incoming message using gRPC comes into this controller, it will

11:04.370 --> 11:08.960
go to this correct function and we can even get rid of the payload decorator here.

11:08.960 --> 11:15.110
We don't need this because Proto will automatically be providing us with the correct arguments.

11:15.120 --> 11:20.910
Now finally, to make sure that the controller is type safe and that we actually don't forget any methods

11:20.910 --> 11:25.800
that are gRPC proto definition expects on this payments controller.

11:25.830 --> 11:31.380
We can actually make sure we implement the payments service controller.

11:31.500 --> 11:36.000
And now let's say for example, we forgot to implement create charge.

11:36.000 --> 11:41.850
The payments controller would complain because the payment service controller makes sure we implement

11:41.850 --> 11:44.970
everything defined in our proto definition.

11:44.970 --> 11:47.160
In this case the create charge method.

11:47.160 --> 11:49.170
So this will make our code type safe.

11:49.170 --> 11:55.320
Now next up, let's go to our main.ts in the payments service where we're going to refactor the connect

11:55.320 --> 11:56.670
microservice call.

11:56.670 --> 12:04.110
So instead of TCP, now we're using gRPC and the options we're going to provide here are going to be

12:04.110 --> 12:10.560
the same exact options we've already provided to the reservation module so we can simply copy these.

12:10.560 --> 12:17.780
Let's go ahead and copy these and we'll paste them in to our current options object.

12:17.810 --> 12:24.050
I'll import the payments package name and change this import to be from app slash common.

12:24.380 --> 12:26.510
Make sure we import join.

12:27.370 --> 12:29.950
And now we need to make sure we have the payments.

12:29.950 --> 12:33.110
gRPC URL correctly configured.

12:33.130 --> 12:35.560
So let's go ahead and add that payments.

12:35.560 --> 12:40.180
gRPC URL equal to payments 5001.

12:43.890 --> 12:48.780
Finally, let's go into our Docker file for payments and make sure we do just the same as we did for

12:48.780 --> 12:50.640
the Reservations Docker file.

12:51.480 --> 12:57.480
We need to copy over the proto from the root of our folder into our container so that it's available

12:57.480 --> 12:58.590
during runtime.

12:59.010 --> 13:05.880
Now let's also go into our notifications controller and follow the same pattern that we just implemented.

13:05.880 --> 13:13.200
So we're going to decorate the notifications controller with the notifications, service controller

13:13.200 --> 13:17.580
methods from app slash common.

13:17.970 --> 13:23.070
So as we've seen before, this is going to make sure that all the correct metadata is added to these

13:23.070 --> 13:24.000
methods.

13:24.120 --> 13:31.320
Next up, we'll make sure that we are implementing the notification.

13:32.790 --> 13:39.390
Service controller so that our code is type safe and that we can go ahead and get rid of the event pattern

13:39.390 --> 13:43.090
decorator and remove the payload decorator as well.

13:43.110 --> 13:49.220
Now, as I said before, we're still going to have validation on all of our methods in our microservices,

13:49.230 --> 13:50.790
even though we're using gRPC.

13:51.090 --> 13:56.760
Thanks to Class Validator and our validation pipe we're using here all of our pipes, interceptors,

13:56.760 --> 13:59.700
middleware, everything will still work, just as it did before.

13:59.700 --> 14:06.660
And our notify email DTO with the class validator decorators, we will still have validation applied.

14:06.660 --> 14:09.750
Even though we're using gRPC, nothing will change.

14:10.680 --> 14:16.500
So we can lastly go ahead and just remove these unused imports that we are no longer using.

14:16.980 --> 14:24.210
And let's go into the Main.ts for notifications now and refactor the transport to be in gRPC.

14:24.540 --> 14:31.110
And now we can go to the payments module and copy the options that are used currently to connect to

14:31.110 --> 14:32.920
the notifications service.

14:32.920 --> 14:43.510
And let's just paste these in here so that we are finding the proto for notifications and we are targeting

14:43.510 --> 14:45.760
the notifications package name.

14:45.880 --> 14:49.030
We can change this import to be from app slash common.

14:49.030 --> 14:54.940
And finally in our Env, let's make sure that we have the notifications.

14:54.940 --> 15:00.310
gRPC URL set equal to notifications 5001.

15:01.420 --> 15:07.780
Now finally, don't forget in our Docker file, just as we've done before, we will copy the proto into

15:07.780 --> 15:09.580
our current running container.

15:10.730 --> 15:18.590
Now, one thing we want to add to our existing JWT strategy is actually adding an extra question mark

15:18.590 --> 15:24.350
here on line 19 to check to see if there are headers being passed at all, because in our case with

15:24.350 --> 15:26.150
gRPC, there are no headers.

15:26.150 --> 15:31.100
So this will fail if we don't check to see if headers is defined first before accessing it.

15:32.420 --> 15:39.170
Now that we've done that, let's go to our main.ts for auth and change the transport here to be gRPC.

15:39.200 --> 15:40.880
As we've already done before.

15:41.000 --> 15:48.200
And we can go back to the reservations module and copy all of these options and paste them in to the

15:48.200 --> 15:54.620
options object here and simply import everything we need from app slash common to correctly configure

15:54.620 --> 15:56.810
this gRPC microservice.

15:56.840 --> 16:05.240
I'll make sure I import everything correctly and then we can replace the TCP port with the auth gRPC

16:05.270 --> 16:09.290
URL, which we know will be auth 5001.

16:10.760 --> 16:18.260
Next up, let's go into the auth controller where we will decorate this with the auth service controller

16:18.260 --> 16:20.720
methods from app slash common.

16:21.140 --> 16:28.040
We can also implement the auth service controller to make sure we're type safe and implementing all

16:28.040 --> 16:31.310
of the gRPC methods that we expect to be.

16:32.300 --> 16:39.290
And then we will refactor our authenticate methods so we can remove the existing message pattern and

16:39.290 --> 16:44.750
we still want to pull the payload off of authenticate because by default we're not going to be supplied

16:44.750 --> 16:50.280
this by Proto because it doesn't expect this to be coming in from our local strategy.

16:50.300 --> 16:57.050
And now instead of returning the data dot user, we want to return an object where we spread everything

16:57.050 --> 17:04.130
on the incoming user, which of course, if you remember, is being provided from our JWT strategy.

17:04.460 --> 17:12.480
Now the only difference is we need to explicitly set the ID property here from the data dot user dot

17:12.480 --> 17:16.500
underscore ID because gRPC will not allow underscores.

17:16.500 --> 17:22.140
We need to make sure we're mapping the ID properly here when we're passing it over the wire.

17:22.920 --> 17:27.270
Let's go ahead and remove all of our unused imports as well.

17:27.630 --> 17:35.070
And then we'll go into the Docker file and copy over the proto definition so that auth has access to

17:35.070 --> 17:35.610
them.

17:35.730 --> 17:42.000
Now, since we've refactored to no longer require certain environment variables, let's go to our payments

17:42.000 --> 17:48.210
dot module and remove the notifications, host and port as required environment variables as well as

17:48.210 --> 17:51.690
the port itself, which we no longer are utilizing.

17:51.840 --> 17:55.050
We'll go ahead and do the same thing in the reservations module.

17:55.050 --> 18:02.220
We can get rid of all of the host and port environment variable validations that we're currently using

18:02.490 --> 18:06.450
and let's go ahead and do the same thing in the auth dot module.

18:06.450 --> 18:14.100
We'll get rid of the TCP port and in the notifications module we can also remove the port which we no

18:14.100 --> 18:15.660
longer are utilizing.

18:16.740 --> 18:22.350
Now, finally, we need to change the injection tokens that we're currently using instead of these injection

18:22.350 --> 18:23.910
tokens that we've defined.

18:23.940 --> 18:28.140
We're going to use the ones from TF Proto, which we are using inside of our services.

18:28.140 --> 18:36.420
So for the auth service, this will be auth service name from app slash common and payments service

18:36.450 --> 18:38.730
name from app slash common.

18:47.460 --> 18:55.260
Now, finally, let's go ahead and change the injection token from notifications to notifications service

18:55.260 --> 19:02.430
name, which is the injection token we're using inside of the payments service, which matches this

19:02.460 --> 19:05.220
injection token we have in the constructor.

19:05.400 --> 19:09.630
So now at this point, we're ready to go ahead and rebuild our containers.

19:09.630 --> 19:17.250
So firstly I'm going to run NPM install dash R to recursively install all dependencies in our packages

19:17.250 --> 19:25.410
to make sure we're up to date and then I'll run and end to run Docker, compose up dash dash build,

19:25.410 --> 19:31.140
which is going to rebuild all of our containers and make sure we have the most up to date dependencies

19:31.140 --> 19:33.330
provided to our containers.

19:33.330 --> 19:37.020
So go ahead and let this command finish running.

19:37.890 --> 19:44.520
Okay, so now I can see all of my microservices have started up successfully and we can test out our

19:44.520 --> 19:45.590
functionality.

19:45.600 --> 19:53.740
So open up postman and we'll firstly launch a post request at localhost 3001 slash users to firstly

19:53.740 --> 19:57.220
create a new user with an email and password.

19:57.490 --> 20:05.410
So I've created a new user and I will then launch a request at auth slash login to actually log in and

20:05.410 --> 20:06.820
get our JWT set.

20:06.850 --> 20:14.800
Next I'll launch a reservations request, a localhost 3000 slash reservations and send our typical payload

20:14.830 --> 20:17.080
to create a new reservation.

20:17.080 --> 20:23.110
I'll change the amount here to be $60 and send this off to create the reservation.

20:23.320 --> 20:28.060
You can see we have a 201 created that has come back with the reservation.

20:28.630 --> 20:34.960
And now if I go up to my browser and navigate to the Stripe dashboard, I'll go ahead and refresh.

20:34.960 --> 20:39.340
You can see we have that $60 payment that has just come into the system.

20:39.340 --> 20:41.830
So our payment service is working properly.

20:41.830 --> 20:50.860
And if I go to my email I can see I have a payment of $60 that has completed successfully from Sleeper.

20:50.860 --> 20:55.870
So our notifications microservice is also working properly.

20:55.870 --> 21:00.040
So now we fully refactor our application to work with gRPC.
