TIL: 동물 찾기 사이트, 자바스크립에서 MySQL 구문

엉썬·2022년 4월 2일
0

Needog

목록 보기
1/8
post-thumbnail

TIL-22-04-02

동물 찾기 사이트 프로젝트(Needog)

Node.js 교과서의 프로젝트를 다시 스스로 해보는 김에 Nodebird(트워터의 클론 사이트)를 구현하는 게 아니라 내 프로젝트를 진행해 보면 어떨까 싶었다. 나름대로 프로젝트의 이름도 정했는데, Needog이다. 발음은 니덕(...)으로 니덕분에 동물을 구했다는 김빠지는 네이밍을 했다.

부끄러워

Client : React

사실 요새 Vue를 공부하고 있긴 class가 기반이 되는 Vue가 영 재미가 없다. 물론 SFC로 할 수는 있다고는 하지만 굳이 프로젝트를 하는데 시간을 더 들여서까지 뷰를 도입할 이유를 찾을 수가 없어서 일단은 보다 익숙한 React로 Client-Side를 만들기로 했다.

목표

  • React-Router-Dom@6를 잘 사용해 보기
  • Styled-Components 쓰기
  • 로그인 / 로그아웃 / 회원가입 만들어 보기
  • 실제 서버와 통신해 보기

Server : Express

서버는 뭐 노드 교과서로부터 시작한 것이니까 Express를 사용하기로 했다.
와 그런데 확실히 서버와 드디어 통신할 수 있게 되니 데이터를 어떻게 구성하고 처리할 지 알 수 있게 되어서 너무 재밌다. 진작에 다른 사람들과 프로젝트를 참여해 볼 것을... 항상 부족함을 느껴서 혼자하게 되니까 결국 서버를 배우는 지경에 오게 되었다. 그래도 Nodejs를 알아두는 것은 너무 좋은 일 같다. 다른 라이브러리라던가 네트워크도 훨씬 감각적으로 알 수 있게 되어서 좋다 😎

구성: Client/Pages; Server/Routes, middlewares

일단 가볍게 Client에 react-router-dom을 이용해서 페이지를 몇 개 생성했다. 페이지 구성은 기존에 있는 사이트와 앱을 참고했다.

  • 404
  • Adoption: 유기동물 입양
  • Care: 유기동물 보호
  • Community: 사용자 게시판, 자원 봉사 모집, 광고, 공지 사항 등
  • Home: 첫 화면
  • Missing: 실종 동물 게시판
  • SignIn: 로그인 페이지
  • SignUp: 회원가입 페이지

HeaderFooter컴포넌트도 navigation을 위해서 임의로 만들어 두었다.

Server 쪽은 간단하게 session, 그리고 passport를 이용한 기본적인 사용자 인증을 미들웨어로 설치해 두었다. mysql2를 이용한 사용자 검색 함수도 구현해 두었다.
사용자가 이용한 페이지 렌더링은 모두 Client쪽에서 React를 통해서 제어할 것이므로 route는 일단 //auth만 설정해 두었다.

기능: 회원가입 구현하기

일단은 Client/SignUp 페이지에서 Form을 통해 axios로 데이터를 처리 받아서 MySQL서버에 유저 정보를 저장하는 식으로 생각했다.

  1. 유저가 id, nickname, password를 기입한다.
  2. 유저가 회원가입 버튼을 눌러 서버로 request를 시작한다.
  3. 서버에서는 로그인 여부를 확인한 후 에이전트로 부터 받은 데이터를 처리한다.
  4. 아직 로그인 기능은 구현되지 않았으므로, MySQL을 통해서 기존에 같은 id가 있는 유저가 있는지 확인하다.
    4.1 만약 기존에 같은 id의 유저가 존재한다면 실패
    4.2 기존의 유저가 존재하지 않는다면 유저를 새로 만든다.
  5. 서버에서 응답이 오면 결과가 어찌되었던 "/"으로 redirect한다.

이슈: MySQL이 생각대로 작동하지 않았다.

그런데 전달 받은 id를 통해 table에서 유저를 찾는 함수인 findeUser에서 자꾸 오류가 발생하였다.

findUser: async (where) => {
    const [key, val] = Object.entries(where);
    try {
      const [user] = await promisePool.query(
        `SELECT * FROM users WHERE ${key}=${val}`
      );
      return user;
    } catch (error) {
      console.log(error);
    }
  },
  1. const [key, val] = Object.entries(where) 에서 첫 번재 오류가 있었다. Object.entries()는 함수의 이름이 가리키듯이 [key, value] 을 element로 갖는 배열을 반환한다. 즉 [[key1, val1], [key2,val2], ...]의 형태가 된다. 따라서 제대로 실제 코드에는 key에 배열이 들어갔고, val에는 undefined가 할당되었다.
const [key,val] = Object.entries(where);
console.log(key); //Print: [id,val]
console.log(val); //Print: undefined | [id2,val2]
  1. SELECT * FROM users WHERE ${key}=${val}에서 자꾸 오류가 발생했다. 뭔가 싶어서console.log를 찍어서 계속 확인 했는데 SQL 문법상 key는 문자열 표기("", '')를 할 필요가 없지만 val에는 문자열 표기를 했어야 했다. 따라서 SELECT * FROM users WHERE ${key}=$'{val}'와 같이 수정하였다.

마찬가지로 createUser도 같은 문제가 있어서 수정하였다.

createUser: async (enrollment) => {
    const keys = Object.keys(enrollment);
  	//const values = Object.values(enrollment);
    const values = Object.values(enrollment).map(
      (val) => '"' + val.toString() + '"'
    );
    try {
      //바뀌기 전
	  //await promisePool.query(`
      //  INSERT INTO users (${keys.toString()})
      //  VALUES (${values.toString()});
      //`);
      await promisePool.query(`
        INSERT INTO users (${keys.toString()})
        VALUES (${values});
      `);
    } catch (error) {
      console.log(error);
      throw new Error("MySQL: failed to create a user");
    }

실제 MySQL에서는 문자 표기를 계속 해왔는데 자바스크립트에서는 쿼리 구문 자체가 문자열로 표기되어있다 보니 나도 모르게 문자열 표기를 하는 것을 깜빡하게 되는 것 같다.

참고

profile
하던 일부터 끝내자

0개의 댓글