관리 메뉴

Jerry

[스프린트][회고]chatterbox databases 본문

자기 성찰/회고

[스프린트][회고]chatterbox databases

juicyjerry 2021. 1. 18. 03:45
반응형

이번 스프린트는 먼저 쉽게 이야기하자면, 서버와 데이터베이스를 연결시켜줘야 하는 과제다. 

더 자세하고 명확하게 이야기하자면, 이전에 했던 chatterbox client와 chatterbox server에서는 Javascript 변수와 in-memory 저장 방식을 이용하는 방법으로 데이터를 받아와 스프린트를 진행했었다. 이에 반해, 이번 스프린트는 서버가 영속성(persistence)을 가져 서버를 껐다 켰다 해도 데이터가 사라지지 않게 하도록 한다. 

 

여기서 In-memory와 Persistence에 대해 잠시 집고 넘어가겠다. 바로 밑 문장을 읽어보자.

 

 

In-memory databases are more volatile than traditional databases because data is lost when there is a loss of power or the computer’s RAM crashes. Data can be more easily restored from the disks of a traditional database.

출처: www.omnisci.com/technical-glossary/in-memory-database

 

 

"In-momory 데이터베이스는 컴퓨터 RAM의 충돌이 나거나 전원이 꺼질 때 데이터 손상이 발생하기 때문에 전통적 데이터베이스 보다 휘발성이 존재합니다. 데이터는 전통적 데이터베이스 디스크로부터 쉽게 복구가 됩니다." 라고 한다. 여기서 In-memory의 특성은 데이터가 쉽게 사라질 수 있고 그에 비해 전통적인 데이터베이스는 디스크라는 저장공간으로부터 복구가 가능하다고 한다. 

다시말해, 전자는 (휘발성이 있어서) 영속성과 거리가 있으며 후자는 영속성이 존재한다고 볼 수 있다. 

 

 

스프린트 첫 단계로 DB Diagram으로 데이터베이스에서 필요한 스키마를 디자인을 했다. DB Diagram을 사용해보고 느낀 점이 간단하고 편리했는데 그 이유에는 2가지가 있다.. 그 이유는 처음에 예제 코드가 제공되는데 이 예제 코드를 보고 내가 만들고 싶은 테이블을 충분히 만들 수 있었고 Export 기능으로 원하는 디렉터리에 저장하게 되면 자동으로 schema.sql을 만들어 주었다. 

 

 

직접 만든 테이블이다

 

 

 

그 후, 추가한 스키마 파일을 mysql 서버에 로드(load) 하기 위해 아래 명령어를 수정해 사용했다.

mysql -u root < path/to/schema.sql.

 

로드를 끝낸 후, mysql에 접속하여 스키마가 잘 로드되었는지 확인을 해주었다. 

 

 

 

이후부터는 테스트 케이스에 통과에 기준을 맞추어 소스코드를 짰다. 

 

 


 

그동안 스프린트 하면서 우여곡절이 많았지만 이번 스프린트도 쉽지 않았다. 

 

첫째, 낯섬

 

먼저, 낯설다는 게 가장 컸던 거 같다. 

- MVC 디자인 패턴으로 과제를 진행하는터라 파일 구조가 왜 이렇게 되어 있는지부터 알아야 했었다. (MVC 패턴에 대한 내용은 다음 시간에 배워서 미리 맛보기로 넣은 거 같아 직접 찾아봐야하는 비중이 컸다) 

 

참고로, MVC 디자인 패턴이란?


Model–view–controller (usually known as MVC) is a software design pattern[1] commonly used for developing user interfaces that divides the related program logic into three interconnected elements. This is done to separate internal representations of information from the ways information is presented to and accepted from the user.[2][3]

출처: 위키피디아

 

 

  • MVC 모델은 Model과 View와 Controller로 각각 구분되어 서로 유기적인 프로그램 로직으로 UI(user interface)를 주로 개발하는 데 사용되는 소프트웨어 디자인 패턴이라고 한다.
    1. Model은 데이터 로직을 다루고 데이터베이스와 상호작용한다.
    2. View는 화면에 데이터가 보이게끔(렌더링) 하는 역할을 담당한다.
    3. Controller는 브라우저에서 유저의 요청이 오면, 요청에 대한 응답을 위해 Model과 View에게 지시를 한다.
    4. 참고로 Model과 View와의 상호 작용 및 접근은 MVC 디자인 패턴 상 불가하다.  

 

