Skip to content

Commit fc722db

Browse files
author
monica.lopez-gris
committed
add schema first doc
1 parent a557268 commit fc722db

1 file changed

Lines changed: 120 additions & 142 deletions

File tree

documentation/guides-grapql.asciidoc

Lines changed: 120 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -17,185 +17,175 @@ toc::[]
1717

1818
= GraphQL on Devon4Node
1919

20-
=== Database setup
20+
GraphQL is a query lenguage that gets exactly the data that we ask for instead of static predefined responses.
2121

22-
First of all we are going to setup a mongo database to work with, we are not going to get in details with this so you can go to the https://docs.nestjs.com/techniques/mongodb[Nestjs documentation] to find more.
23-
24-
First we need to install a couple of dependencies:
22+
To install it:
2523

2624
[source,bash]
2725
----
28-
yarn add @nestjs/mongoose mongoose
29-
yarn add -D @types/mongoose
26+
yarn add @nestjs/graphql graphql-tools graphql apollo-server-express
3027
----
3128

32-
And add MongooseModule to `app.module.ts`
29+
== Schema first
30+
This tutorial uses the schema first method.
31+
32+
We assume you have already a functioning TODO service on a module
33+
34+
First we need to import GraphQLModule to our `app.module.ts`.
3335

3436
[source,typescript]
3537
----
36-
import { Module } from '@nestjs/common';
37-
import { MongooseModule } from '@nestjs/mongoose';
38+
...
39+
import { GraphQLModule } from '@nestjs/graphql';
40+
import { join } from 'path';
3841
3942
@Module({
4043
imports: [
41-
MongooseModule.forRoot('mongodb://localhost:27017'),
44+
// Your module import
45+
GraphQLModule.forRoot({
46+
typePaths: ['./**/*.graphql'],
47+
definitions: {
48+
path: join(process.cwd(), 'src/graphql.ts'),
49+
outputAs: 'class',
50+
},
51+
}),
4252
],
4353
})
4454
export class AppModule {}
4555
----
4656

47-
Now let's create our schema, inside `todos/schemas` we are going to create a file `todo.schema.ts` with:
57+
The `typePaths` indicates the location of the schema definition files.
4858

49-
[source,typescript]
50-
----
51-
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
52-
import { Document } from 'mongoose';
59+
The `definitions` indicates the file where the typescript definitions will automatically save, adding the `outputAs: 'class'` saves those definitions as classes.
5360

54-
@Schema()
55-
export class Todo extends Document {
56-
@Prop()
57-
id!: number;
61+
=== Playground
5862

59-
@Prop()
60-
task: string | undefined;
63+
Once we have imported GraphQL we can access it's playground by default on `http://localhost:3000/graphql`.
6164

62-
@Prop()
63-
status: boolean | undefined;
64-
}
65+
The playground allow us to test or resolvers, we can call a query this way:
6566

66-
export const TodoSchema = SchemaFactory.createForClass(Todo);
67+
[source,typescript]
68+
----
69+
{
70+
findAll{
71+
id,
72+
task
73+
}
74+
}
6775
----
6876

69-
Then import it on `todo.module.ts`.
70-
77+
And the output will look something like:
7178
[source,typescript]
7279
----
73-
import { Module } from '@nestjs/common';
74-
import { MongooseModule } from '@nestjs/mongoose';
75-
import { Todo, TodoSchema } from './schemas/todo.schema';
76-
77-
@Module({
78-
imports: [MongooseModule.forFeature([{ name: Todo.name, schema: TodoSchema }])]
79-
})
80-
export class TodosModule {}
80+
{
81+
"data": {
82+
"findAll": [
83+
{
84+
"id": "5fb54b30e686cb49500b6728",
85+
"task": "clean dishes"
86+
},
87+
{
88+
"id": "5fb54b3be686cb49500b672a",
89+
"task": "burn house"
90+
}
91+
]
92+
}
93+
}
8194
----
8295

83-
=== Service
96+
As we can see, we get a json "data" with an array of results.
8497

85-
To interact with the database we need a service, first we create a module with `devon4node generate module todos` and inside create the service `todos.service.ts`.
98+
And for our mutations it's very similar, in this case we create a todo with task "rebuild house" and we are going to ask on the response just for the task data, we don't want the id.
8699

