18) 벌써 넷쨰쥬 수요일

이희주·2022년 6월 1일
0

React

지난시간 코드리뷰

강아지 9마리를 같이 띄워줘야 하니까 prev앞에 ...으로 스프레드 시킨 다음에, result.data.messagedp 현재 강아지사진을 추가해준다.
그래서 총 9마리 강아지가 화면에 보여지게 되는 것 !

CORS

(cross origin resource sharing)

cors 에러
: openAPI 업체에서 보안상의 이유로 아무 브라우저나 허용하지 않게 되면, 브라우저에서 받을수가 없게 되고 cors에러를 보게 된다!
(ex, 네이버에서 카카오 api 요청하면)

ApolloServer

graphql을 이용해서 api를 만들어야 하기 때문에 apollo-server 설치 (rest-API는 express 사용)

기본 api 틀 생성 및 서버 열어두기

아폴로 서버를 생성하려면 resolver(api), typeDefs(api type) 두가지가 필요하다

게시판 CRUD 만들기 실습

// 1. 타입만들기 => typeDefs
const myTypeDefs = gql`
  input CreateBoardInput {
    writer: String
    title: String
    contents: String
  }
  # input 으로 안하고 앞에 type으로 하면 오류남

  type Board {
    number: Int
    writer: String
    title: String
    contents: String
  }

  type Query {
    fetchBoards: [Board]
    # Board가 객체 형태니까 배열로 바꿔주기 위해서 괄호로 감싸주기 []
  }

  type Mutation {
    # createBoard(writer: String, title: String, contents: String): String
    # 연습용(example api에서 이런식으로 작성했음)
    createBoard(createBoardInput: CreateBoardInput): String
    # freeboard api에서는 createBoard(createBoardInput: CreateBoardInput): String 이렇게 작성
  }
`;

// 2. 함수(API)만들기 => resolvers
const myResolvers = {
  Query: {
    fetchBoards: async () => {
      //브라우저에 요청한 패치보드가 여기서 실행됨

      const result = await Board.find();
      //이 보드는 Board.postgres.ts 의 Board table
      //게시글 목록 fetch 해야하니까 .find 로 찾아옴
      //find() : 목록 조회하기, findOne() : 한 개 찾아오기

      return result;
      //요청했을 때 응답으로 받을 수 있음
      //DB에서 꺼내서 result에 저장한 값을 리턴해오기
      //return의 type과 myTypeDefs Query의 타입이 일치해야 함 ( [Board])
    },
  },

  Mutation: {
    createBoard: async (_: any, args: any) => {
      // 브라우저에 요청한 크리에이트보드가 여기서 실행됨
      // parent, args, context, info 총 4개의 인자가 들어옴
      // parent : api에서 api 요청할 때 넣어주는 애
      // args : 브라우저에서 입력한 데이터(프론트엔트) (wrter:"철수") (주로 args 많이 사용함! parent는 지금 안쓰니까 _ 언더바처리)
      // context : 로그인정보, info : api정보

      await Board.insert({
        ...args.createBoardInput,
        // writer: args.createBoardInput.writer,
        // title: args.createBoardInput.title,
        // contents: args.createBoardInput.contents,
        // freeboard.api에서는 이렇게 바뀜!

        // writer: args.writer,
        // title: args.title,
        // contents: args.contents,
        // 연습용 api에서는 ...args 로 쓸 수 있음
      });
      // 게시글을 데이터에 넣어줘야 하니까 .insert() 로 넣어줌
      // number는 자동으로 생성됨

      // 수정의 경우
      // Board.updata({writer: "철수"}, {title: "제목2"})

      // 삭제의 경우
      // Board.delete({writer: "철수"})

      // 실무에서 데이터의 삭제는 굉장히 민감한 부분이기 때문에 실제로 삭제하는것이 아니라 삭제한것처럼 보여줌
      // 1. column을 새롭게 만들고 isDelete의 불린값만 true로 바꿔줌, 그다음 isDelete가 false인 데이터들만 보여주면 된다
      // 2. 삭제 시간을 명시해준다, 그다음 deleteAt이 null값인 데이터들만 보여주면 된다
      // Board.delete({writer: "철수"} {isDeleted: true} {deleteAt: new Date()})

      return "게시물 등록에 성공했습니다!";
      // 요청했을 때 응답으로 받을 수 있음
    },
  },
};

