IT STUDY LOG

[SECTION2] <AWS 배포 자동화> DAY 4 LOG 본문

devops bootcamp 4/project log

[SECTION2] <AWS 배포 자동화> DAY 4 LOG

roheerumi 2023. 5. 2. 16:10

# 학습 목표

  • 프론트엔드의 배포를 자동화
  • CDN을 통해 프론트엔드를 캐싱하고, HTTPS를 적용
  • 프론트엔드와 WAS를 연결
  • 프론트엔드가 잘 작동하기 위해 WAS를 구현

 

# 해결 과제

💡 마일스톤10 - 서버 애플리케이션 CRUD 구현

  • API 요구사항에 맞춰 서버 애플리케이션을 작성
  • 데이터베이스에 접속해, 원하는 데이터가 잘 들어갔는지 확인
  • 프론트엔드가 잘 작동하는지도 같이 확인

 

# 과제 항목별 진행 상황

✏️  마일스톤10 - 서버 애플리케이션 CRUD 구현

Step 1 : mongoDB 초기 데이터 활용

1. ECS에 배포한 mongoDB에 mongoDB Compass를 통해 접속

1-1. mongoDB compass의 new Connection으로 AWS ECS에 배포한 mongoDB의 NLB와 연결

2. mongosh를 열어 mongoDB 데이터베이스 생성 후 전환

3. 스크립트를 작성해 DB 초기 데이터 구성

3-1. DB Data를 기입하는 스크립트 작성

db.createCollection('customer')
const customers = db.customer.insertMany([
  {"username":"김개발","address":"부산광역시 수영구 민락로 100번길"},
  {"username":"최운영","address":"서울시 마포구 양화로 777"}
])

db.createCollection('restaurants')
const menu1 = ObjectId()
const menu2 = ObjectId()
const restaurants = db.restaurants.insertMany([
  {
    "name": "용다방",
    "menu": [
      {
        "_id": ObjectId(),
        "name": "애플 시나몬 에이드",
        "price": 6500,
        "duration": 5
      },
      {
        "_id": ObjectId(),
        "name": "카페모카",
        "price": 6000,
        "duration": 5
      }
    ],
    "address": "서울시 마포구 양화로 1111",
    "rating": 4.5
  },
  {
    "name": "피프",
    "menu": [
      {
        "_id": ObjectId(),
        "name": "에스프레소",
        "price": 2000,
        "duration": 5
      },
      {
        "_id": ObjectId(),
        "name": "스트라파차토",
        "price": 2500,
        "duration": 5
      },
      {
        "_id": ObjectId(),
        "name": "크로플",
        "price": 3000,
        "duration": 10
      }
    ],
    "address": "서울시 마포구 성미산로 4444",
    "rating": 5
  },
  {
    "name": "동백커피",
    "menu": [
      {
        "_id": menu1,
        "name": "동백커피",
        "price": 4000,
        "duration": 10
      },
      {
        "_id": menu2,
        "name": "아인슈페너",
        "price": 4500,
        "duration": 10
      }
    ],
    "address": "부산시 수영구 센텀1로 777",
    "rating": 4.8
  },
  {
    "name": "미포 대구탕",
    "menu": [
      {
        "_id": ObjectId(),
        "name": "대구탕",
        "price": 10000,
        "duration": 20
      },
      {
        "_id": ObjectId(),
        "name": "알말이",
        "price": 6000,
        "duration": 20
      }
    ],
    "address": "부산시 해운대구 미포로 61",
    "rating": 4.5
  }
])

db.createCollection('courier')
const couriers = db.courier.insertMany([
  {"courier":"최배달","location":"35.169161,129.132079","available":false},
  {"courier":"박배송","location":"37.550806,126.903781","available":true}
])

db.createCollection('order')
db.order.insertMany([
  {
    "deliveryInfo": {
      "status":"preparing",
      "assignedCourier":"박배송",
      "estimatedDeleveryTime":40
    },
    "consumer_id": customers.insertedIds[0],
    "restaurant": {
      "name": "동백커피",
      "address": "부산시 수영구 센텀1로 777"
    },
    "orderedMenu":[
      {
        "name": "동백커피",
        "price": 4000,
        "quantity": 3
      },
      {
        "name": "아인슈페너",
        "price": 4500,
        "quantity": 2
      },
    ]
  }
])

db.createCollection('review')
db.review.insertMany([
  {
    "comment":"커피가 아주 일품이예요.","rating":4.5,"reply":"고객님 감사합니다. 더 좋은 커피로 보답하겠습니다.",
    "consumer_id": customers.insertedIds[0]
  }
])

