WEBVTT

00:00.320 --> 00:00.710
All right.

00:00.710 --> 00:08.030
So to get started integrating gRPC with our microservices, we're going to need to install some dependencies

00:08.030 --> 00:10.680
that Nestjs will use underneath the hood.

00:10.700 --> 00:12.110
To use gRPC.

00:12.680 --> 00:20.600
Now, as I've done, typically I'm going to keep the completed code for this gRPC work in a new branch

00:20.600 --> 00:22.490
called gRPC.

00:22.730 --> 00:29.780
So if you want to see the completed project with gRPC, you can check out this branch and follow along

00:29.780 --> 00:30.410
there.

00:30.650 --> 00:34.970
I'm going to check out the main branch and work off of this on a clean slate.

00:35.680 --> 00:39.100
So let's go ahead and get started by installing those dependencies.

00:39.100 --> 00:52.720
So I will run npm install, dash dash, save grab gRPC, slash gRPC, JS and gRPC slash proto loader.

00:52.960 --> 01:00.400
We're also going to install TS, proto TS Dash Proto, which is going to allow us to convert our Protobuf

01:00.400 --> 01:07.360
definition files, which is the shape of our data and services in a language that gRPC understands.

01:07.390 --> 01:13.480
It's going to allow us to convert those files into TypeScript code so that we don't have to keep duplicating

01:13.480 --> 01:14.290
all of that.

01:14.290 --> 01:19.290
And it's also going to allow us to integrate this in Nestjs very easily.

01:19.300 --> 01:22.930
So let's go ahead and let these dependencies finish installing.

01:24.010 --> 01:29.770
So now that we have our dependencies installed, let's go back to our project and we're going to create

01:29.770 --> 01:33.310
a new folder at the root of our project called Proto.

01:33.310 --> 01:38.960
And this is where the definitions, those protobuf definitions that I mentioned earlier, this is where

01:38.960 --> 01:40.430
we're going to host all of them.

01:40.430 --> 01:46.100
And this is going to be the data and services that act on those data.

01:46.100 --> 01:50.720
It's going to be a description of that in a language that gRPC understands.

01:50.840 --> 01:55.700
And the big advantage of using these files is that we can use them on any client.

01:55.700 --> 02:01.580
So whether it's our back end here, a mobile app, a web page, any application that wants to use these

02:01.620 --> 02:03.230
products can be shared.

02:03.230 --> 02:09.350
And we don't have to keep duplicating all of these types, which is a big benefit of using gRPC.

02:09.800 --> 02:14.420
So let's start off with defining the Proto for our auth service.

02:14.420 --> 02:17.540
I'm going to create an auth dot proto first.

02:17.870 --> 02:21.800
And to start off we need to define the syntax that we're using.

02:21.800 --> 02:28.220
So there's different Syntaxes for Proto, we can use proto two or proto three, we're going to use proto

02:28.220 --> 02:31.460
three because that's the most up to date version currently.

02:31.700 --> 02:39.620
And we specify this by running syntax equals quotes proto three and have a colon.

02:39.830 --> 02:44.540
Now if you notice I have syntax highlighting enabled on my VS code.

02:44.540 --> 02:51.710
If you'd like this as well, you can go to the extensions page and make sure you have the proto vs code

02:51.710 --> 02:57.080
proto three extension installed, which is what I'm using, which is going to allow us to have proto

02:57.080 --> 03:03.320
three support for VS code and give us IntelliSense highlighting directly, which is very useful.

03:03.320 --> 03:07.580
So next we're going to set the name of the current package we are using.

03:07.580 --> 03:14.570
So in this case we'll call it auth since we're defining the auth proto and then we define the service

03:14.570 --> 03:17.540
that we are going to be describing.

03:17.540 --> 03:23.450
So in this case we're going to be describing the auth service with all of the methods that are exposed

03:23.450 --> 03:24.860
on the auth service.

03:25.100 --> 03:29.420
Now you can think of this as the controller currently in our application.

03:29.420 --> 03:36.620
So if we go to the auth controller we have now that's using micro services, we have our one method

03:36.620 --> 03:40.700
here to authenticate over our micro services.

03:40.850 --> 03:47.990
So we want to describe that method here in the auth service definition by writing RPC to describe a

03:47.990 --> 03:49.640
remote procedural call.

03:49.880 --> 03:55.610
And then we can call it whatever we want, we're going to stick with the name authenticate and this