87100
[source,typescript]
88101
----
89-
import { Injectable } from '@nestjs/common';
90-
import { InjectModel } from '@nestjs/mongoose';
91-
import { Model } from 'mongoose';
92-
import { Todo } from './schemas/todo.schema';
93-
94-
@Injectable()
95-
export class TodosService {
96-
constructor(@InjectModel(Todo.name) private readonly todoModel: Model<Todo>) {}
97-
98-
async create(task: string): Promise<Todo> {
99-
const object = {
100-
task: task,
101-
}
102-
const createdTodo = new this.todoModel(object);
103-
return createdTodo.save();
104-
}
105-
106-
async findAll(): Promise<Todo[]> {
107-
return this.todoModel.find().exec();
102+
mutation{
103+
createTodo (
104+
task: "rebuild house"
105+
){
106+
task
108107
}
109108
}
110109
----
111110

112-
To finish this section we need to create the corresponding schema on `todos/schemas/todo.schema`:
111+
And the output
113112

114113
[source,typescript]
115114
----
116-
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
117-
import { Document } from 'mongoose';
118-
119-
@Schema()
120-
export class Todo extends Document {
121-
@Prop()
122-
id: number;
123-
124-
@Prop()
125-
task: string;
126-
127-
@Prop()
128-
status: boolean;
115+
{
116+
"data": {
117+
"createTodo": {
118+
"task": "rebuild house"
119+
}
120+
}
129121
}
130-
131-
export const TodoSchema = SchemaFactory.createForClass(Todo);
132122
----
133123

134-
=== GraphQL
124+
In this case we return just one item so there is no array, we also got just the `task data` but if we want the `id`` too, we just have to add it on the request.
135125

136-
To install it:
126+
[NOTE]
127+
====
128+
We need to have resolvers to try this.
129+
====
137130

138-
[source,bash]
139-
----
140-
yarn add @nestjs/graphql graphql-tools graphql apollo-server-express
141-
----
131+
=== Schema
142132

143-
=== Schema first
144-
This tutorial uses the schema first method.
145-
146-
First we need to import GraphQLModule to our `app.module.ts`.
133+
Let's define de elements, querys and mutations that our module is going to have.
147134

148135
[source,typescript]
149136
----
150-
...
151-
import { GraphQLModule } from '@nestjs/graphql';
152-
import { join } from 'path';
153-
154-
@Module({
155-
imports: [
156-
...
157-
GraphQLModule.forRoot({
158-
typePaths: ['./**/*.graphql'],
159-
definitions: {
160-
path: join(process.cwd(), 'src/graphql.ts'),
161-
outputAs: 'class',
162-
},
163-
}),
164-
],
165-
})
166-
export class AppModule {}
167-
----
137+
type Todo {
138+
id: ID
139+
task: String
140+
}
168141
169-
The `typePaths` indicates the location of the schema definition files.
142+
type Query {
143+
todos: [Todo]
144+
todoById: Todo
145+
}
170146
171-
The `definitions` indicates the file where the typescript definitions, adding the `outputAs: 'class'` saves those definitions as classes.
147+
type Mutation {
148+
createTodo(task: String): Todo
149+
deleteTodo(id: String): Todo
150+
}
151+
----
172152

173-
==== Resolver
153+
=== Resolver
174154

175-
Resolvers has the instructions to turn graphQL orders into the data requested.
155+
Resolvers has the instructions to turn GraphQL orders into the data requested.
176156

177-
To create a resolver we go to todos module and then create a new `todos.resolver.ts` file, import the decorators needed and set our resolver.
157+
To create a resolver we go to our module and then create a new `todo.resolver.ts` file, import the decorators needed and set our resolver.
178158

179159
[source,typescript]
180160
----
181161
import { Resolver, Args, Mutation, Query } from '@nestjs/graphql';
182-
import { TodosService } from './services/todos.service';
183-
import { Todo } from './schemas/todo.schema';
162+
import { TodoService } from '../services/todo.service';
163+
import { Todo } from '../schemas/todo.schema';
184164
185165
@Resolver()
186-
export class TodosResolver {
187-
constructor(private readonly todosService: TodosService) {}
166+
export class TodoResolver {
167+
constructor(private readonly todoService: TodoService) {}
188168
189-
@Query()
169+
@Query('todos')
190170
findAll(): Promise<Todo[]> {
191-
return this.todosService.findAll();
171+
return this.todoService.findAll();
172+
}
173+
174+
@Query('todoById')
175+
findOneById(@Args('id') id: string): Promise<Todo | null> {
176+
return this.todoService.findOneById(id);
192177
}
178+
193179
@Mutation()
194180
createTodo(@Args('task') task: string): Promise<Todo> {
195-
return this.todosService.create(task);
181+
return this.todoService.create(task);
196182
}
197-
}
198183
184+
@Mutation()
185+
deleteTodo(@Args('id') id: string): Promise<Todo | null> {
186+
return this.todoService.delete(id);
187+
}
188+
}
199189
----
200190

201191
`@Resolver()` indicates that the next class is a resolver.
@@ -204,49 +194,37 @@ export class TodosResolver {
204194

205195
`@Mutation` is used to create or modify data.
206196

207-
The `@mutation` will create the next schema in or autogenerated schema file:
208-
[source,typescript]
209-
----
210-
type Mutation {
211-
createTodo( task: String ): Todo
212-
}
213-
----
214-
215-
And the `@Query` would do the same:
216-
[source,typescript]
217-
----
218-
type Query {
219-
todos: [Todo]
220-
}
221-
----
222-
223197
Here we have also an argument decorator `@Args` which is an object with the arguments passed into the field in the query.
224198

225-
Learn more about resolvers, mutations and their argument decorators on the https://docs.nestjs.com/graphql/resolvers#schema-first[NestJS documentation].
199+
By default we can access the query or mutation using it's name, for example:
226200

227-
228-
Now start the server and go to `http://localhost:3000/graphql` you should see a playground, here you can test your resolvers.
229-
230-
For try querys you only need to write a json with what you need:
201+
For the `deleteTodo` mutation.
231202

232203
[source,typescript]
233204
----
234-
{
235-
findAll{
205+
mutation {
206+
deleteTodo( id: "6f7ed2q8" ){
207+
id,
236208
task
237209
}
238210
}
239211
----
240212

241-
To test the mutation you can:
213+
But if we write something different on the decorator, we change the name, for example:
242214

215+
For the `findAll` query, we named it `todos`.
243216
[source,typescript]
244217
----
245-
mutation{
246-
createTodo (
247-
task: "aasas"
248-
){
249-
id, task
218+
{
219+
todos{
220+
id,
221+
task
250222
}
251223
}
252224
----
225+
Also if we go back to the `schema.graphql`, we will see how we define the query with `todos`.
226+
227+
Learn more about resolvers, mutations and their argument decorators on the https://docs.nestjs.com/graphql/resolvers#schema-first[NestJS documentation].
228+
229+
230+
Now start the server and go to `http://localhost:3000/graphql` you should see a playground, here you can test your resolvers.

0 commit comments

Comments
 (0)