기존에는 데이터베이스 2개를 바탕으로 진행을 하려고 했다. 그런 경우 발생하는 문제가 user의 정보를 채팅로그에 담아서 해당하는 유저 정보인지 확인을 하는 과정인데 2데이터베이스를 오가는 과정에서 문제가 생길 것 같았다.
우선은 기능 구현을 해보는 것이 목적이므로 향후 RDBMS 기반에 RabbitMQ를 적용해서 만들어보는 방법도 시도해보면 좋을 것 같다 .
그래서 우선은 MongoDB단일로 진행하기로 결정!
우선은 개발용 develop 브랜치를 만들고 DBconnect관련 commit을 만들 feature/DBConnect 브랜치를 만든다.
MongoDBAtlas에 연결하면 별도로 데이터베이스를 배포할 필요 없이 클라우드에 데이터를 쌓을 수 있다. 단 MongoDB에 연결하는 정보가 노출되면 안되기 때문에 환경변수에 담아준다.
$ npm install @nestjs/config
위에 패키지를 설치해서 환경변수를 사용할 수 있도록 하고 환경변수를 모든 module
에서 접근할 수 있도록 app.module
에 isGlobal
옵션을 true
로 넣고 import
해준다.
MONGO_URI = mongodb+srv://DB_admin:<password>@nodedb.ijmlb.mongodb.net/myFirstDatabase?retryWrites=true&w=majority
그리고 .env
파일을 만들어 MONGODB_URI
를 입력해 노출이 되지 않도록 한다. (gitignore에 되어서 git에 push를 해도 제외되어 push됌)
몽고 URI는 다음과 같은 과정을 통해서 확인할 수 있다.
우선 자신의 MongoDBAtlas 대시보드에 들어가서 Connect를 눌러준다.
로컬 앱에서 작업을 할 것이기 때문에 Connect your application
을 눌러주면 다음과 같은 화면이 나온다.
위에 링크에서 받은 URI에 처음 데이터베이스를 만들 때 나온 PW를 password자리에 입력해주면 된다.
만약 password를 잊어버리면 아래와 같이 수정을 할 수 있다.
Database access
에 들어가서 해당하는 user의 Action
중에 Edit
을 눌러준다.
Password Authentication
에 Edit Password
를 눌러준다.
Autogenerate Secure Password
를 눌러서 새로운 랜덤한 pw를 발급받거나 직접 pw를 입력할 수 있다.
typescript/Javascript로 몽고DB에 접근하여 작업하기 위해서 ODM툴인 mongoose
를 다운받아준다. 그리고 nestJs에서 mongoose를 사용하기 위해 @nestjs/mongoose
도 다운받아 준다.
$ npm install mongoose
$ npm install @nestjs/mongoose
MongooseModel에 AppModule에 import를 해준다.
이때 for root의 의미는 connection과 동일하다고 생각하면 된다. (by 공식문서)
옵션 의미
useNewUrlParser : true
mongodb url
을 읽을 수 있도록 설정. 설정하지 않으면 다음과 같은 경고 발생useUnifiedTopology : true
최신 mongodb 드라이버 엔진을 사용하도록 설정
(안정적인 연결을 유지할 수 없는 경우를 제외하고 이 옵션을 true로 설정해야 한다.)db 연결 확인을 하기 전에 User의 Schema
를 만들어준다.
Shema- Mongoose
Entity- typeorm
@Schema decorator로 해당 class 가 mongoDB에 스키마 역할할 것임을 지정해주고 이 부분은 Document로부터 상속을 받아 만들어진다.
각 field는 @Prop()
을 통해 만들어지고 이 안에 required: true, unique:true
등의 속성을 넣어줄 수 있다.
이제 user폴더 안에 컨트롤러
서비스
등에서 데이터베이스에 접근해서 사용할 수 있도록 mongooseModule
을 import
해준다. import할 때는 해당 class의 이름
과 그 클래스로 만든 schema
를 맵핑해준다.
cf) forRoot
vs forFeature
의 차이
MongoURI는 forRoot를 쓰고 forFeature를 사용하는 차이가 궁금했다.
해당 클래스를 확인해보니 forRoot는 url
를 변수로 받아서 Database url을 받고 forFeature는 Model
을 받아서 해당하는 Model과 매핑을 진행한다.
진행을 하고나면 제대로 연결이 된 것을 확인할 수 있다.
mongoDBAtlas에 Browse Collections
탭에 들어가보면
의도한대로 collection이 잘 반영된 것을 확인할 수 있다.