03:55.610 --> 03:58.760
is going to look very similar to a function definition.

03:58.760 --> 04:05.810
So we'll open up parentheses here where we can describe the parameters that this RPC method will take.

04:05.840 --> 04:12.200
In this case, we'll create a new type called authentication, and then we'll specify that this is going

04:12.200 --> 04:17.330
to return a user message and open up curly brackets.

04:17.330 --> 04:23.450
So this is our method that we've defined here and now we need to describe these types that we're using.

04:23.450 --> 04:30.920
So, so we do this by using the message keyword and then we will create an authentication message.

04:31.490 --> 04:35.480
And now we can describe all of the properties that exist on this message.

04:35.480 --> 04:43.100
So in our case, when we have a request that comes in to this authenticate route, we know what's going

04:43.100 --> 04:46.220
to be sent along with it is our JWT token, right?

04:46.220 --> 04:50.690
So we have currently our auth guard that's protecting this route.

04:50.810 --> 05:01.640
We know that the JWT auth guard is using the JWT strategy, which is going to be pulling the authentication

05:01.640 --> 05:04.580
or JWT off of the incoming request.

05:04.580 --> 05:11.450
So let's go ahead and describe this with an authentication property and then we're going to set this

05:11.450 --> 05:16.580
equal to one because all of our properties in our messages need to be ordered.

05:16.580 --> 05:21.860
So we'll describe this with the one number as the first property.

05:21.860 --> 05:27.350
Next we will describe our return type here, which is just going to be the user.

05:27.350 --> 05:33.710
So we have the user message and we will have a string that represents the ID of the user.

05:33.740 --> 05:35.210
Now we know in our application.

05:35.360 --> 05:37.460
The ID is going to be underscore ID.

05:37.730 --> 05:44.330
However, an RPC doesn't support the use of underscores, so we're going to have to use just an ID property

05:44.330 --> 05:48.230
here and then map this accordingly in our application.

05:48.440 --> 05:54.320
So let's go ahead and specify this as the first property and then we'll fill out the rest of our properties

05:54.320 --> 05:55.250
on a user.

05:55.280 --> 06:05.210
We know that we have the email, the password and of course we can reference the user schema if we need

06:05.210 --> 06:07.760
to be reminded of all the properties on the user.

06:08.000 --> 06:10.130
Of course we have the roles as well.

06:10.130 --> 06:18.050
So to describe an array in gRPC, we can use the repeated keyword which says that this property will

06:18.050 --> 06:21.710
be repeated in an array and we'll set this equal to four.

06:21.710 --> 06:25.010
So it's a repeated string where we have our roles.

06:25.010 --> 06:32.360
So this is all we have to do for our auth Proto, we have all of the methods for our auth service defined

06:32.360 --> 06:34.670
and all of the types that we're going to be using.

06:34.670 --> 06:37.470
So next we can move on to our other Proto.

06:37.470 --> 06:44.160
So let's move on to the payments proto, which will represent our payments micro service.

06:44.160 --> 06:51.930
So we'll start off by defining the syntax which will be again proto three and then our package will

06:51.930 --> 06:54.030
be payments.

06:54.030 --> 07:00.870
In this case because we're working with the payments proto and then we'll define the payments service

07:01.620 --> 07:08.040
so we can remind ourselves by going to the payments controller to see our one method here, which is

07:08.040 --> 07:09.150
create charge.

07:09.150 --> 07:16.680
So we'll need to define this in our payments proto, so we'll have an RPC called Create Charge that

07:16.680 --> 07:27.210
will take in a create charge message that we will define and this will return a create charge response

07:27.300 --> 07:29.370
and we'll have a curly bracket.

07:31.620 --> 07:39.240
So let's go ahead and define the crate charge message firstly, which is going to be the same thing

07:39.240 --> 07:43.500
as our current payment create charge DTO.

07:44.220 --> 07:53.790
So we'll copy over the email from this DTO, and then if we go back here, we see we're of course extending

07:53.790 --> 08:00.140
the crate charge DTO so if we look at this, we have the card and then the amount property.

08:00.150 --> 08:08.250
So let's go ahead and firstly define the amount which is going to be an INT 32, which represents an

08:08.250 --> 08:10.860
integer and we'll set this equal to two.

08:11.010 --> 08:15.520
And then I want to define a new type in here called card message.