3-2. MongoDB Compass를 이용해 정상적으로 DB가 입력되었는지 확인

 

Step 2 : node.js를 이용한 mongodb 개발 문서를 참고해 데이터베이스에서 데이터를 조회 및 HTTP 요청에 따라 적절한 응답을 제공

0. Request JSON Schemas

1. GET /api/restaurants

1-1. ../routes/api/restaurants/index.js 코드

'use strict'

module.exports = async function (fastify, opts) {
  fastify.get('/', async function (req, reply) {    
      const database = this.mongo.client.db("baedal");
      const restaurants = database.collection("restaurants");
      const result = await restaurants.find({}).toArray();
      reply.code(200).send(result)
  })
}

1-2. request, parameters, responses (swaggerhub)

1-3. PostMan 테스트 결과

2. GET /api/orders

2-1. ../routes/api/orders/index.js 코드

'use strict'
const { ObjectId } = require("@fastify/mongodb");

module.exports = async function (fastify, opts) {
  fastify.get('/', async function (req, reply) {
    const database = this.mongo.client.db("baedal");
    const orders = database.collection("order");
    const result = await orders.find({}).toArray();
    reply.code(200).send(result)
  })
  // ...하략 ...//
}

2-2. request, parameters, responses (swaggerhub)

2-3. PostMan 테스트 결과

3. POST /api/restaurants

3-1. ../routes/api/restaurants/index.js 코드

'use strict'
const { ObjectId } = require("@fastify/mongodb");

module.exports = async function (fastify, opts) {
  //... 상략 ...//
  fastify.post('/', async function (req, reply) {
    const restaurants = this.mongo.client.db("baedal").collection("restaurants");
    const restaurant = await restaurants
                            .findOne({ _id: new ObjectId(req.body.restaurantId) }
                            , {projection: { _id: 1, name: 1, address: 1, menu: 1 },});

    const orders = this.mongo.client.db("baedal").collection("order");
    const order = {
      _id: new ObjectId(),
      "deliveryInfo": {
        "status":"PREPAIRING",
        "assignedCourier":"9팀",
        "estimatedDeleveryTime":10
      },
      "consumer_id": new ObjectId(),
      "restaurant": restaurant,
      "orderedMenu":req.body.menu
    }

    const result = await orders.insertOne(order)
    order._id = result.insertedId; 
    reply.code(200).send(order)
  })
  //... 하략 ...//
}

3-2. request, parameters, responses (swaggerhub)

3-3. PostMan 테스트 결과

4. GET /api/restaurants

4-1. ../routes/api/restaurants/index.js 코드

'use strict'
const { ObjectId } = require("@fastify/mongodb");

module.exports = async function (fastify, opts) {
  // ...상략 ...//
  fastify.get('/:id', async function (request, reply) {
    try {
      const orderId = new ObjectId(request.params.id);

      const client = fastify.mongo.client
      const database = client.db("baedal")
      const order = database.collection("order")

      const query = { _id: orderId };

      const result = await order.findOne(query);

      if(result != null) {
        reply
          .code(200)
          .header('Content-type', 'application/json')
          .send(result)
      } else {
        reply
          .code(404)
          .header('Content-type', 'application/json')
          .send("존재하지 않는 주문입니다.")
      }
    } catch {
      reply
        .code(500)
        .header('Content-type', 'application/json')
        .send("오류가 발생했습니다.")
    }
  })
}

4-2. request, parameters, responses (swaggerhub)

4-3. PostMan 테스트 결과

 

#TROUBLE SHOOTING LOG

📝 ISSUE 1 :  mongoDB 참조 문제

1. 현상

MongoError: Use of expired sessions is not permitted , ....

2. 원인

fasitfy에서 mongodb를 플러그인으로 register할 경우 mongodb 객체를 singleton으로 사용하며 참조하므로 close를 수행하면 mongodb와의 연결이 종료되므로 발생하는 현상

3. 해결 방법

명시적으로 close()하지 않음

 

# References

https://www.mongodb.com/docs/drivers/node/current/usage-examples/findOne/

 

Find a Document — Node.js

Docs Home → Node.js You can query for a single document in a collection with the collection.findOne() method. The findOne() method uses a query document that you provide to match only the subset of the documents in the collection that match the query. If

www.mongodb.com

https://stackoverflow.com/questions/59816298/how-to-fix-mongoerror-cannot-use-a-session-that-has-ended

 

How to fix MongoError: Cannot use a session that has ended

I'm trying to read data from a MongoDB Atlas collection using Node.js. When I try to read the contents of my collection I get the error MongoError: Cannot use a session that has ended. Here is my c...

stackoverflow.com

 

Comments