typescript, typegraphql & TypeOrm[Backend](Part-1)을 통해 react-node를 사용하여 dev.to 복제

안녕하세요 커뮤니티 여러분, 오늘 저는 ReactJs와 NodeJs를 사용하여 dev.to 웹사이트를 복제하려고 합니다. 사용자가 가입/로그인하고 게시물 및 기타 기능을 만들 수 있는 프로토타입이 될 것입니다.

I am doing it for just learning purpose.



기술 스택:



NodeJs, ReactJs, Graphql, TypeOrm, TypeGraphql, Typescript, JWT, Apollo-server-express, Jest, Apollo-client, Apollo-link 등..



시작하려면 typeorm을 사용하여 typegraphql-typescript-node 설정을 시작했습니다. 지금까지 jest 설정으로 등록 및 로그인 기능을 완료했습니다. 인증을 위해 'JWT'를 사용하고 있습니다. 그리고 해싱 목적으로 bcryptjs를 사용하여 비밀번호를 저장하고 있습니다.

이 기사 시리즈가 충분히 클 수 있기 때문에 단계별로 진행하기가 어려울 것이므로 git에서 분기를 만들었습니다.
2019년 10월 13일까지 다음과 같은 목적으로 Git에 3개의 브랜치를 만들었습니다.




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


    프로젝트 구조




    패키지.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"
        }
    }
    
    

    모든 스크립트를 실행하기 위해 'yarn' 패키지 관리자를 사용하고 있습니다.
    1) 원사 시작(localhost:4000/graphql에서 백엔드 서버를 실행합니다.)
    2) 원사 테스트(모든 실행 사례를 테스트하려면)

    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();
    
    

    Postgres를 DB로 사용하고 있습니다. db의 ormConfiguration은 다음과 같습니다.

    {
        "type": "postgres",
        "host": "localhost",
        "port": 5432,
        "username": "postgres",
        "password": "root",
        "database": "dev-to-clone",
        "synchronize": true,
        "logging": false,
        "entities": [
            "src/entity/*.*"
        ]
    }
    

    리졸버를 테스트하기 위해 jest와 다른 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]
      });
    };
    

    지금까지 내 '사용자' 엔터티에는 다음 속성이 있으며 나중에 조작해야 하는 경우 업데이트할 수 있습니다.

    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;
    }
    
    

    일부 스냅샷은 다음과 같습니다.

    사용자 등록





    액세스 토큰으로 로그인





    로그인하는 동안 토큰을 새로 고칩니다.





    검사 결과





    Access & Refresh 토큰에 대한 논리를 이해하지 못하는 분들은 React with Typescript & Apollo를 사용하여 프론트엔드 부분을 다룰 때 제대로 이해할 수 있을 것입니다.

    그때까지 Bye-Bye 커뮤니티는 최대한 빨리 다른 기능으로 돌아올 것입니다.

    좋은 웹페이지 즐겨찾기