[Week13] 0414

안나경·2024년 4월 14일

크프정 일상

목록 보기
93/109

어제의 이야기

어제 공부한 것

TIL 쓰고나서
게시글 delete 확인하고

로그인 파트를 읽는데
로그인 파트를 하면서 mySQL DB간 관계 정의 파트 보다가
보는 걸로는 이해가 바로 안 되어서 실습해보고 나니

로그인 파트는 또 passport 모듈을 쓰니까
그냥 슥 보는 걸로는 이해가 잘 안 되어서
해보다가...

그치만 별로 못한게
낮에 팀원분들에 관한 협의...기타 등등...하느라고
낮에는 그걸로 시간이 다 가고 저녁엔 진이 빠져서 일찍 퇴근했음

Delete 실습 동안 확인한 것.

  • 삭제 완료시에는 대개 200 OK 정도 보내는 듯.
  • status를 먼저 보내고 그다음 json을 보낸다.
  • res.redirect()는 그 메서드가 알아서 상태 코드를 보내준다.
  • res.app의 app은 Express 앱을 나타내는 것으로, 그 서버가 뭘 쓸지 use, set, listen등을 쓰는 객체임.
  • res.locals는 미들웨어끼리 정보를 주고받을때 정보 저장용으로 쓰는데, 요청이 완료되면 사라짐.
  • render로 변수를 넘기면, 템플릿 엔진의 경우 locals.user.username 등 태그 안에 언급해서 렌더링 시킬 수 있음.

session 읽는 동안 확인한 것.

  • session의 store 옵션은 데이터베이스등에 저장할 때 사용.
    connect-mongo 패키지를 쓰며, session 미들웨어 설정시 옵션에 추가.
const MongoStore = require('connect-mongo')(session);

app.use(session({
  secret: 'your-secret-key',
  resave: false,
  saveUninitialized: true,
  store: new MongoStore({ mongooseConnection: mongoose.connection }) // MongoDB에 세션을 저장
}));

후자의 mongoose.connection은 따로 연결을 해야함.

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/my_database', {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

const db = mongoose.connection;

collection의 이름을 따로 짓고 싶다면 store 옵션의 키값에 설정한다.

  store: new MongoStore({ 
    mongooseConnection: mongoose.connection,
    collection: 'my_sessions' // 컬렉션 이름 설정
  })
  • req를 session에 저장 자체는, 그냥 선언해서 변수를 받는 부분 자체에서 알아서 저장이 됨.

관계 DB 공부시 확인한 것.

  • 외래키는 다른 db를 참고해서 짓는 걸 가리킴.
    제약 조건, 컬럼, 참고하는 컬럼 순으로 쓰는데,
CREATE TABLE 테이블이름 (
    컬럼이름 데이터타입,
    외래키컬럼이름 데이터타입,
    CONSTRAINT 제약조건이름 FOREIGN KEY (외래키컬럼이름) REFERENCES 참조테이블이름(참조컬럼이름)
);

즉 외래키컬럼 자체를 한번 선언하고 대개 제약조건이름, 외래키컬럼 이름을 일치해서 쓴 뒤, 참조테이블 이름과 참조 컬럼을 씀. ex) User(id) 같이.

  • router.route('/:id') 처럼 하면 주소는 주소/id 같은 형태로 들어감.
    (주소?id=3 같은 형태가 아니라.)
    근데 postman으로 param 설정하면 후자처럼 들어가서 내가 설정을 param으로 넣었을때 제대로 route 해석이 되는 건지 궁금하긴 함.
  • db 에서 id는 순차적으로 생기고, 삭제되면 다시 채워지지 않음. 대개 삭제가 되더라도 이후에 추적이 꼬이지 않게 하기 위함. 요즘 메모리로 따지면 그 숫자가 커져서 이슈가 생기진 않음.

내장 모듈 다시 확인하기.

  • nunjucks 템플릿 엔진의 express 키 값에 들어가는 app은 그 express의 app 객체를 넣는다는 것을 의미.
    watch: 템플릿 파일이 수정되면 자동으로 변경사항 반영하는 옵션.
    앞부분 첫번째 인수는 폴더명 경로임.
  • session 옵션을 보면
app.use(session({
  resave: false,
  saveUninitialized: false,
  secret: process.env.COOKIE_SECRET,
  cookie: {
    httpOnly: true,
    secure: false,
  },
}));

resave는 수정사항이 없어도 자동 저장할지, saveUninitialized는 초기화되지 않은 세션을 저장할지, 인데, 보통 보안 관련해서 세션 생성 허가를 받기전까지는 초기화 되지 않은 세션을 저장하지 않아야함.
그냥 인증과 권한을 관리용으로 저장은 할수는 있음.

  • sequelize는 하단에 옵션 파트가 아예 따로 있는데
 sequelize,
      timestamps: true,
      underscored: false,
      modelName: 'User',
      tableName: 'users',
      paranoid: true,
      charset: 'utf8',
      collate: 'utf8_general_ci',
    });

