Creating a Reddit Clone Using React and GraphQL - 02
Published: 2021-02-02 11:30:45

This is a series of posts and the previous one you can find from here.

[**Learning React with Ben Awad — 01**](https://www.rasikag.com/posts/learning_react_with_ben_awad_01)

> Note:
>
> use `yarn watch` to build the JavaScript files.
>
> use `yarn dev `to run with `nodemon` .
>
> All these commands set up on `package.json` file.

At this point from the previous post, we set up our databases. That means we can successfully add data to the database. But here, we are using `GraphQL` . So, let's set up the `QraphQL` to our project. Also, we are right now building the backend web service. Let's add relevant packages. Use below command to add `express` web framework, GraphQL support to express server by `apollo-server-express` and GraphQL by `graphql` and TypeScript support for creating `Schemas` by `type-graphql`

`yarn add express apollo-server-express graphql type-graphql`

Then add `reflect-metadata`. This is the metadata reflection API that supports to add attributes or annotations and more. Use below command to add it.

`yarn add reflect-metadata`

Also, we need to add `express` TypeScript support. Using below command let’s add it.

`yarn add -D @types/express`

Now we created a server and it is up right now.

But here we are using GraphQL. So we create an `ApolloServer` object and pass the express server into the middleware pipeline. You can check that we need to add the `config` object that telling what are the `resolvers` .

```javascript
const apolloServer = new ApolloServer({
  schema: await buildSchema({
    resolvers: [HelloResolver, PostResolver],
    validate: false,
  }),
  context: () => ({ em: orm.em }),
});
apolloServer.applyMiddleware({ app });
```

These resolvers are query handlers for the `GraphQL.` In here we can define our query functions and mutation functions. To define a class as resolver use `@Resolver` annotation.

#### `@Query` annotation. 

Define as this is a query. Pass the return type as the first parameter. If you want to return null, you need to explicitly define it.

```javascript

@Query(() => Post, { nullable: true })

```

Once you run the webserver you can open `graphql` the playground by `localhost:[port]/graphql`

But the thing is Post is an Entity. We can convert it to GraphQL object. use `@ObjectType()` and `@Field()` annotations. (check the below link )

[**rasikag/reddit-clone**](https://github.com/rasikag/reddit-clone/blob/add-graphql-resolvers/src/entities/Post.ts)

Now we need to database context. We can create it and pass it as `@resolver` function parameter. Here we are creating the context object.

```javascript

export type  RedditDbContext {
  em: EntityManager<any> & EntityManager<IDatabaseDriver<Connection>>
}

```

Then user this context in post resolver as a parameter in query or mutation function.

One thing is there is `GraphQL` type and `Entity` type. Kinda duplication. Also, make the return type as `Promise<Post[]>` to avoid the returning any type.

```javascript
  @Mutation(() => Post) // GraphQL return type that map to same Post Entity
  async createPost(
  @Arg("title") title: string,
  @Ctx() { em }: RedditDbContext
  ): Promise<Post> // same Entity return type
  {
  ...
  }

```

Now all set and if you run this you will get an error because GraphQL yield to set the type in `createdAt` property in `Post` entity.

```javascript

NoExplicitTypeError: Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'createdAt' of 'Post' class.

```

To resolve that add types explicitly for the Post entity for support GhraphQL.

```javascript

@Field(() => String) // explicitly define type.
@Property({ type: "date" })
createdAt = new Date();

```

> Query or Mutation method needs 2 parameters. Context object and Arguments.

Now we set up all the things and you can go GraphQL playground and execute the below query to get all posts from the database.

```javascript
{
  posts {
    id,
    createdAt,
    updatedAt,
    title
  }
}
```

Hola… We got the data from `GraphQL`

Now we are going to create all the CRUD operations for the Post entity. These methods should return a `Promise.` Once we implement all the CRUD methods we can execute below `GraphQL` queries.

To get post by post id execute below query.

```javascript

{
  post(id:3){
    title
  }
}

```

We can create a new post using the below query. It is a `mutation` query. Also, make attention that how we pass the parameters.

```javascript

mutation {
  createPost(title:"Hello from GraphQL"){
    title,
    id
  }
}

```

Here is the update post query.

```javascript

mutation {
  updatePost(id:1, title: "I am going to update this title") {
    title
  }
}
// the title is what are the values that we need as return values

```

Here is the `delete` post `GraphQL` query.

```javascript

mutation{
  deletePost(id:1)
}

```

Once you closely pay the attention to the `console` , you will see the query executed by GraphQL.

All the code related to this post, you can find in here.

[**rasikag/reddit-clone**](https://github.com/rasikag/reddit-clone/tree/add-graphql-resolvers)

I will wrap-up this note from here. Soon I will publish next part of this note.

If you have anything to ask regarding this please leave a comment here. Also, I wrote this according to my understanding. So if any point is wrong, don’t hesitate to correct me. I really appreciate you.

That’s for today friends. See you soon. Thank you

Main image [credit](https://www.pexels.com/photo/photo-of-person-standing-on-cliff-edge-3181458/)