๐Ÿ  TIL 0207

j00b33ยท2022๋…„ 2์›” 7์ผ
0

CodeCamp FE 05

๋ชฉ๋ก ๋ณด๊ธฐ
18/33

โฌ‡๏ธ Main Note
https://docs.google.com/document/d/1oMku0twdgRbrT4l17wijbS0L54FrdvlTYgJjw2lYaJw/edit


๐ŸŒฟ [cors]

: cross origin resource sharing

  • requesting origin
  • When this error occurs, that means backend didn't allow the request.
  • Usually error pops out when the sites are mix-matched.
    --> ex) When koreanjson.com and mysite.com are crossed, corse appears but when backend allows, then the request goes successfully.
  • Even it isn't allowed, the data is sent, It's just the browsers who block the request.
  • Detouring the route => Proxy Server

๐Ÿงข [Apollo Server]

  • Creating my own API
  • Can make multiple and see what data it is containing.

โฌ‡๏ธ Creating my own API

import { createConnection } from "typeorm";
import { ApolloServer, gql } from "apollo-server";
//graphql ์„ค์น˜ํ•ด์ค˜์•ผํ•จ
import { Board } from "./Board.postgres";

const typeDefs = gql`
  type Board {
    number: Int
    writer: String
    title: String
    age: Int
  }

  input CreateBoardInput {
    writer: String!
    title: String!
    age: Int!
    # type์€ return์œผ๋กœ ๋ฐ›๋Š” ๋ถ€๋ถ„๋งŒ ๊ฐ€๋Šฅํ•จ ๊ทธ๋ž˜์„œ input ์ด๋ผ๊ณ  ๋ฐ”๊ฟ”์ค˜์•ผํ•จ
    # type ๊ณผ input type์˜ ์ฐจ์ด์ 
  }

  type Query {
    fetchBoards: [Board]
  }

  type Mutation {
    createBoard(createBoardInput: CreateBoardInput): String
    deleteBoard(number: Int!): String
    # //ID๋Š” number type, ๋ฆฌํ„ด ๋ฉ”์‹œ์ง€๋Š” string

    # string์ด๋ž€ ๋ฆฌํ„ด์ด ๋‚˜์˜ด
    # String! => ! ๋ฐ˜๋“œ์‹œ ์žˆ์–ด์•ผํ•œ๋‹ค (๋Š๋‚Œํ‘ฑ)
    # ๋Š๋‚Œํ‘œ๊ฐ€ ์žˆ์œผ๋ฉด ์žˆ์„์ˆ˜๋ก ์•ˆ์ „ํ•ด์ง€์ง€๋งŒ ์ œ์•ฝ์ด ๋งŽ์ด ๊ฑธ๋ฆฌ๋Š๊ฑฐ์ž„
  }
`;

