Okay.
So our first step to add GraphQL to our reservations, microservice will be to open up the reservations
module and in our imports array.
Let's go ahead and add a new import to the GraphQL module from Nestjs slash GraphQL and we're going
to call for Route on it.
We can then pass in the options or the config that will be supplying.
In this case, it's going to be the Apollo Federation driver config.
And then let's open up an options object where we're going to specify two properties.
So the first will be the driver that we're using.
So this will be the Apollo Federation driver from Nestjs slash Apollo.
And then we're going to specify auto schema file equal to an object.
We're going to set federation equal to two because we're going to be using Federation version two.
And what does auto schema file is going to do is it's going to automatically generate the GraphQL schema
from our code.
So when we set up the GraphQL types in our code, they're automatically going to be converted into a
GraphQL schema that GraphQL understands and there's nothing else we're going to have to do.
This is automatically going to be happening for us since we set this property.
So next up, we're ready to add our first resolver to our reservation service, which is going to be
the equivalent of an Http controller in the GraphQL world.
So the resolver is going to be the list of mutations in queries that we're going to expose in our schema
and that users can call using GraphQL into our system.
So let's go ahead and create this in the source folder.
We'll create a reservations dot resolver, dot ts.
Now let's add the at resolver decorator from Nestjs GraphQL.
And now we need to specify the entity that we're returning from this resolver.
And this is going to be added to our GraphQL schema automatically based off of what we supply here.
So let's open up an anonymous function where we return the entity that is going to be used in this resolver.
So in our case, we are going to be working with the reservation document in our models folder.
Then we'll go ahead and export a class called Reservations Resolver.
Let's go ahead and add a constructor where we will inject the reservations service.
And now we're ready to set up our mutations and queries on the reservation.
So let's go ahead and start off with a mutation which is going to be an operation that mutates the data
by creating or updating the entity.
So we specify this with the at mutation decorator from Nestjs GraphQL, and then we specify the type
that we're returning from this mutation.
In our case, we know it's the reservation document.
We'll go ahead and create a new method here called Create Reservation.
And importantly, the name of the method that we define here is going to be the name of the mutation
in the GraphQL schema.
So I want to keep this the same name, create reservation here so we can leave this as is.
Next up, let's specify the arguments that we expect so we can use the at args decorator from Nestjs
GraphQL and extract out the arguments that are coming in.
In our case, we'll call it the Create reservation input.
Now we know this is going to be the create reservation input and the type of this will be the create
reservation DTO that we already have set up.
So there will be a bit of work we have to do to convert the DTO and the reservation document to types
that GraphQL understands.
Next up, we need to make sure that we extract the current user so we can get the current user decorator
from app slash common.
And there will also be some work that we have to do to convert the current user decorator to work with
GraphQL.
We'll do this later on.
For now, let's make sure we extract the user of type user DTO So now that we have the parameters we
need to create the reservation, we will simply return this dot reservation service dot create pass
in the create reservation input and the user.
So now we have our mutation set up to create a reservation.
Let's go ahead and add a query using the query decorator and it will specify this method will return
an array of reservation documents.
And then additionally, I want to explicitly specify the name for this query and simply call the name
of it reservations.
That's because the method I want to name this will be find all.
However, I don't want the GraphQL schema query to be called find all so we can explicitly override
this by providing the name here and importantly, make sure that the query decorator is imported from
Nestjs GraphQL and not Nestjs common.
You can see here the name property will override the name of the query, which is what we want to do.
And now we'll simply return this dot reservation service dot find all with no parameters needed.
Next up, let's specify a query to find a single reservation.
So we'll use the same query decorator and simply specify where returning a single reservation document.
Now I'll specify the name of this query will just be reservation.
And now we will have a find one method and we will get access to the at args here and now.
Instead of specifying an explicit dto file for the args, we can do this inline.
We'll firstly specify the name of the arguments or the property in this case which will be called ID,
and then we'll specify the type.
So we can do this by saying type property and return the type of this argument here.
In this case the ID will be a string and now we can specify the ID parameter of type string.
Now we'll return this dot reservation service, find one and pass in the ID to that method to find a
single reservation by ID.
Finally, we have the mutation to remove a reservation.
So let's go ahead and specify that we will still return a reservation document from this mutation and
we'll call this method remove reservation.
I'll get the same argument as find one so we can actually just copy this because we're also going to
be passing in an ID to remove the reservation by ID and then we can simply return this reservation service
dot remove and pass in our ID.
So now we've fully set up our reservations resolver to be able to implement our Crud methods on our
reservation documents.
Let's go ahead and update our reservation document with a necessary decorators so that Nestjs will actually
find this class and add it to our GraphQL schema.
So to do this, we're going to decorate it with the object type decorator to mark it as a GraphQL type.
And then we simply need to decorate each of these fields with the at field decorator to mark them as
part of this schema.
So we'll go ahead and make sure we add the field decorator to all of these properties.
Now we've updated our reservation document to be compatible with GraphQL so that it will be added to
our schema.
We need to also go to our abstract document in our Libs common folder and do the same thing for the
abstract document here so that we can expose the underscore ID property as part of our schema as well.
So to do this we're going to add the Add object type decorator again, and then we're also going to
specify an options object where we specify that this will be abstract so that this type won't be registered
in our schema by itself.
It will just be inherited in other GraphQL schema types like our reservation document.
So let's go ahead and mark it as abstract and then we'll specify the Add field decorator from Nestjs
GraphQL again.
So by default, we didn't have to specify a type for any of our other fields in our reservation document.
And that's because Nestjs and GraphQL will pick up on the type of these properties and we'll use that
same type to mark these properties as that type.
So for example, our dates and strings.
However, in the abstract schema we know that this object ID won't be an object ID when it's sent over
the wire, it will be a string.
So to mark this explicitly as a string, we can specify the type by using an anonymous function here
that returns the type.
In this case, we know that this will be a string when it's returned from our server.
So finally, let's go back to our Create Reservation DTO and update this to be compatible with GraphQL.
So we'll add another decorator to this DTO and instead of object type, we'll mark this with an input
type to mark it as an input type in GraphQL, which is going to be how we supply arguments to our GraphQL
calls.
We'll then go ahead and mark all the properties we want to expose with the Add field decorator, just
like we've done before.
And let's go ahead and do the same thing for the Create charge.
DTO here we need to specify the actual type that gets returned because Nestjs won't be able to pick
up on non primitive types like this.
Create charge DTO.
So we need to explicitly specify that the type here is of create charge DTO So now let's make sure we
go into the create charge DTO and update the create charge DTO so that it's also part of our schema.
So we'll have the input type decorator on this DTO as well.
We'll mark the card DTO with an app field decorator where we specify that it is of type card DTO and
we'll mark the amount field with just a add field decorator.
Now finally we'll go into the card DTO and repeat the same exercise.
So we want to add this as part of our GraphQL schema.
We'll mark it with the Add input type decorator and go ahead and mark the rest of these fields with
the Add field decorator so that they are also part of our GraphQL schema.
So our final step is going to be to go into the reservations module and in our providers array, make
sure we actually register the new reservations resolver so that it gets registered.
And in doing this, all of the associated types in the resolver, like the reservation document that
we decorated with the GraphQL decorators and the DTOs we just updated will get registered in our GraphQL
schema thanks to the auto schema file property that we specified earlier.
Now finally we have a typo in our Create reservation method, so make sure we've spelt create reservation
properly.