백엔드 Back-end setting firebase

hyeseon han·2021년 10월 11일
0

SQL vs NoSQL

SQL

관계형 데이터베이스 관리 시스템(RDBMS)의 데이커를 관리하기 위해 설계된 특수 목적의 프로그래밍 언어이다. 관계형 데이터베이스 관리 시스템에서 자료의 검새과 관리, 데이테베이스 스키마 생성과 수정, 데이ㅓ베이스 개게 접근 조정 관리를 위해 고안되었다.

NoSQL

데이터베이스는 전통적인 관계형 데이터베이스 보다 덜 제한적인 일관성 모델을이용하는데 데이터의 저장 및 검색을 위한 매커니즘을 제공한다.

DBeaver

SQL 클라이언트이자 데이터베이스 관리 도구이다. NoSQL의 경우 사유 데이터베이스 드라이버를 사용한다.

PostgreSQL

확장 가능성 및 표준 준수를 강조하는 객체-관계형 데이터베이스 관리 시스템(ORDBMS)의 하나이다.

TypeORM

ORM: 코드의 객체와 데이터베이스의 데이터를 일치시켜주는 도구이다.

  1. 데이터베이스 만들기(ORM을 이용해서 만들기)
  2. DB와 연결하기
  3. API 만들기
//Board.postgres.ts
// TyeORM 타입 지정

import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from "typeorm";

 // @Entity() 데코레이터 라고 부름
 // @Entity() 이걸로 인해서 읽힐 때 데이터베이스에 테이블이 만들어지게 됨.
@Entity()
export default class Board extends BaseEntity {
  
  // 자동으로 1씩 증가하는 숫자.
  @PrimaryGeneratedColumn("increment") // PK
  number!: number;

  // @Column 테이블의 열이 됐음을 알려줌
  @Column({ type: "text" })
  writer!: string;

  @Column({ type: "text" })
  title!: string;

  @Column({ type: "integer" })
  age!: number;

  @Column({ type: "timestamp", default: null, nullable: true }) //null이 들어갈수 있는 타입이냐
  deleteAt?: Date;
}
import { createConnection } from "typeorm";
import { ApolloServer, gql } from "apollo-server";
import Board from "./Board.postgres";

// 플레이그라운드에서 보는내용(타입정의)
const typeDefs = gql`
  input CreateBoardInput {
    writer: String
    title: String
    age: Int
  }

  # Retrun 이름은 아무거나 해도 상관없음
  type Return {
    message: String
    number: Int
  }
  # 타입의 이름이 Board일뿐.
  type Board {
    number: Int
    writer: String
    title: String
    age: Int
  }

  type Query {
    fetchBoard: Board
    fetchBoards: [Board] # 객체니까 [] 담는다.
  }

  type Mutation {
    # Return 안에 메세지가 들어있음
    #( ) 안에 input 으로 타입을 씀. 갯수가 많을 때 위에 처럼 input type을 따로 줌.
    # 주석 createBoard(writer: String, title: String, age: Int): Return
    createBoard(createBoardInput: CreateBoardInput): Return # 반드시 있어야하면 CreateBoardInput!
    updateBoard: Return
    deleteBoard: Return
  }
`;
// type 을 지정해줘에 local4000에서 볼수 잇음