const resolvers = {
  Query: {
    fetchBoards: async () => {
      //DB์™€ ์—ฐ๊ฒฐ (๊บผ๋‚ด์„œ ์˜ค๊ธฐ)
      const result = await Board.find({
        //find : ์ด๋ฆ„ ์ฒ ์ˆ˜ ์ธ ์•  ๋‹ค ๊ฐ€์ ธ์˜ค์…ˆ 10๊ฐœ๋ฉด 10๊ฐœ ๋‹ค ๊ฐ€์ ธ์™€
        //๋‹ค ์ฐพ์•„์˜ฌ ์ˆ˜๋„ ์žˆ๊ณ --()--์‚ฌ์šฉ // ์กฐ๊ฑด์„ ๊ฑธ ์ˆ˜๋„ ์žˆ์Œ : where ์‚ฌ์šฉ
        where: { writer: "์ฒ ์ˆ˜", deletedAt: null },
        //์ด๋ฆ„์ด ์ฒ ์ˆ˜์ด๋ฉฐ deletedAt ์ƒํƒœ๊ฐ€ null ์ธ๊ฒƒ๋“ค์„
      });
      console.log(result);
      return result;
      //string์ด๋ž‘ result๋ž‘ ๋‹ค๋ฆ„. ์–œ ์ด์ œ๋ถ€ํ„ฐ Board type์ด ๋˜์–ด์•ผํ•จ
    },
  },

  Mutation: {
    createBoard: async (_: any, args: any) => {
      //args: ์‹ค์ œ ์ธ์ž (์ธ์ž๋ฅผ ๋ฐ›์•„์™€์„œ ๋„˜๊ฒจ์ค˜์•ผํ•˜๊ธฐ๋•Œ๋ฌธ์— ์‚ฌ์šฉ)
      //parent๋Š” ์•„์ง ์•ˆ์“ฐ๊ธฐ๋•Œ๋ฌธ์— _์ฒ˜๋ฆฌ
      //DB์™€ ์—ฐ๊ฒฐ (์ €์žฅํ•˜๊ณ  ์ €์žฅํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ด)

      //   await Board.insert({
      //     writer: "์ฒ ์ˆ˜",
      //     title: "์ œ๋ชฉ์ž…๋‹ˆ๋‹ค",
      //     age: 12,
      //   });
      //-->์ด๋žฌ๋˜๊ฑธ ์•„๋ž˜์ฒ˜๋Ÿผ ํ•ด์„œ ์ง์ ‘ ์ธ์ž๋ฅผ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ๋” ๋งŒ๋“œ๋Š”๊ฒƒ โฌ‡

      await Board.insert({
        //   ...args.createBoardInput  (--> ์ด๊ฑฐ ์“ฐ๊ฑฐ๋‚˜ ์•„๋ž˜ 3์ค„ ์“ฐ๊ฑฐ๋‚˜)
        //spread์—ฐ์‚ฐ์ž ์‚ฌ์šฉํ•˜๋ฉด ๋” ์ถ•์•ฝํ•  ์ˆ˜ ์žˆ์Œ
        writer: args.createBoardInput.writer,
        title: args.createBoardInput.title,
        age: args.createBoardInput.age,
      });
      return "createBoard๋ฅผ ์š”์ฒญํ•˜์…จ์Šต๋‹ˆ๋‹ค";
    },

    deleteBoard: async (_: any, args: any) => {
      //์ด๋Ÿฌ๋ฉด args์— ์‚ฌ์ œ์š”์ฒญํ•œ ID๊ฐ€ ๋“ค์–ด์˜ค๊ฒŒ ๋จ
      args.boardID;
      await Board.update({ number: args.number }, { deletedAt: new Date() });
      //{์กฐ๊ฑด}, {๋ฐ”๊ฟ€ ๋‚ด์šฉ}

      // Board.delete({writer: "์ฒ ์ˆ˜", isDeleted: false})
      //writer๊ฐ€ ์ฒ ์ˆ˜ ์ธ ์• ๋“ค ์ „๋ถ€ ๋‹ค ์ง€์›Œ๋ฒ„๋ฆฌ๋Š”๊ฒƒ
      //isDeleted ๋กœ ์‚ญ์ œ๋œ๊ฑฐ์ฒ˜๋Ÿผ ๋ณด์—ฌ์„œ ์กฐํšŒ๋งŒ ์•ˆ๋ ๋ฟ ๋ฐ์ดํ„ฐ๋Š” ์žˆ์Œ (์‹ค์ œ๋กœ ๋ง‰ ์ง€์šฐ์ง„ ์•Š์Œ)
      //์ด๋Ÿฐ ์‚ญ์ œ๋ฅผ soft delete๋ผ๊ณ  ํ•จ

      return "์‚ญ์ œ๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค";
      // --> soft delete
    },
  },
};

//server๋Š” ๊ทธ๋ƒฅ ์ด๋ฆ„์ด์—ฌ์„œ aaa๋กœ const ํ•ด์ค˜๋„ ์ƒ๊ด€์—†์Œ
const server = new ApolloServer({
  typeDefs,
  //type ๋„ฃ๊ณ 
  resolvers,
  //api ๋„ฃ๊ณ 
  cors: true,
  //cors ๋ฌธ์ œ ํ•ด๊ฒฐ
  //   corse:{
  //       origin: "http/mysite.com"
  //   }
  //--> ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด mysite๋งŒ true๋กœ ํ•˜๊ณ  ๋‚˜๋จธ์ง€๋Š” ๋‹ค False
});