08:15.540 --> 08:22.380
Set it equal to card and set it equal to three so we can reference other types within our messages as

08:22.410 --> 08:23.790
we're doing here.

08:23.790 --> 08:30.290
And then we'll define this card message which holds all of the properties associated with the card.

08:30.300 --> 08:38.530
So now if we go to the Create Charge, DTO, we can see the card DTO where we have all of these properties.

08:39.030 --> 08:42.060
So let's go ahead and fill these out in our card message.

08:42.060 --> 08:47.880
So we have the string CVC, we have the INT 32.

08:48.850 --> 08:50.720
Expiration month.

08:50.740 --> 08:55.270
Now, as we did with the ID earlier, we can't use underscores.

08:55.270 --> 09:01.630
So we're going to use camel case and then map this at the application layer later on.

09:02.110 --> 09:06.510
So next we have the expiration year, which we will also camel case.

09:06.520 --> 09:11.530
And then finally we have the number which will be the actual credit card number.

09:11.650 --> 09:13.300
It will set equal to four.

09:14.200 --> 09:20.070
Now we can see our compiler's complaining because we haven't defined the create charge response.

09:20.080 --> 09:26.840
So the create charge response is going to be whatever is returned from the Stripe API.

09:26.860 --> 09:31.450
So right now we know we're returning the payment intent from the Stripe API.

09:31.540 --> 09:40.210
And the payment intent is a really large object that contains a lot of properties and we don't really

09:40.210 --> 09:41.950
care about most of these properties.

09:41.950 --> 09:48.280
Really, all that we're concerned about is the ID that's returned from the payment intent and we can

09:48.380 --> 09:55.070
confirm this by going to the reservation service where we actually call the payment service, right?

09:55.070 --> 10:02.330
We get back the response from the payment service and we're just pulling the ID off of the payment intent,

10:02.330 --> 10:06.140
which we can map back to the invoice ID on the reservation.

10:06.320 --> 10:10.040
And we don't care about all the other properties on the payment intent.

10:10.070 --> 10:17.300
So in this create charge response, instead of having to define all of the properties on the payment

10:17.300 --> 10:24.050
intent, I'm just going to create this create charge response and I'm only going to list the ID property

10:24.050 --> 10:29.360
here, which is a string because that's the only property we care about and want to actually access

10:29.360 --> 10:30.800
on this object.

10:30.980 --> 10:32.720
Now we can see our payments.

10:32.720 --> 10:34.550
Proto is fully completed.

10:34.550 --> 10:41.720
We can move on to the last proto that we need to define and this will be the notifications proto.

10:42.110 --> 10:44.980
So we'll follow the same pattern as we've done before.

10:44.990 --> 10:53.030
We'll set the syntax equal to proto three and then we will specify the package is notifications, and

10:53.030 --> 11:01.580
then we'll define the notifications service and we can reference the notifications controller to remind

11:01.580 --> 11:05.810
herself that we have our notify email method that we need to define.

11:06.260 --> 11:16.190
So let's go ahead and define the notify email rpc method that will take in a notify email message and

11:16.190 --> 11:17.130
return.

11:17.150 --> 11:19.940
Well, it's actually not going to return anything.

11:19.940 --> 11:27.050
However, we still need to we still need to define some sort of message in this return statement.

11:27.050 --> 11:31.070
So we'll use an empty return type that we will define.

11:31.880 --> 11:35.990
So let's go ahead and define the empty message here called empty.

11:36.020 --> 11:38.360
That is just going to have no properties on it.

11:38.780 --> 11:45.200
And then if we go back to the notifications controller in our notify email, DTO, we see we have the

11:45.200 --> 11:50.240
two properties that we need to define the email and the text, which are both strings.

11:50.240 --> 11:57.050
So we'll go ahead and create a new message for notify email message, and we will define the string

11:57.080 --> 12:00.520
of email and the string text.

12:00.530 --> 12:06.320
So now we have completed each of these proto definitions that describe each of our microservices.

12:06.350 --> 12:13.430
It describes all of the data and methods on these services, so the clients and servers will both know

12:13.430 --> 12:19.550
exactly which methods can be called and what data will be required and returned from those methods.

12:19.580 --> 12:27.560
Next up, let's go ahead and utilize Proto to actually generate TypeScript types from these definitions

12:27.560 --> 12:30.260
which we can utilize in our application.