// 실제로 실행되는 API(실행되는 함수)
const resolvers = {
  Query: {
    // API 명
    fetchBoard: async () => {
      // 데이터베이스에서 해당하는 데이터 꺼내서 브라우저에 던져주기(응답주기)
      // findeOne: 하나를 찾아와라. where: 위치?
      const result = await Board.findOne({
        where: { number: 1, deleteAt: null },
      });
      return result; // fetchBoards 와 마찬가지로 배열이니까 굳이 길게 안쓰고 return result로 하면됨.

      // return {
      //세개의 객체가 됨
      //   writer: result?.writer,
      //   title: result?.title,
      //   age: result?.age,
      // };

      // return { writer: "철수", title: "제목입니다." };
    },
    fetchBoards: async () => {
      const result = await Board.find({ where: { deleteAt: null } }); //이미 배열에 담겨져 나옴 [{..},{..}...]
      return result;
      //  result.map 맵은 배열일 때 사용. 이미 배열이 담겨져 나오니까 리턴리졸트
    },
  },

  Mutation: {
    // API 명
    createBoard: async (_: any, args: any) => {
      // 데이터베이스에 데이터 입력하기
      // const result = await Board.insert({
      //   title: args.title, //"안녕하세요",
      //   writer: args.writer, //"철수",
      //   age: args.age, //20,
      // });
      const result = await Board.insert({
        ...args.createBoardInput, //아래 세개랑 같은 내용
        // title: args.createBoardInput.title,
        // writer: args.createBoardInput.writer,
        // age: args.createBoardInput.age,
      });
      console.log(result);
      return { message: "성공했습니다.", number: result.identifiers[0].number };
      // return { message: "성공했습니다.", number: 3 };
    },
    updateBoard: async (_: any, args: any) => {
      await Board.update({ number: 3 }, { writer: " 영희" });
      //(  {조건}, {변경할 값} } )
      return { message: "수정완료" };
    },

    deleteBoard: async () => {
      // await Board.delete({ number: 4 });
      await Board.update({ number: 5 }, { deleteAt: new Date() });
      return { message: "삭제완료" };
    },
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

// 데이터베이스 연결
createConnection({
  type: "postgres",
  database: "postgres",
  username: "postgres",
  password: "********",
  port: ****,
  host: "34.64.221.225",
  entities: [__dirname + "/*.postgres.ts"],
  logging: true,
  synchronize: true,
})
  .then(() => {
    // 연결성공시 실행
    console.log("접속완료!!!");
    server.listen({ port: 4000 }); // 연결을 기다리겠다.
  })
  .catch((error) => {
    console.log(error);
  }); //어떤 에러인지 확인할 때

백엔드 초기 셋팅

타입스트립트 기반의 node.js 백엔드 폴더 만들기

  1. 최상위 폴더에서 📁 class_backend 폴더 만들기

  2. yarn init
    ∴ 📁 package.json 생성

  3. yarn add typeorm
    ∴ 📁 node_modules / yarn.lock 폴더 생성
    ∴ 📁 package.json 에 "typeorm" 생성

  4. yarn add graphql
    ∴ 📁 Package.json 에 “graphic” 생성

  5. yarn add apollo-server
    ∴ 📁 Package.json 에 “apollo-server” 생성

  6. yarn add pg
    ∴ 📁 Package.json 에 “pg” 생성

  7. yarn add -D typescript
    ∴ 📁 Package.json 에

    "devDependencies": { "typescript": "^4.4.3"}
  8. 📄 index.js 파일 생성

  9. 📁 package.json 에 입력

    "scripts": {
          "dev": "node ./index.ts"
          },
  10. yarn add ts-node
    “ts-node”: ~ 생성

  11. yarn add -D ts-node-dev
    “ts-node-dev” 생성

  12. yarn add -D ts-node
    “ts-node”생성

    "ts-node""devDependencies으로 내려준다

    "devDependencies": {
        "ts-node": "^10.2.1",
        "ts-node-dev": "^1.1.8",
        "typescript": "^4.4.3"
      }
  13. yarn install

  14. rm -rf node_modules

  15. yarn install (혹시 “scripts”~ 부분 사라졌으면 다시 입력하기)

  16. yarn dev

  17. 📄 Board.postgres.ts

  18. 📂 tsconfig.json 생성

  19. 위 폴더 안에

      "compilerOptions": {
        "target": "ES2015",
        "module": "commonjs",
        "strict": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true
      },
      "$schema": "https://json.schemastore.org/tsconfig",
      "display": "Recommended"
       }

    입력
    https://www.npmjs.com/package/@tsconfig/recommended

  20. 📄 Board.postgres.ts 의 class Board 에 마우스를 갖다대면 set 메세지가 뜬다.

  21. 📂 tsconfig.json 에

    ```jsx
      "experimentalDecorators": true
    ```

    넣어준다.

Firebase

import {
  getFirestore,
  collection,
  addDoc,
  getDocs,
} from "firebase/firestore/lite";
import { firebaseApp } from "../_app";

export default function FirebasePage() {
  async function onClickSubmit() {
    const blog = collection(getFirestore(firebaseApp), "blog");
    await addDoc(blog, {
      writer: "철수",
      title: "제목입니다",
      contents: "내용입니다.",
    });
  }

  async function onClickFetch() {
    const blog = collection(getFirestore(firebaseApp), "blog"); // 블로그 라는 객체를 마늠
    const result = await getDocs(blog);
    const docs = result.docs.map((el) => el.data());
    console.log(docs);
  }

  return (
    <>
      <div>파이어베이스 페이지 입니다.</div>
      <button onClick={onClickSubmit}>등록하기</button>
      <button onClick={onClickFetch}>불러오기</button>
    </>
  );
}

0개의 댓글