예를 들어, 

  1. 소비자가 소셜 커머스에서 사고 싶은 물건을 장바구니에 담는 버튼을 클릭한다. 즉, 요청(request)를 한다.
  2. Controller에서 요청(request)을 받는다.
    1. Controller는 Model에게 지시한다. Model은 선택한 물건에 대한 정보를 얻기 위해 DB와 정보를 주고 받는다.
    2. 얻은 정보를 가지고 Controller는 View에게 장바구니 페이지에 담은 물건이 추가하라고 지시한다.
  3.  Controller에서 소비자의 요청을 처리했다면, 다시 소비자에게 요청한 결과를 보여준다.

 

 

출처: https://youtu.be/DUg2SWWK18I

 

 

둘째, 환경 변수 설정

서버를 실행하기 전에 (혹은 터미널을 열 때마다) 비밀번호를 환경 변수로 분리했기에 매번 아래 코드를 해야 되었고, 가끔 까먹고 넘어갈 때마다 발생한 에러 탓에 삽집도 여러 번 했었다. 이 설정을 해준다면 (터미널을 새로 키지 않는 이상) 일일이 안 입력해도 된다. 

export process.env.변수명=비밀번호  

여기서 .env 파일을 이용하여 필요한 환경변수를 관리할 수 있다. 글쓴이는 비밀번호와 같은 개인정보를 담는 수단으로 사용했다. 

아래 두 페이지를 참고하길 바란다.

 

www.npmjs.com/package/dotenv

 

dotenv

Loads environment variables from .env file

www.npmjs.com

stackoverflow.com/questions/52084447/what-is-the-need-for-env-and-env-example-files-in-laravel

 

What is the need for env and env.example files in Laravel?

I am new to Laravel and want a simple explanation of the .env and .env.example files, why we need them and the difference between them. I know that .env is used to specify the app's database conn...

stackoverflow.com

 


셋째, 끝도 없는 에러..

 

 

에러 1

error connecting: Error: ER_ACCESS_DENIED_ERROR: Access denied for user 'root'@'localhost' (using password: NO)
    at Handshake.Sequence._packetToError (/home/juicyjerry/Desktop/Desktop/IM25/im-sprint-database/im-sprint-database/node_modules/mysql/lib/protocol/sequences/Sequence.js:47:14)
    at Handshake.ErrorPacket (/home/juicyjerry/Desktop/Desktop/IM25/im-sprint-database/im-sprint-database/node_modules/mysql/lib/protocol/sequences/Handshake.js:123:18)

 

 

두 번째에서 언급한 내용과 관련이 있지만 다른 문제가 원인이었다.

에러가 발생하고 취한 처음 조치는 비밀번호를 변경하고 권한 설정이 변경되었다고 인지시켜주도록 했는데

 

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourRootPassword';
FLUSH PRIVILEGES;

 

오타나 env 파일도 바꿔주고 터미널도 다시 껐다 켜고 하면서 여러 번 시도를 했지만 에러는 해결되지 않았다. 

도저히 모르겠어서 레퍼런스 코드와 비교해봤더니, dotenv 모듈을 불러오는 코드가 내 소스코드에는 빠져 있었다... 

아래와 같이 추가해줘서 해결했다.

 

const dotenv = require('dotenv');
dotenv.config()

 


 

에러 2

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

위 에러는 하나의 요청에 두 번 이상의 응답이 보내졌을 경우에 발생하는 에러라고 한다.

그래서 난 send()를 end()로 다 바꿨다. 그리고 다시 npm script로 돌렸더니..

이번에 이런 에러가 발생했다. 

TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Error

 

원인은 파악을 못했지만 stackoverflow를 보고 다시 원래 코드로 돌려놓았다.

stackoverflow.com/questions/61865764/the-chunk-argument-must-be-of-type-string-or-an-instance-of-buffer

 

The "chunk" argument must be of type string or an instance of Buffer

I'm running the following code and it fails with the below error. AWS Code to list all objects inside a bucker const http = require('http'); const host = '127.0.0.1'; const port = 5000; const pa...

stackoverflow.com

이후, Model과 Controller 소스코드를 수정해서 해결은 했는데 정확한 원인이 무엇이었는지 까먹었다.. (메모의 중요성)

 


 

 

에러 3

Uncaught SyntaxError: Unexpected token u in JSON at position 0

이 에러는 아랫글을 보고 바로 이해가 되었다. JSON.parse(tartget) 이란 코드가 있는데 target를 parse 해야 되는데 target이 undefined이어서 json으로 serialize가 되지 않아서 발생한 에러였다. 

 

stackoverflow.com/questions/46613243/uncaught-syntaxerror-unexpected-token-u-in-json-at-position-0

 

Uncaught SyntaxError: Unexpected token u in JSON at position 0

Only at the checkout and on individual product pages I am getting the following error in the console log: VM35594:1 Uncaught SyntaxError: Unexpected token u in JSON at position 0 at JSON.parse...

stackoverflow.com

