So we're ready to go inside of our reservation service now and actually make a call to the payment service
and test this functionality out.
Firstly, we're going to go ahead and open up our reservations module or have to go ahead and provide
the newly created payment service to our client module here so that we can inject it and actually communicate
with it.
So we can simply go ahead and copy this auth service object.
And I will change this out now to a new service.
So in our constants folder in lib slash Common.
We have our services file here and we'll go ahead and export a const called Payments Service and this
will be called payments.
So now in our reservations module, let's go ahead and change the injection token out here to payment
service.
We're still going to inject the config service, but now we're going to be looking for the payments
host and the payments port.
So let's go ahead in our dot env and actually set this up.
I'll break things up here and add a new payments host which we know in our Docker compose set up will
be the name of the service that we define in here directly is going to be the host name for that service.
So we know it'll just be payments.
So let's go back into our ENV and set the host here to payments.
And then we have the payments port which if you remember correctly, in our payments service, we defined
this at 3003.
So let's go ahead and set that as well.
Finally in our Reservations module, let's go ahead and actually add some schema validation to all of
our microservices right now.
I'll go ahead and add an auth host, which is a joy dot string dot required and I'll copy this for the
next one, which is the payments host, which is also a required string.
And then we have the auth port, which is a type number and this will be required.
And then lastly, we'll do the same here for the payments port.
So make sure as we update the environment variable that we, we start our Docker containers and allow
that new environment variable to be read in.
So now let's go back into our reservation service and let's go ahead and inject by using the inject
decorator here.
We'll go ahead and provide the payments service as our injection token and we'll go ahead and change
the import here to apps slash common to make sure we import that correctly.
So now we're injecting the payment service.
We'll go ahead and call this payments service of type client proxy here from Nestjs microservices.
So now in our Create method here where we're actually creating our reservations and I'm now just realizing
that we actually need to make sure that all of these functions here are async because these all return
a promise.
So let's go ahead and update these function signatures here.
And now inside of Korea, instead of just creating the reservation, after I create the reservation
in our database, I want to go ahead and reach out to our payment service and bill the appropriate user
for this reservation.
So the first thing we'll have to do is go into our Create Reservation, DTO and update this here so
we know we need to add the credit card in the Create Reservation DTO So let's go ahead and add a new
card property here and we want to add a sub DTO here so that we can apply validation to this actual
card object itself.
So let's go ahead and create a new DTO in the reservations folder and we'll call this card DTO Dots,
and we'll go ahead and export a card.
DTO here now inside of the card, DTO, we can go back into our payment service and confirm the type
on the card here, which we know will be of type stripe payment method, create params card one so we
can see all the properties on the card here that we want to validate.
So let's go ahead and copy these properties and paste them into this card DTO so that we can validate
them.
I'm also going to go ahead and remove all of the comments here and I'm going to make CBC required as
well.
So we'll go ahead and validate the CBC here and make sure that this is a string as well as we'll say,
this will not be an empty string.
And now for the expiration month, we'll say that this will be a number here and same for the expiration
year.
We will also say that this will be of type is number.
And then for the actual credit card number here, there's actually a custom validator we can use here
to actually check to see if this is a valid credit card number.
So we'll go ahead and import this from class validator as well.
So now back in our Create Reservations, DTO, we can specify the type of the card here will be of type
card DTO from our new DTO file.
And importantly, we're going to go ahead and apply some validation to this itself.
Will firstly say that this is actually be defined here.
So we'll have the is defined from class validator as well as is not empty object to make sure this is
an actual object and then we're going to use the validate nested property here which will ensure that
it will actually get validated on the properties that live inside of this DTO or the ones that we just
defined.
And now we have everything we need to actually supply this card in a DTO.
Lastly, we're going to add our amount field here, which is of type number, and this will be the actual
cost of this reservation itself.
So we'll go ahead and make sure that this is a number here.
So this is great and should work perfectly fine in our case.
However, if you notice right now, we actually have some duplication because in this crate reservation,
DTO, we're essentially defining this set of properties here that we're passing to the payments controller.
And we've already defined this DTO here as a create charge DTO.
Now we want to avoid this duplication, but we also want to eventually implement validation on this
payments controller.
In this route here, we want to actually validate the incoming payload on our create charge route.
So in order to accomplish both of these tasks, we're just going to move the newly created card DTO
into our Libs common folder, into our DTO directory.
We'll move this card DTO in here and then I'll also go ahead and move our create charge DTO into the
DTO folder.
Now in the create charge, DTO instead of the card here referencing the stripe type, we will make this
of type card DTO and then we'll go ahead and copy over the annotations from this card DTO and move it
to the common one.
Here we'll add the annotations to the create charge DTO here or we have the card.
We'll just need to go ahead and make sure that we import these from class validator.
And then the amount here will also, of course be a number.
So now in our index.ts, I'll go ahead and make sure we export everything from the create charge.
DTO now back in the Create Reservation, DTO, let's go ahead and get rid of these two properties and
we'll add a new object here called the Charge property, which we know will be of type create charge
DTO and we will add the same annotations we did earlier where we say this is defined, it's not an empty
object and we want to go ahead and validate nested here.
So now we have a cleaner DTO here for our reservation.
I'll go ahead and clean up our imports here and make sure we import this from app slash Common and then
I'll go back into our payments controller here.
And I'll also just change the import here to be from app slash common as well.
So now our details are exactly the same in both our reservation and payment service and we have consistency
with our types in one place, which is great.
So let's go ahead and test out our updated DTO, I'm going to go ahead and make sure I log in first
on our auth service to get our JWT cookie.
So let's go ahead and post to 3001 all slash login with a valid user here.
I'll go ahead and send this off and I have a 201 and I can see my JWT cookie.
So now we'll send a request to localhost 3000 slash reservations and if we immediately post this off
we should get a bad request.
You can see we are complaining and importantly, we can see we have validation about the charge itself.
So let's go ahead and fill out our DTO here.
Okay.
So I've gone ahead and partially filled out the DTO here, left the card blank.
If we send the request off here, we can see we're getting a weird error message about an unknown value
being passed to the validate function.
And the reason for this is because we're not actually converting this property here into the create
charge DTO object itself or instantiating a new class.
Instead, we're just passing a plain JavaScript object, which is not what we want to do.
We want to do what we did up here with our date and convert it to an actual object.
So we'll use the class transformer type decorator here and actually return the type we want to turn
this into.
In this case the create charge.
DTO if we follow the create charge DTO further on, we can do the same thing for the card.
Here.
We want to use class transformer to actually turn this into a card.
DTO So now if I go off and send this request again, you can see we get the expected validation messages
for our card object.
So let's go ahead and finish completing this card.
Okay, so I've gone ahead and completed the full DTO here now with some sample credit card information
as well as changing my amount out to a real number.
And now if we send the request off, we can see our validation is passing and we are able to pass this
charge object along with our DTO.
So now we can actually pass this to our payment service directly inside of our reservation service.