DEV Community

vinodchauhan7
vinodchauhan7

Posted on • Updated on

dev.to clone using react-node via typescript, typegraphql & TypeOrm[Backend](Part-1)

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

Part-2

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 :

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

Package.json

{
    "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

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.

{
    "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.

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.

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

Login With Access Token

Alt Text

Refresh Token while login.

Alt Text

Test result

Alt Text

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.

Top comments (0)