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..
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)
- Part-2 (Adding Registration logic with test setup)
- Part-3 (Adding Login functionality with Refresh Tokens)
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
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
Login With Access Token
Refresh Token while login.
Test result
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)