From Rest to Graph
Currently, we have created a Rest API with one exposed endpoint, the GET defined in the src/app/app.controller.ts file, in this section, we will transition from the Rest API to Graphql API the painless way.
In our app.module.ts file, we have used the @Module decorator, diving into the Nest documentation, we understand that it provides metadata that Nest makes use of to organize the application structure, in other words, each Nest application has at least one Module to make it work, that we’ll call the root module, it’s our starting point, meaning, if we need to transform our API from Rest to Graph, we will need to detect and update our route module, in the way it starts listening only one endpoint, the graphql/.
Getting back to the module decorator, according to its documentation, a module can become a Provider to another module, all linked to the root module, the module-provider relationship is implementing a GRAPH data structure under the hood shown in the image below:
](/assets/images/3A-92a247b5559aa5b364925453b8027ef5.png)
image3A - Application module-providers relationship from THE NEST OFFICIAL DOC
The module decorator takes a single object as a set of properties that defines the module, we will use those properties to transform our API into a graphql, the most important ones for now are:
imports: the list of imported modules that export the providers which are required in this module.providers: the providers that will be instantiated by the Nest injector and that may be shared at least across this module.controllers: the set of controllers defined in this module that have to be instantiated.
Let’s go ahead and improve our root module so that our app will become a graphql app:
In the
importsarray, let’s use theGraphQLModuleexported from@nestjs/graphqlpackage, after the required packages below.# install the required packages
$ yarn add @nestjs/graphql @nestjs/apollo graphql apollo-server-express apollo-server-coreThen, in the
app/app.module.tsfile, change the emptyimportsarray to:// app/app.module.ts
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
playground: false,
plugins: [ApolloServerPluginLandingPageLocalDefault()],
}),
],With
GraphQLModuleimported from@nestjs/graphql,ApolloDriverandApolloDriverConfigfrom@nestjs/apollo, join frompath, andApolloServerPluginLandingPageLocalDefaultfromapollo-server-core.In the GraphQLModule. we have added a couple of other properties:
- By setting the autoSchemaFile property to
join(process.cwd(), 'src/schema.gql'), we can use the code-first approach instead of the schema-first approach. This way, Nest will automatically generate our schemas based on our model classes. We've chosen to store the schema file in thesrc/schema.gqllocation, but you can also let Nest determine the location by simply setting autoSchemaFile to true. To learn more about the pros and cons of the schema-first vs code-first approach, you can check out this resource. - playground: set to
falseTo useApollo Sandboxinstead of thegraphql-playgroundas a GraphQL IDE for local development. - plugins: we need to define it as ApolloServerPluginLandingPageLocalDefault based on the playground value, if it’s set to true, we don’t necessarily need to add it as part of our plugins.
- By setting the autoSchemaFile property to
Then, let’s rename the
app.controller.tsfile toapp.resolver.tsand just enter the code below:// app/app.resolver.ts
import { Query, Resolver } from '@nestjs/graphql';
import { AppService } from './app.service';
@Resolver()
export class AppResolver {
constructor(private readonly appService: AppService) {}
@Query(() => String)
getHello(): string {
return this.appService.getHello();
}
}From the previous content, we can see these differences:
- The
@Controllerdecorator has been changed to@Resolver - The
@Getdecorator by@Query(() => String)
But everything else remains exactly the same.
Let’s now get back to our
app.module.tsfile, and fix the imports- Change the import of the controller, we no longer have one, we have a resolver instead
- Remove the
AppControllercontroller from thecontrollersarray, - Add the
AppResolverin theprovidersarray along withAppService
Our file now looks like the following:
import { Module } from '@nestjs/common';
import { AppResolver } from './app.resolver';
import { AppService } from './app.service';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { join } from 'path';
import { ApolloServerPluginLandingPageLocalDefault } from 'apollo-server-core';
@Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
playground: false,
plugins: [ApolloServerPluginLandingPageLocalDefault()],
}),
],
controllers: [],
providers: [AppService, AppResolver],
})
export class AppModule {}That way, we have transformed our initial Rest API into a Graphql one, in a few steps, easy to follow.
- The
Let’s run the app once again and confirm that our API is now Graphql API
# Let's run the app in dev mode
$ yarn start:dev
Let’s go at http://localhost:3000/graphql
This is what we normally get:

image4A
Let’s query our server, we currently have only one Query, the getHello, if you were following along, everything should be running like on the image below

image4B - Our graphql API running 🚀
Kudos, our API is running, let’s now configure our database.