timestamps는 생성및 수정 시간이 자동 기록되고,
underscoredsms...언더바(_)임.
이걸 사용하면 대문자를 소문자로 변환하거나 단어사이 언더바를 추가함.
paranoid는 활성화하면 실제로 삭제하지 않고 삭제했다는 표시를 함.

  • 특히 여기서 modelName과 tableName은
    내가 앞으로 여기서 작성했던 테이블들을 참조하기 위해 쓰는 이름을
    여기서 필요하면 재정의할수 있음.(보통 내가 처음 선언한 클래스 이름 그대로 쓰긴함.)
  • sequelize 를 작성하고 DB를 명령어로 생성할때는 자바스크립트 파일을 만들어 그냥 서버 자체를 돌려서 반영시키는데, 그때 쓰는 코드가 이거임.
sequelize.sync({force:false})
.then(() => {
    console.log('데이터베이스 연결 성공');
})
.catch((err) => {
    console.error(err);
});

sync는 동기화 시킨다는 건데, 여기서 force는 내가 만약 변경했다면
DB가 손상되더라도 반영시킬지 여부임. 대개 개발환경에서 true를 쓰고
서비스 중에는 false로 한다.

그 이후는 책의 nodebird , nodejs로
SNS만들기를 하는데, express 수준에서 controller 만들어서 관리하더라.

express로 controller 만들기

  • route에 page.js로 controller 폴더에 page에 있는 route를 다 get으로 가져와서 주소를 연결하기.
const { renderProfile, renderJoin, renderMain } = require('../controllers/page');

router.get('/profile', renderProfile);

router.get('/join', renderJoin);

router.get('/', renderMain);
  • 그리고 controller의 page에 exports.으로 method들을 구현하되, 기본적인 render만 수행하기.
exports.renderProfile = (req, res) => {
    res.render('profile', { title: '내 정보 - NodeBird' });
  };

DB 끼리 관계 정의하기

  • 일단 models 폴더에 index로 model 등을 다 부르고 intiate해야하는데, forEach로 자동으로 다 연결하게 할수도 있고 수동도 가능.
  • class 안에
    static initiate, static associate가 있는데
    전자는 보통 그 클래스 관련을 선언하고(init 하고 sequelize 옵션 설정함.)
    후자는 관계성 있는 DB를 이음.

관계성은...

  • User hasMany -> belongsTo Post
    ( 1 대 N )
  • 같은 DB끼리 서로 여럿을 소유할 수 있다고 할때
    User belongsToMany - User belongsTomany
    가 가능한데 각각 A입장에서 B를 보는 것과
    B입장에서 A를 보는 것이 다를 경우 두번 각각 선언 한다.
    db.User.belongsToMany(db.User, {
        foreignKey: 'followerId',
        as: 'Followings',
        through: 'Follow',
    })

이건 내 User 칼럼에서 followerId라는 칼럼을 만들거고
매칭되는 DB의 이름은 as로 Followings며
이 공동 모델 이름을 Follow로 한다.
(즉, 팔로잉을 찾으려면 먼저 팔로워하는 사람의 아이디를 찾아야한다..)
(몰라 난 모르겠다 반대로 쓰면 된다고는 한다.)

  • 만약 서로의 관계성이 각자 다르지 않다면 그냥 한번만 선언하고 through로만 선언한다. 이때 DB는 같은 거든 다른거든 되는거같긴한데.
    db.Post.belongsToMany(db.Hashtag, {through: 'PostHashtag'});

쓰다보니 궁금해서
mongoDB는 관계성을 어떤 식으로 정의하는지 지피티에게 물어봄

  • 참고하는 칼럼을
const BookSchema = new mongoose.Schema({
  title: String,
  author: { type: mongoose.Schema.Types.ObjectId, ref: 'Author' },
});

식으로 type을 명시하고 ref로 내가 정의했을 model을 ref로 가져온다음

Book.find().populate('author').exec(function(err, books) {
  // books 배열은 모든 책을 포함하며 각 책의 작성자 정보가 채워진 상태입니다.
});

populate로 포함시켜서 함.
참고로 저건 단순 문자열로 쓰는게 아니라 이미 정의된 model이 임포트하고 있어야함.

const AuthorSchema = new mongoose.Schema({
  name: String,
});

const Author = mongoose.model('Author', AuthorSchema);

소감

배고프다
뭔가 말할랬는데 까먹었네

질문했던거 생각보다 다시 보니 기억을 못하고 있었음
그런 의미에서 지피티가 참 다시 복기하기 좋아
공부하기도 좋고...

오늘의 계획

변경 사항 및 일정

사실 낮에도 공부하려했는데 끝내주게 쉬었음

오전

늘 보는 유튜버가 신작이없음
다른 유튜버 보려했는데 인간 얼굴만 쳐다보는 유튜브는 어색하다
상황극을 잘하는 유튜버를 봤음

낮잠잠
고양이가 무거웠음
보통이면 악몽이라도 꿨을텐데
아무튼 긴장이 좀 풀렸음

그리고 팀을 짠다면
어떤 식으로 첫날을 할지
커뮤니케이션은 어떤 식으로 할지 구상함.

저녁

좀 늦게 옴
올라올까말까 하다가 올라왔음

다른분들 얘기 들으면서 TIL 쓰니
벌써 11시임..

오늘의 다짐

음 자기소개만 올리고 퇴근해야지

사실 로그인과 이미지 업로드까진 공부하고
react를 볼까했는데 월 화만 남았네
아니 수요일까지 있긴 한데...

profile
개발자 희망...

0개의 댓글