이 3가지 에러 말고도 많은 에러가 발생했고 지나갔지만 대표적으로 위 3가지만 적어보았다. 

 

 

 

느낀 점

이번 스프린트는 정해진 시간 내에 못 끝내고 전체적인 흐름과 개념이 부족했다. 그래서 주말에 코드 하나하나 뜯어가면서 공부를 했다. 시간은 많이 걸렸다. 주말 내내 이 스프린트에 매달렸고 해결하기 위해 용썼다. 그럼에도 불구하고, 자력으로 해결이 안 되어 레퍼런스를 참고해 공부하였다. 주말에 계획이 물거품이 돼버렸지만 대신 얻어간 것도 분명히 있었다. 

 

1. 테스트 케이스를 분석하기 위해 JEST API Reference를 참조하였다.

jestjs.io/docs/en/api.html#testname-fn

 

Jest · 🃏 Delightful JavaScript Testing

🃏 Delightful JavaScript Testing

jestjs.io

 

 

2. mysql 깃허브 페이지에 있는 레퍼런스를 반복하면서 보니 레퍼런스에 대해 친밀감이 생겼고 대략 어떻게 보고 참고해야 되는지 알게 되었다. 

github.com/mysqljs/mysql#performing-queries

 

mysqljs/mysql

A pure node.js JavaScript Client implementing the MySQL protocol. - mysqljs/mysql

github.com

 

 

3. express에 대한 공부를 하게 되었다.

express에 대해 학습을 하긴 했지만 미흡한 부분을 남기고 넘어갔었는데 이번 기회에 궁금했던 것들 포함해 공부할 수 있는 시간이 되었다.  

내가 주로 공부한 사항은 

먼저, app.use의 기능을 알게 되었다. 

app.use([path,] callback [, callback...])
: Mounts the specified middleware function or functions at the specified path: the middleware function is executed when the base of the requested path matches path. 

expressjs.com/en/api.html#app.use

 

Express 4.x - API Reference

Express 4.x API express() Creates an Express application. The express() function is a top-level function exported by the express module. var express = require('express') var app = express() Methods express.json([options]) This middleware is available in Ex

expressjs.com

 

 

Q. use와 get, post, put, patch, delete 같은 메서드의 차이는 무엇일까?

app.get is called when the HTTP method is set to GET, whereas app.use is called regardless of the HTTP method, and therefore defines a layer which is on top of all the other RESTful types which the express packages gives you access to.

stackoverflow.com/questions/15601703/difference-between-app-use-and-app-get-in-express-js#:~:text=get%20is%20called%20when%20the,packages%20gives%20you%20access%20to.&text=Up%20vote%2023-,Difference%20between,use%20%26%20app

 

Difference between app.use and app.get in express.js

I'm kind of new to express and node.js, and I can't figure out the difference between app.use and app.get. It seems like you can use both of them to send information. For example: app.use('/',func...

stackoverflow.com

 

 

Q. app.get( '/messages', ...) 으로 분기하는 것과 router.get('/messages', ...) 으로 분기하는 것의 차이가 무엇일까요?

-> 둘 다 기능은 비슷하다.

전자는 이렇게 분기하겠다.

후자는 이미 이전에 상대 경로를 지정했던 코드가 있어(세부 경로를 받게 해) 처리하게 한다 

 

 

4. template engine에 대해서 알게 되었다.

의도적이었던 것은 아니었는데 mvc 패턴에 대해서 찾다 보니 알게 되어 찾아보았다.

-> 대략적으로 알아보았는데,  정적 템플릿 파일을 사용할 수 있게 하는 것으로 필요한 부분만 추가/수정해서 사용할 수 있는 장점으로 리액트의 virtualDom과 개념이 비슷하다고 생각이 들었고 개발 사이즈가 커질수록 유용하다는 것과 개발자 블로그로 많이 이용된다고 한다.   

show-me-the-money.tistory.com/56

 

템플릿 엔진이란 무엇인가?

자, 여기 인형을 만드는 업자가 있습니다. 이 업자는 인형을 만들기 시작한지 얼마 되지 않아 바느질에 익숙하지 않습니다. 고객으로부터 원하는 인형을 주문 받으면 업자는 창고에서 몸통, 눈,

show-me-the-money.tistory.com

 

5. 뭐라고 말해야 하나 모르겠지만.. 모듈화? 가 이런 것도 있구나가 있었다. 

 

최종 경로가 디렉터리일 때에 뒤에 파일명이 특정되어 있지 않은 경우에는 index.js를 찾게 된다. 따라서 다음과 같이 작성을 하셨을 때에는 models 폴더의 index.js를 찾게 된다.

const models = require('../../models');

아래 모듈화로 model 내로 다양한 접근이 가능해진다.

module.exports = db

 

 

반응형