// ApolloServer 만들어주기
const server = new ApolloServer({
  typeDefs: myTypeDefs,
  // API type
  resolvers: myResolvers,
  // API
});

// DataSource:  접속 정보 작성하는곳
const AppDataSource = new DataSource({
  type: "postgres",
  host: "34.64.124.242",
  port: 5028,
  username: "postgres",
  password: "postgres2022",
  database: "postgres",
  entities: [Board], // table 이름 입력
  synchronize: true, // DB랑 VScode 동기화
  logging: true, // 뭐 할때마다 로그 찍기
});

AppDataSource.initialize()
  //이 접속 정보로 연결 시켜조
  .then(() => {
    //.then() 성공했을때
    console.log("연결성공");

    // 백엔드 API를 리슨(24시간동안 접속가능하게 대기상태로 만들어주기)
    server
      .listen(4000)
      .then(() => {
        console.log("서버 실행 성공!");
      })
      .catch(() => {
        console.log("서버 실행 실패ㅜ");
      });
  })
  //.catch() 실패했을떄
  .catch(() => {
    console.log("연결실패");
  });

yarn dev 결과

mutation 해주기

Firebase BAAS 서비스

Firebase란?
프론트엔드 개발자가 백엔드 없이 데이터를 Firebase 에 직접 넣어줄 수 있게 해주는 것

  1. Firebase 세팅하기
  2. _app.tsx 에서 키 설정 하기
  3. 등록, 조회 실습

++
1. 나는 레이아웃에서 navigation 부분에서 메뉴 선택할 때 onclick 함수를 여러개 만들어서 각 각 따로 해줬었는데,

배열로 묶어즈고, map으로 묶어준 다음, router.push를 event.target.id 로 주면 하나하나 다 따로 안만들어도 될 것 같다!! 효율적으로 리팩토링하기!

const onClickMenu = (event: MouseEvent<HTMLDivElement>) => {
    if (event.target instanceof Element) router.push(event.target.id);
  };
  

  const NAVIGATION_MENUS = [
  { name: "라이브강아지", page: "/openapis" },
  { name: "라이브게시판", page: "/boards" },
  { name: "라이브상품", page: "/markets" },
  { name: "마이페이지", page: "/mypages" },
];

export default function LayoutNavigationUI(props: ILayoutNavigationUIProps) {
  return (
    <Wrapper>
      {NAVIGATION_MENUS.map((el) => (
        <Fragment key={el.page}>
          <MenuItem id={el.page} onClick={props.onClickMenu}>
            {el.name}
          </MenuItem>
        </Fragment>
      ))}
    </Wrapper>
  );
}
export const Wrapper = styled.div`
  height: 64px;
  background-color: #5729ff;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  font-size: 18px;
  color: white;
`;

export const MenuItem = styled.div`
  margin: 0px 60px;
  cursor: pointer;

  :hover {
    color: orange;
  }
`;
  1. map과 forEach의 차이! 둘다 도는건 똑같지만, map은 return 해주고,
    forEach는 return을 안 해주는 대신 속도가 map보다 빠르다
    return값이 없어도 될 경우에는 forEach를 사용하는게 더 효율적

  2. 자유게시판 아직 디자인 못정했는데 넷플, 왓챠 , 시지비 같은걸로 구현해볼까? 영화같은거 api 받아와서 영상 화면에 뿌려주면 좋을 것 같음

  1. 나중에 중고게시판 같은거 할 때 옆에 날씨 api 받아와서 조그맣게 날씨 띄워주면 좋을 것 같다! 중고게시판 할 때 해봐야지,,
profile
어제보다 오늘 발전하는 프론트엔드 개발자

0개의 댓글