console.log("hello typescript");

//๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ์ฝ”๋“œ๋ฅผ ์จ์ค˜์•ผํ•จ
createConnection({
  type: "postgres",
  database: "postgres",
  username: "postgres",
  password: "postgres2021",
  port: 5021, //๋‚ด ๊ฐœ์ธ ํฌํŠธ๋ฒˆํ˜ธ
  host: "34.64.187.209",
  entities: ["./*.postgres.ts"],
  logging: true,
  synchronize: true,
})
  .then(() => {
    //์—ฐ๊ฒฐ ์„ฑ๊ณต์‹œ ์‹คํ–‰
    console.log("์ ‘์†์™„๋ฃŒ");

    server.listen({ port: "4000" });
    // ์„œ๋ฒ„ ์ ‘์† ์™„๋ฃŒ ํ•˜๋ฉด --> 4000 ๋ฒˆ ํฌํŠธ๋กœ 24์‹œ๊ฐ„ ๊ธฐ๋‹ค๋ฆฌ๋Š”๊ฒƒ (listen)์˜ ๊ธฐ๋Šฅ
    // ๊ทธ๋Ÿผ 4000๋ฒˆ์„ ๊ธฐ์ค€์œผ๋กœ ๋‹ค์–‘ํ•œ API๊ฐ€ ์กด์žฌํ•˜๋Š”๋ฐ ๊ทธ ์ค‘ fetchBoards๋ž‘ createBoard๋ฅผ ๋งŒ๋“ ๊ฒƒ
  })
  .catch((error) => {
    //์—ฐ๊ฒฐ ์‹คํŒจ์‹œ ์‹คํ–‰
    console.log(error);
  });

  • Able to fetch and delete boards.

๐Ÿ’ง[Firebase]

  • Firebase is useful for frontend developers who work without backend developers.
  • Frontend devloper can directly save data into database.
  • Since there is not backend computer that secures the data, it might seem dangerous. But via using firebase, the google provides those securities.
    --> BAAS : Backend As A Service
    : Lend backend as a service
  • To use BAAS, the user must access to the homepage and write the source code.
    --> It's simple and easy to use when making a simple service.
    --> No need for complicated source code, but only frontend codes.
  • Also, firebase is usually used for testing the web page, so the developer can extend developing when it works successfully.
  • Firebase use noSQL.
    --> collection usage.
    --> Collection saves the data as an object form.

โฌ‡๏ธ Practice

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

export default function FirebasePage() {
  const onClickSubmit = async () => {
    //firebase์— ํ•œ์ค„ ๋“ฑ๋กํ•˜๊ธฐ
    const board = collection(getFirestore(firebaseApp), "board");
    //์ ‘์†์ •๋ณด, ์ปฌ๋ ‰์…˜ ์ด๋ฆ„
    await addDoc(board, {
      writer: "์ฒ ์ˆ˜",
      title: "์ œ๋ชฉ์ž…๋‹ˆ๋‹ค",
      contents: "๋‚ด์šฉ์ž…๋‹ˆ๋‹ค",
    });
  };

  const onClickFetch = async () => {
    //firebase์—์„œ ๋ฐ์ดํ„ฐ ๊บผ๋‚ด์˜ค๊ธฐ
    const board = collection(getFirestore(firebaseApp), "board");
    const result = await getDocs(board);
    const docs = result.docs.map((el) => el.data());
    console.log(docs);
  };
  return (
    <div>
      <h1>ํŒŒ์ด์–ด๋ฒ ์ด์Šค ์—ฐ์Šต ํŽ˜์ด์ง€์ž…๋‹ˆ๋‹ค</h1>
      <button onClick={onClickSubmit}>๋“ฑ๋กํ•˜๊ธฐ</button>
      <button onClick={onClickFetch}>์กฐํšŒํ•˜๊ธฐ</button>
    </div>
  );
}

Then, this can be seen in firebase Page as:

profile
์ฝฑใ…†l

0๊ฐœ์˜ ๋Œ“๊ธ€