So now that we've exposed our reservations microservice over our GraphQL Gateway, let's continue and
add the authentication microservice as well so that we can query all the users in our system.
We'll go into the auth module and follow the same process that we did in the reservation service.
So we'll simply add the GraphQL module for route and pass in the Apollo driver config as the options
here.
Now I want to pass in the driver.
That will be the Apollo Federation driver from Nestjs Apollo.
And then we'll specify the auto schema file again where we want to set federation equal to two so that
our schema is automatically generated from our code.
So in our users directory, let's go ahead and create a new users dot resolver.
It's.
And this is going to be just like we did with the reservation service.
We'll use the resolver decorator that will be returning the user document and make sure we import this
from app slash common.
And so we'll go ahead and export the class users resolver and our constructor will go ahead and inject
the user service.
And now I want to add a mutation using the mutation decorator that will return a user document.
And I want to expose the create user method.
So here we'll use the add args decorator again and extract the create user input that we'll call create
user input, but we'll know it will be simply the same.
DTO we've already created the create user DTO so inside of this method we will simply return this dot
user service dot, create and pass in the create user input.
Next up, let's add a new query here using the Add query decorator from Nestjs slash GraphQL, where
we'll go ahead and return an array of user documents.
And I'll give this a custom name of users because we'll create a new find all method here that will
simply return this dot user service dot find all which we haven't implemented yet.
However, we can easily implement this by going to the user service and creating a new async find all
method that will call this dot users repository dot find and pass in an empty filter query object so
that we will find all users in our database.
So now we'll go to our user dot schema file in lib slash common so that we can convert this into a GraphQL
schema type by adding the at object type decorator to it.
And now we will go ahead and expose our properties by using the at field decorator.
Now I don't want to expose the password property here because that is sensitive data, so we can merely
leave off the at field decorator from it and it won't be added to our schema.
So that can be really helpful when we want to leave off certain data.
So I'll go ahead and add the field decorator finally to our roles array.
And because this is a non primitive type, we'll go ahead and explicitly specify the type here of an
array of strings.
Now, finally, back in our users resolver, we'll go into our create user DTO and do the same thing
by decorating it.
We'll add the add input type decorator and add the add field decorator to all of these properties that
we know will be passed in when we create a new user.
And finally, for the roles array, we'll specify that this is an array of strings.
Additionally, in order to specify that this is an optional property and doesn't need to be provided,
we need to provide an options object where we specify nullable to true, which makes it so that this
property can be nullable.
Lastly, make sure we go to the users module and add the newly created users resolver to our providers
array so that all of our types and schemas get registered in our GraphQL schema.
So now that we've correctly exposed our users document using the users resolver, let's go back to the
Gateway module and integrate the newly created auth GraphQL service into our subgraphs array.
By following the same process, we'll provide the name of it and call it off and specify the URL equal
to config service dot getter throw and now we'll provide the auth GraphQL URL.
So now we need to go into the dot m file for our gateway and make sure we add the auth GraphQL URL,
which will be our Http protocol and it's going to be the name of the auth service and this will be on
Port 3001.
We can go to the auth M file to remind yourself that our Http server is listening on 3001 and we'll
target slash GraphQL.
Finally, go ahead and restart our Docker services so that we now have access to the auth GraphQL server.
So now that our services have started up, let's go back to our GraphQL server and refresh it.
And now if we look at our docs, we can see we have the user's query and mutation added to our super
graph in our gateway schema.
So as an end user, this is all just one schema.
Even though these are from different services underneath, it's all abstracted away, which makes this
a great solution for exposing APIs like this.
So of course we can query all of the users in our system now by executing a new user's query and pulling
back everything we want in this user, the ID and email.
And of course there is no password on the user and we can even see this by looking at the raw schema
for the user document.
There is no password exposed so we can pull the roles off as well.
And now if we query the users, we can see the user that we've created earlier.
And notice this is the same user ID associated with the reservation that we created so we can see our
current user decorator is working.
As expected because it's pulling the user off and the auth context from the auth service and sending
it to the underlying services, in this case the reservation service.
So this is great to see and we can quickly check to see that our create user mutation is also working.
So we'll pass in a create user input that has a user email.
So I'll use some test email at test.com and make sure we have a strong password with some special characters
in it and then specify we want the ID, email and roles to come back and we can add some roles as well
to make sure the roles array looks correct.
And now we can see the user is created and if we execute this query, we can see the new user in our
response.
So this is excellent.
Okay, so finally, let's go ahead and expose one more microservice.
The payments microservice, which is currently actually locked down to the outside world because there's
no way for an external service to call this TCP, TCP microservice.
So it's a great candidate for adding it to our API gateway to, for example, query the list of all
payments we have in our system.
So let's go ahead and follow our standard procedure so we can actually go into the auth module and I'll
simply copy the GraphQL module that we set up and let's paste it in to the payments module and make
sure we import the necessary files here.
So we have the driver, the options and the GraphQL module that we just imported.
So next up I want to go to our Main.ts where currently we are not listening on an Http port.
So let's change this.
In addition to calling start all microservices, we need to make sure we call await app dot listen.
So that we listen on an Http port where our GraphQL server will be running on so that the gateway microservice
can reach it.
So let's call config service dot getter throw and call the port dot http and then I'll also rename the
existing port and MV to port TCP to make sure this is a bit more clear that these are two separate ports
and we'll go back to our payments module and make sure we change the validation schema to also be port
TCP.
So now we'll go into our Env and make this change as well.
So we'll add a port dot TCP equal to 3003 and then our port dot http I'll say will be on 3005 and now
we can go ahead and create our payments resolver inside of our payment source folder that will go ahead
and expose our payment intents that are coming from our Stripe API.
So let's go ahead and firstly define what this payment intent entity will look like.
So I'll create a new file called Payment Intent dot Entity Dot TS, and this will be an Add object type.
And now we'll export a class called Payment Intent.
So if we look in the payment service, we can see the payment intent that gets returned from the Create
call has a bunch of different properties on it that we really don't care about.
Most of them.
All I really want is the amount on the payment intent and the ID of the payment intent so we can make
sure we just expose these two properties by adding a field decorator, set an ID equal to string, and
then the Add field decorator to set the amount to type number.
So we really only care about these two properties on the payment intent.
Let's go ahead and expose them in our payment intent object type, which will be added to our GraphQL
schema.
So let's go to our payment resolver now and flesh this out.
We'll add the resolver decorator as we're used to doing that will return the payment intent that we
just created.
So we'll export a class called payments resolver and we'll inject the payments service in this resolver
so that we can call it.
And now we'll expose our one query in here using the Nestjs GraphQL query decorator that will return
an array of payment intent.
Now also query this and I'll also give this a custom name of payments.
And then we'll create this function called find all.
And then in here we will return this dot payment service dot, get payments, which we haven't set up
yet.
So let's go ahead and do that next by going into the payments service and creating this function.
So in here I'll create a new async get payments method that is going to be very simple.
It's going to get all of the payment intents from our Stripe API by creating a new const called Payments.
We'll set it equal to await this dot stripe dot payment intents dot list, which will retrieve a list
of payment intents.
And then we're going to return payments dot data, which contains all of our payment intents, which
includes the ID and amount on each payment intent.
So lastly, in our payments module, don't forget to add the payments resolver to the providers array.
Let's go back to the gateway now, the Gateway module and add the last object to our subgraph that will
contain the payments service, we'll call it payments, and then the URL will be config service, dot
getter throw and extract the payments GraphQL URL and variable.
So we'll go to the MV and now get the payments GraphQL URL and set this equal to Http.
Colon slash slash.
The name of the payment service, which we know is payments and then the port it's exposed on which
we just created, which was 3005 and then reached the GraphQL endpoint, which is called GraphQL.
So I'll go ahead and do one last restart of my containers and let them start up.
So now our services have started up.
I'll go back and refresh the GraphQL playground and now if we query the docs, we can see we have the
new payment query that's been added with our payment intent.
Entity.
So let's go ahead and test this out.
I'll create a new query called.
Payments, we query all payments and then I want to pull back the ID and the amount for each payment.
So I'll go ahead and execute this.
And now you can see we have a list of all the payments I've ever created on the Stripe API.
So you can see the ID and the amount for each one, which is super useful.