dev.to clone using react-node via typescript, typegraphql & TypeOrm[Backend](Part-1)
Tags: react, node, typescript, graphql
Published: 2019-10-13 18:35:10

Hello Community, Today I am trying to clone **dev.to** website using **ReactJs** and **NodeJs**. It will be a prototype, in which user can **signUp/signIn**, create post & other features. 
> I am doing it for just learning purpose.

###Technology Stack :
**NodeJs, ReactJs, Graphql, TypeOrm,TypeGraphql, Typescript, JWT, Apollo-server-express, Jest, Apollo-client, Apollo-link & much more..**

[GitHub Link for dev.to clone](https://github.com/vinodchauhan7/dev.to-clone)

[Part-2](https://dev.to/vinodchauhan7/dev-to-clone-using-react-hooks-graphql-codegen-apollo-refresh-token-authentication-middleware-backend-frontend-part-2-28g8)

To commence with, I have just started with typegraphql-typescript-node setup using typeorm. Till now, I have completed Registration and login functionality with jest setup. For **Authentication** I am using 'JWT'. And I am saving password using **bcryptjs** for hashing purpose.

It will be difficult for me to make proceed with step by step as this article series can be large enough, So for that I have made branches in git.
Till the date(13/10/2019), I have made 3 branches in Git for following purpose :
 * [Part-1 (Setting up server)] (https://github.com/vinodchauhan7/dev.to-clone/tree/Part-1/server)
 * [Part-2 (Adding Registration logic with test setup)] (https://github.com/vinodchauhan7/dev.to-clone/tree/Part-2/server)
 * [Part-3 (Adding Login functionality with Refresh Tokens)] (https://github.com/vinodchauhan7/dev.to-clone/tree/Part-3/server)

> If anyone having problems in running any of above stated branches then please check for 'master' branch, it will be in running condition always.

##Project Structure
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/p5hsbjoaof92l631jgg2.png)

###Package.json
```javascript
{
    "name": "server",
    "version": "1.0.0",
    "main": "index.js",
    "license": "MIT",
    "dependencies": {
        "apollo-server-express": "^2.9.6",
        "bcryptjs": "^2.4.3",
        "class-validator": "^0.10.1",
        "dotenv": "^8.1.0",
        "express": "^4.17.1",
        "graphql": "^14.5.8",
        "jsonwebtoken": "^8.5.1",
        "pg": "^7.12.1",
        "reflect-metadata": "^0.1.13",
        "type-graphql": "^0.17.5",
        "typeorm": "^0.2.19"
    },
    "devDependencies": {
        "@types/bcryptjs": "^2.4.2",
        "@types/express": "^4.17.1",
        "@types/graphql": "^14.5.0",
        "@types/jest": "^24.0.18",
        "@types/jsonwebtoken": "^8.3.4",
        "@types/node": "^12.7.12",
        "jest": "^24.9.0",
        "nodemon": "^1.19.3",
        "ts-jest": "^24.1.0",
        "ts-node": "^8.4.1",
        "ts-node-dev": "^1.0.0-pre.43",
        "typescript": "^3.6.4"
    },
    "scripts": {
        "start": "ts-node-dev --respawn src/index.ts",
        "db:setup": "ts-node ./src/test-utils/setup.ts",
        "test": "npm run db:setup && jest"
    }
}

```

I am using 'yarn' package manager for running all my scripts.
1) yarn start (It will run your backend server at localhost:4000/graphql)
2) yarn test ( To test all the run cases)

###Index.ts
```javascript
import "dotenv/config";
import "reflect-metadata";
import { ApolloServer } from "apollo-server-express";
import Express from "express";
import { createConnection } from "typeorm";
import { createSchema } from "./utils/createSchema";

const server = async () => {
  await createConnection();

  const schema = await createSchema();

  const apolloServer = new ApolloServer({
    schema,
    context: ({ req, res }) => ({ req, res })
  });

  const app = Express();

  apolloServer.applyMiddleware({ app });

  app.listen(4000, () => {
    console.log("Dev.to server started on localhost:4000/graphql");
  });
};

server();

```


**I am using postgres as my DB.**. The ormConfiguration for db will be like this.
```javascript
{
    "type": "postgres",
    "host": "localhost",
    "port": 5432,
    "username": "postgres",
    "password": "root",
    "database": "dev-to-clone",
    "synchronize": true,
    "logging": false,
    "entities": [
        "src/entity/*.*"
    ]
}
```

For testing my resolvers, I am using jest and different db.
```javascript
import "dotenv/config";
import "reflect-metadata";
import { createConnection } from "typeorm";
import { User } from "./../entity/User";

export const testConn = (drop: boolean = false) => {
  return createConnection({
    type: "postgres",
    host: "localhost",
    port: 5432,
    username: "postgres",
    password: "root",
    database: "dev-to-clone-test",
    synchronize: drop,
    dropSchema: drop,
    logging: false,
    entities: [User]
  });
};
```

Till now my 'User' entity has following attributes, I can update them If I need to manipulate it in future.
```javascript
import { Entity, PrimaryGeneratedColumn, Column, BaseEntity } from "typeorm";
import { ObjectType, Field, ID } from "type-graphql";

@ObjectType()
@Entity()
export class User extends BaseEntity {
  @Field(() => ID)
  @PrimaryGeneratedColumn()
  id: number;

  @Field()
  @Column()
  name: string;

  @Field()
  @Column("text", { unique: true })
  email: string;

  @Column()
  password: string;

  @Field()
  @Column({ nullable: true, default: null })
  workPlace?: string;

  @Field()
  @Column({ nullable: true, default: null })
  about?: string;

  @Field()
  @Column({ nullable: true, default: null })
  linkedIn?: string;

  @Field()
  @Column({ nullable: true, default: null })
  github?: string;

  @Field(() => [String])
  @Column("simple-array", { nullable: true, default: null })
  tags?: string[];

  @Field()
  @Column()
  joinedDate: string;

  @Field()
  @Column({ nullable: true, default: null })
  location?: string;

  @Field()
  @Column({ nullable: true, default: null })
  isActive?: boolean;
}

```


Some snapshots are :

###Register user
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/tnwn6audgjf4znsin0u4.png)

###Login With Access Token
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/jklrf23d6l3pea7068oj.png)

###Refresh Token while login.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/b3arwri051cohai0u9m2.png)

### Test result
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/8yk57siyrctscgi7xvrl.png)

Those who dont understand the logic for Access & Refresh token, It will be properly understandable when we are covering its frontend part using React with Typescript & Apollo.

Till then Bye-Bye community, will come back with other functionality asap.