분류 Nodejs

Node, Express 및 MongoDB로 REST API를 구축하십시오!

컨텐츠 정보

  • 조회 353 (작성일 )

본문

이 프로젝트에서는 사람들이 Youtube 계정의 데이터를 구독, 업데이트, 검색 및 삭제하는 방법을 만들 것입니다. 

우리는 데이터베이스가 수용 할 정보와 사용자가 원하는 것에 따라 데이터를 조작하는 방법을 정의하여 사용자가 YouTube 데이터베이스와 상호 작용할 수 있도록 하는 REST API를 코딩하여 이를 수행합니다.


Web Dev Simplified의 큰 외침으로 이 튜토리얼을 작성하는 데 도움을 줄 수 있는 지식에 대해 알게 되었습니다. 이에 대한 비디오 연습을 보려면 Web Dev Simplified의 자습서를 확인하십시오.


https://dev.to/beznet/build-a-rest-api-with-node-express-mongodb-4ho4 


내 GITHUB REPO 


문제가 발생하거나 잘못한 것으로 생각되어 알아낼 수 없는 경우 여기에서 완성 된 응용 프로그램의 Github Repo를 참조하십시오. https://github.com/Beznet/node-api 


프로젝트 및 종속성 설정 


중요 전제 조건 :이 학습서를 시작하기 전에 시스템에 MongoDB가 설치 및 설정되어 있는지 확인하십시오. 다음은 MongoDB가 웹 사이트에서 제공하는 안내서 링크입니다. MongoDB 설치 


먼저 터미널을 열고 이 프로젝트의 새 디렉토리를 만들어 봅시다. 이제 터미널 유형 npm init를 시작하고 각 질문에서 Enter 키를 눌러 당분간 모든 필드를 비워 두십시오. 다음으로 ExpressMongoose를 설치하려고 합니다 :


npm i express mongoose 


그런 다음이 두 개의 설치가 완료되면 다음을 입력하여 dotenvnodemon도 설치해야 합니다.


npm i --save-dev dotenv nodemon 


참고 : 위의 --save-dev는 개발 전용 종속성을 프로덕션에 저장하지 않고 저장합니다. 


dotenv를 사용하면 .env 파일에서 환경 변수를 가져올 수 있으며 nodemon은 저장할 때마다 로컬 서버를 업데이트합니다.


이전에 npm init를 실행했을 때 package.json 파일이 생성되었습니다. 이 파일에서 스크립트 아래의 'test'스크립트를 nodemon으로 서버를 시작하는 자체 스크립트로 바꾸려고 합니다.

"scripts": {
  "devStart": "nodemon server.js"
}


서버 설정 


이제 server.js라는 첫 번째 파일을 만듭니다. 파일의 맨 위에는 프로젝트에 필요한 모든 종속성을 포함 시키려고 합니다.

const express = require('express')
const app = express()
const mongoose = require('mongoose')

테스트하고 서버가 작동하는지 확인하려면 포트 3000에서 수신 대기하고 문자열이 성공하면 이 기능을 실행하여 문자열을 기록합니다.

app.listen(3000, () => console.log('server started'))

이 시점에서 server.js 파일은 다음과 같아야 합니다.

const express = require('express')
const app = express()
const mongoose = require('mongoose')

app.listen(3000, () => console.log('server started'))


데이터베이스에 연결 


mongoose.connect로 시작하는 server.js 파일의 다음 코드는 데이터베이스에 연결하는 방법입니다. 한 줄씩 설명하겠습니다.

const express = require('express')
const app = express()
const mongoose = require('mongoose')

mongoose.connect(process.env.DATABASE_URL, { useNewUrlParser: true })
const db = mongoose.connection
db.on('error', (error) => console.error(error))
db.once('open', () => console.log('connected to database'))

app.listen(3000, () => console.log('server started'))


첫 번째 줄에서는 Mongoose를 사용하여 데이터베이스에 연결할 수 있습니다. DATABASE_URL이 무엇인지 궁금 할 것입니다.이 위치는 .env 파일에서 정의한 데이터베이스에 대한 위치입니다. .env 파일을 만들지 않았다면 지금은 좋은 시간이 되었으므로 DATABASE_URL을 설정할 수 있습니다.

// .env file

DATABASE_URL=mongodb://localhost/subscribers


.env에 DATABASE_URL을 정의한 후 server.js 파일로 돌아갑니다. 이제 .env 파일에서 변수를 참조하려면 server.js 파일 맨 위에 dotenv 패키지가 필요합니다.

require('dotenv').config()


우리가 그 패키지를 얻었으면

mongoose.connect(process.env.DATABASE_URL, { useNewUrlParser: true })


… 이제 제대로 작동합니다.


계속해서, 우리는 데이터베이스를 문법적으로 보다 쉽게 ​​참조 할 수 있도록 db를 mongoose.connection로 설정했습니다. 다음으로, 데이터베이스에 오류가 발생했을 때 발생하는 작업, 즉 오류 자체를 기록하는 방법을 정의했습니다. 오류가 없으면 데이터베이스에 연결된 문자열을 터미널에 기록하려고 합니다.


승인! 많은 것들입니다. 따라서 모든 것을 정리하려면 server.js 파일이 다음과 같아야 합니다.

require('dotenv').config()

const express = require('express')
const app = express()
const mongoose = require('mongoose')

mongoose.connect(process.env.DATABASE_URL, { useNewUrlParser: true })
const db = mongoose.connection
db.on('error', (error) => console.error(error))
db.once('open', () => console.log('connected to database'))

app.listen(3000, () => console.log('server started'))


데이터베이스 연결을 테스트합시다! 


이제 데이터베이스와의 연결을 테스트하여 모든 것이 원활하게 작동하는지 확인할 수 있습니다. 터미널에서 mongod를 입력하여 데이터베이스를 시작한 다음 다른 터미널 탭에서 npm run devStart를 사용하여 서버를 시작하겠습니다. 모든 것이 잘 진행되면 서버를 시작한 후 다음 메시지가 표시됩니다.


1eg6v5zu79s73pu5i3sl.png 


서버를 성공적으로 시작했으며 데이터베이스가 작동하는 것으로 보입니다.


JSON을 허용하도록 서버 설정 


동일한 server.js 파일에서 Express에게 JSON을 수락해야 한다고 말하고 싶습니다. 이 코드 줄을 '데이터베이스가 열려 있습니다'코드 줄과 '포트 3000에서 듣기'줄 사이에 넣겠습니다.

...
db.once('open', () => console.log('connected to database'))

app.use(express.json())

app.listen(3005, () => console.log('server started'))
...


.use는 서버가 요청을 받았을 때 경로로 전달되기 전에 코드를 실행할 수 있도록 하는 미들웨어입니다. 따라서 이 예에서는 데이터 형식으로 JSON을 수락하도록 Express에 지시합니다.


경로 폴더 및 파일 만들기 


라우트라고 하는 라우트에 새 디렉토리를 만들고 이 디렉토리에 subscribers.js라는 파일을 만듭니다. 이 파일 안에는 GET, POST 또는 PATCH 요청을 받을 때 서버가 데이터를 처리하는 방법을 정의 할 위치가 있습니다.


그러나 생성을 시작하기 전에 server.js 파일로 다시 전환하여 이제 서버에서 처리하고 사용해야 하는 경로가 있다고 알려주십시오. 다음 두 줄의 코드는 실제로 server.js 파일에 필요한 마지막 줄입니다.

const subscribersRouter = require('./routes/subscribers')
app.use('/subscribers', subscribersRouter)


다음은 새로운 코드 줄이 추가 된 완전한 server.js 파일입니다.

require('dotenv').config()

const express = require('express')
const app = express()
const mongoose = require('mongoose')

mongoose.connect(process.env.DATABASE_URL, { useNewUrlParser: true })
const db = mongoose.connection
db.on('error', (error) => console.error(error))
db.once('open', () => console.log('connected to database'))

app.use(express.json())

const subscribersRouter = require('./routes/subscribers')
app.use('/subscribers', subscribersRouter)

app.listen(3005, () => console.log('server started'))

빠진 것이 있거나 잘못된 것이 있다면 지금 당장 위의 내용으로 업데이트 된 것을 확인하기 위한 훌륭한 체크 포인트입니다. 이 멀어지기 위해 등을 두 드리십시오! 우리는 다음에 재미있는 것들을 배우고 있습니다 ...


경로 설정 


이제 서버 파일이 모두 설정되었으므로 이제 새로운 subscribers.js 경로 파일로 기어를 전환하겠습니다. 시작하려면 Express를 필요로 하고 router라는 변수에 express.router() 함수를 정의하십시오. 우리가 진행하는 동안 맨 아래에 모듈 내보내기 기능을 추가하겠습니다.

const express = require('express')
const router = express.Router()

module.exports = router


코드에 들어가기 전에 경로와 정확히 어떤 일을 하고 있는지 이해해야합니다. YouTube에서 새로운 구독자를 보고 인위적으로 만들려고 하므로 다음과 같은 기준이 필요합니다. 

  • 모든 가입자를 확보하기 위한 경로
  • 한 명의 가입자를 확보하기 위한 경로
  • 하나의 가입자를 만들기 위한 경로
  • 한 명의 가입자 업데이트를 위한 경로
  • 한 명의 가입자를 삭제하기 위한 경로

이제 GET, POST 또는 PATCH 요청 여부에 따라 기본 프레임워크로 위의 각 글 머리 기호를 시작해 보겠습니다.

const express = require('express')
const router = express.Router()

// Get all subscribers
router.get('/', (req, res) => {
})

// Get one subscriber
router.get('/:id', (req, res) => {
})

// Create one subscriber
router.post('/', (req, res) => {
})

// Update one subscriber
router.patch('/:id', (req, res) => {
})

// Delete one subscriber
router.delete('/:id', (req, res) => {
})

module.exports = router


GET, POST 및 DELETE 메소드는 익숙해 보일 것입니다. 이상하게 보일 수 있는 것은 PATCH 방법입니다. PATCH 방법은 기존 PUT 방법 대신 여기에서 사용됩니다. 왜냐하면 이 방법을 사용하여 가입자의 모든 정보가 아닌 가입자 정보의 일부만 업데이트 하려고 하기 때문입니다.


또한 대부분의 매개 변수에 / : id가 포함되어 있음을 알 수 있습니다. 이는 단일 가입자에 대해 조치를 요청하는 경로에 대한 것이므로 해당 가입자의 고유 ID가 필요합니다.


API 테스트 


경로를 약간 벗어나서 지금까지 가지고 있는 API를 테스트 해 보겠습니다. '모든 가입자 확보'경로 내에서 서버로 텍스트를 보내겠습니다.

// Get all subscribers

router.get('/', (req, res) => {
   res.send('Hello World')
})


이제 API 테스트를 위해 REST Client라는 Visual Studio Code 확장을 사용하겠습니다. VS 코드가 없으면 Postman이라는 다른 프로그램을 사용하여 API 테스트에 도움을 줄 수 있습니다. 이 튜토리얼에서는 VS 코드에서 REST Client 만 사용합니다.


REST Client 확장을 설치 한 후, route 폴더에 테스트를 실행하고 route.rest라고 하는 새 파일을 작성하겠습니다. .rest로 끝나야 합니다. 그렇지 않으면 REST Client에서 올바르게 작동하지 않습니다.


이제 route.rest 파일 내에서 서버에 테스트 GET 호출을 작성해 보겠습니다.


GET http://localhost:3000/subscribers


3000 이후에 /subscribers가 있는지 확인하십시오. 방금 작성한 해당 라인 위에 마우스를 올리면 그 위에‘요청 보내기’가 표시됩니다. 그것을 클릭하고 화면 오른쪽에서 결과를 보십시오. 모든 것이 잘 진행되면 다음과 같이 보일 것입니다.


kr3wenx3n5o8qjy05t5f.png 


9 행에서 서버가 'hello world'를 다시 보냈음을 알 수 있습니다. 이는 API가 올바르게 작동하고 있음을 의미합니다! 우리는 지금까지 많은 일을 해왔고 수화 휴식을 취한 다음 모델을 시작하겠습니다.


모델 만들기 


계속해서 모델과 모델 내부에 스키마를 설정해 봅시다. 스키마는 앱이 데이터의 모양을 정의하고 MongoDB에서 문서를 설정하는 방법입니다. 혼란스럽게 들리면 무슨 일이 일어나고 있는지 더 잘 이해할 것입니다.


먼저 models이라는 새 폴더를 만들어 보겠습니다. 이 폴더 안에 subscriber.js라는 새 파일을 만들어 보겠습니다. '구독자'복수형 인 routes 파일과 달리 이 파일을 '구독자'라는 단수로 명명하는 것에 주목하세요. 아이디어는 이 모델이 개별 수준의 모든 가입자가 데이터베이스 내부를 보는 방식을 처리한다는 것입니다. '구독자'경로는 때때로 모든 가입자 구독자 경로와 같은 여러 가입자 요청을 처리합니다. 프로젝트에서 파일 이름을 지정할 때 언어가 중요하므로 언급해야 합니다.


이 새 파일에서는 스키마 모델을 사용하므로 몽구스가 먼저 필요합니다.

const mongoose = require('mongoose')


몽구스가 필요한 후에는 스키마를 정의하는 것으로 시작하겠습니다.

const mongoose = require('mongoose')

const subscriberSchema = new mongoose.Schema({})


이 자바 스크립트 객체 안에는 구독자의 다른 속성에 대한 모든 키가 있습니다. 이 키에는 name, subscribedChannel 및 subscribeDate가 포함됩니다. 우리는 기본적으로 데이터베이스에 키 유형 (필요한 경우 및 기본값을 적용해야 하는 경우)과 같은 각 키에서 무엇을 기대해야 하는지 알려고 합니다.

const mongoose = require('mongoose')

const subscriberSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  subscribedChannel: {
    type: String,
    required: true
  },
  subscribeDate: {
    type: Date,
    required: true,
    default: Date.now
  }
})


유형과 필수 속성은 매우 자명해야 합니다. 이들은 새로운 가입자에 대한 정보를 입력 할 때 해당 키가 필요한 경우 예상되는 스키마 유형 (이 경우 문자열 및 날짜)을 정의합니다.


subscribeDate에 대해 한 가지 주의 할 점은 사용자가 날짜를 기대하기 때문에 유형을 문자열 대신 날짜로 설정합니다. 날짜가 제공되지 않으면 Date.now를 사용하여 현재 날짜로 기본 설정됩니다.


계속해서 스키마에 작성하려는 마지막 코드 줄은 module.exports입니다. 이를 통해 스키마를 사용하여 데이터베이스를 사용하고 데이터베이스와 상호 작용할 수 있습니다. Mongoose에는 mongoose.model()을 사용하여 두 가지 속성을 취하는 모델을 내보내는 특별한 방법이 있습니다.

// exporting our subscriber schema

module.exports = mongoose.model('Subscriber', subscriberSchema)


‘구독자’는 데이터베이스에 모델에 부여하려는 이름이고, 다음은 구독자 스키마 인 해당 모델에 해당하는 스키마입니다.


그게 우리 모델입니다! 완성 된 스키마를 살펴보고 모든 것을 갖추었는지 확인하겠습니다.

const mongoose = require('mongoose')

const subscriberSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  subscribedChannel: {
    type: String,
    required: true
  },
  subscribeDate: {
    type: Date,
    required: true,
    default: Date.now
  }
})

module.exports = mongoose.model('Subscriber', subscriberSchema)


경로 – 가입자 생성 및 가져 오기 


이제 데이터베이스에 대한 스키마를 사용하여 모델 설정이 완료되었으므로 아래에서 routers가 필요한 subscribers.js 경로 파일에서 요청하십시오.

const express = require('express')
const router = express.Router()
const Subscriber = require('../models/subscriber')

이제 우리는 각각의 쉘을 코딩하는 경로와 함께 중단 된 부분을 선택할 수 있습니다.

// Getting all subscribers
router.get('/', (req, res) => {
   res.send('Hello World')
})

// Getting one subscriber
router.get('/:id', (req, res) => {
})

// Creating one subscriber
router.post('/', (req, res) => {
})

// Updating one subscriber
router.patch('/:id', (req, res) => {
})

// Deleting one subscriber
router.delete('/:id', (req, res) => {
})


‘Hello World’를 서버로 보냈을 때부터 테스트 응답을 받았지만 실제로 해당 경로를 Get All Subscribers에게 알리고 싶으므로 삭제할 수 있습니다.


이전 res.send ( 'Hello World') 행을 제거한 후 가장 먼저 해야 할 일은 try / catch 문을 사용하여 함수를 약속으로 감싸는 것입니다.

// Get all subscribers

router.get('/', async (req, res) => {
  try {

  } catch () {

  }
})

try 문 내부에서 모든 구독자를 모델에서 가져 오려고 합니다. 따라서 구독자 모델에 적용된 .find() 메서드를 사용하여 subscribers라는 새 변수를 해당 모델에 설정하려고 합니다.

// Get all subscribers

router.get('/', async (req, res) => {
  try {
    const subscribers = await Subscriber.find()
  } catch () {

  }
})


이름에서 알 수 있듯이 find() Mongoose 메소드는 기준에 맞는 모든 연관된 구독자 오브젝트를 리턴하여 작동합니다. 모든 구독자를 반환하므로 모든 구독자를 원하므로 괄호를 비워 두십시오.


그런 다음 방금 만든 JSON 형식의 구독자 변수 데이터로 응답을 보내려고 합니다.

// Get all subscribers

router.get('/', async (req, res) => {
  try {
    const subscribers = await Subscriber.find()
    res.json(subscribers)
  } catch () {

  }
})


마지막으로 catch 문에서 발생할 수 있는 오류를 포착하여 JSON 형식으로 500 오류로 사용자에게 전송하려고 합니다.

// Get all subscribers

router.get('/', async (req, res) => {
  try {
    const subscribers = await Subscriber.find()
    res.json(subscribers)
  } catch (err) {
    res.status(500).json({ message: err.message })
  }
})


이제 데이터베이스의 모든 가입자를 보낼 경로가 생겼으므로 실제로 데이터베이스에 가입자를 추가 할 수 있는 방법을 코딩해야 합니다. 구독자에 대한 데이터를 입력 할 수 있도록 Create One Subscriber route로 이동하십시오.

// Create one subscriber

router.post('/', async (req, res) => {
  const subscriber = new Subscriber({
    name: req.body.name,
    subscribedChannel: req.body.subscribedChannel
  })

  try {
    const newSubscriber = await subscriber.save()
    res.status(201).json(newSubscriber)
  } catch (err) {
    res.status(400).json({ message: err.message })
  }
})


몇 가지 중요한 차이점을 제외하고는 Get All Subscribers 경로와 다소 유사합니다. 우선 우리는 더 이상 데이터베이스에서 GET 호출을 수행하지 않고 데이터를 데이터베이스로 푸시 할 수 있는 POST를 수행합니다.


이 줄에 :


const subscriber = new Subscriber({... 


이전에 만든 모델에서 새 구독자에게 할당 될 변수를 만듭니다. 리콜하는 경우 새 가입자의 이름, subscribedChannel 및 subscribeDate 속성이 필요합니다.


다음 두 줄의 코드 :


name: req.body.name,
subscribedChannel: req.body.subscribedChannel 


새로운 가입자 이름 속성 및 subscribedChannel 속성에 대한 사용자 입력 요청을 저장하도록 경로를 지정하고 있습니다. subscribeDate는 이 데이터베이스 항목이 작성된 날짜 / 시간으로 자동 설정되므로 정의 할 필요가 없습니다.


try 및 catch 문은 익숙해 보일 것입니다. 대신 find () 대신 .save () Mongoose 메소드를 사용합니다.이 라우터 함수를 통해 사용자가 전달한 정보를 보유하도록 데이터베이스에 알려주기 때문입니다.


마지막으로 :


...
res.status(201).json(newSubscriber)
} catch (err) {
res.status(400).json({ message: err.message })
} 


성공 상태가 201 인 응답을 사용자에게 보내고 새로운 구독자를 JSON으로 다시 전달합니다. 어획량은 잘못된 데이터를 전달하는 데 대한 사용자 오류이므로 400 오류를 전달하는 것을 제외하고는 모든 구독자 가져 오기 경로와 같습니다.


첫 가입자를 만들어 봅시다! 


이 시점에서 우리는 가입자를 만들고 데이터베이스에서 해당 가입자의 정보를 호출 할 수 있는 모델과 두 개의 경로를 만들었습니다. 기어를 route.rest 파일로 다시 전환하고 첫 번째 사용자를 만듭니다.

GET http://localhost:3000/subscribers

###

POST http://localhost:3000/subscribers
Content-Type: application/json

{
  "name": "Robert",
  "subscribedChannel": "Bennetts Channel"
}


REST Client를 사용하면 다른 테스트 요청을 3 행의 두 명령문 사이에 표시되는 3 개의 해시 태그로 분리해야 합니다.


첫 번째 요청은 이전과 동일해야 하므로 여기에서 유일한 다른 것은 새 POST 요청으로, 이름 (Robert)과 구독 한 채널 (mine!)로 새 구독자를 만들 수 있습니다. POST 요청을 실행하고 우리가 얻는 것을 보자.


n2095ojafy3fksfc78ex.png 


모든 것이 제대로 진행되면 '요청 보내기'를 클릭했을 때의 응답은 위와 같습니다. 우리는 방금 연결 한 모든 정보와 함께 맨 아래에 Subscriber 객체와 함께 맨 위에 201 성공 상태를 받았다는 것을 알 수 있습니다.


또한 subscribeDate는 생성 날짜로 자동 설정되므로 수동으로 설정할 필요가 없습니다. 이제 Get All Subscribers 요청을 사용하여 Robert의 정보가 반환되는지 확인하십시오.


51zg5x6qaawdvzh5ea1z.png 


데이터베이스에 단일 사용자 만 있기 때문에 응답은 Create Subscriber 응답과 비슷하지만 여러 구독자를 만들면 모든 구독자가 채워집니다.


미들웨어! 


우리는 마지막 단계에 있습니다! 마지막으로 몇 가지 해야 할 일은 Delete, Update 및 Get One Subscriber 라우트를 완료하고 REST API가 완료된 것입니다!


마지막 라우트 공유 3 개가 모두 특정 사용자의 ID를 얻는 것입니다. 코드의 해당 부분을 3 번 이상 작성하는 대신 해당 코드를 자체 함수에 넣고 Mongoose GET / PATCH / POST 문에서 미들웨어로 호출하면 됩니다. module.exports = router line 바로 앞에 getSubscriber라는 미들웨어 함수를 배치하십시오.

async function getSubscriber(req, res, next) {
  try {
    subscriber = await Subscriber.findById(req.params.id)
    if (subscriber == null) {
      return res.status(404).json({ message: 'Cant find subscriber'})
    }
  } catch(err){
    return res.status(500).json({ message: err.message })
  }

  res.subscriber = subscriber
  next()
}


여기에 많은 일이 일어나고 있습니다. 첫 번째 줄은 next라는 새로운 속성을 제외하고는 매우 친숙하게 보입니다. 기본적으로 next가 호출되면 함수 실행에 코드의 다음 섹션으로 이동하도록 지시합니다.이 getSubscriber 함수가 추가 될 경로 함수입니다.


우리의 시도와 잡기 진술은 다른 경로와 마찬가지로 열립니다. 그런 다음 가입자 모델 객체와 동일한 라인 3에서 가입자를 정의한 다음 findById 메소드를 사용하여 사용자가 상위 라우트에서 전달한 ID와 관련된 가입자를 찾습니다. 그러면 가입자는 해당 ID와 동일한 객체로 설정됩니다.


참고 :이 부분은 약간 혼동 될 수 있지만 아래의 Update / Delete / Get One 경로에 도달 할 때까지 기다려주십시오. 실제로 볼 때 더 이해가 될 것입니다.


구독자가 모델의 객체로 설정되면 if 문을 확인하여 해당 구독자가 null 검사로도 존재하는지 확인합니다. 구독자가 존재하지 않으면 404 오류가 발생합니다. 그런 다음 익숙한 오류 확인을 수행하고 사용자에게 500 상태 코드를 다시 보냅니다.


마지막으로 미들웨어 함수에서 마지막 두 줄의 코드를 남겼습니다.


res.subscriber = subscriber
next() 


res.subscriber가 응답 오브젝트에서 구독자 오브젝트와 동일한 변수를 설정합니다. 이것은 같은 코드 줄을 작성할 필요가 없으므로 이 함수에서 res.subscriber를 참조하면 됩니다. 마지막으로 getSubscriber 함수가 실제 요청으로 이동하도록 알리기 위해 다른 모든 것이 실행 된 후에 next () 함수를 사용합니다.


이제 미들웨어 기능이 완성되었으므로 Delete, Update 및 Get One 라우트에 추가하십시오.

// Get one subscriber
router.get('/:id', getSubscriber, (req, res) => {
})

// Update one subscriber
router.patch('/:id', getSubscriber, async (req, res) => {
})

// Delete one subscriber
router.delete('/:id', getSubscriber, async (req, res) => {
})


경로 – 가입자 1 명 확보 


우리는 미들웨어를 사용하여 이 마지막 3 개 노선에 대해 대부분의 노력을 기울였습니다. Get One 경로부터 시작하겠습니다.

// Get One Subscriber

router.get('/:id', getSubscriber, (req, res) => {
  res.json(res.subscriber)
})

어리석게 간단하게 보이는지 보십시오. 우리가 해야 할 일은 특정 가입자 정보를 반환하는 미들웨어 함수에서 정의한 res.subscriber를 사용하여 사용자에게 JSON 응답을 보내는 것입니다. getSubscriber 미들웨어 기능과 작성한 새 경로가 실제로 작동하는지 확인하기 위해 이 새 경로를 실제로 빠르게 테스트 할 수 있습니다.


route.rest 파일로 돌아가서 가입자 생성 요청으로 가입자를 새로 작성하여 가입자의 ID를 얻을 수 있습니다.


8cew3a9fonj1pzyyor2o.png 


새 구독자를 만들고 이름을 Bob으로 지정하면 이름 위에 객체와 관련된 ID가 길다는 것을 알 수 있습니다. 새 GET 경로를 작성할 때 Bob의 ID로 구체적으로 전화 할 수 있도록 해당 ID를 유지하고 싶습니다. 이를 Get All Subscribers 요청 아래에 넣을 수 있습니다.

GET http://localhost:3000/subscribers

###

GET http://localhost:3000/subscribers/5d3ce4ef1b5de0b79d3443b9

###

POST http://localhost:3000/subscribers
Content-Type: application/json

{
  "name": "bob",
  "subscribedChannel": "Bennetts Channel"
}


5 행에서 새 테스트 요청을 만들 수 있으므로 새로 만든 사용자의 ID를 입력하고 (위의 것과 다름) '요청 보내기'를 클릭하십시오.


yuk16o3zjex5n6xuh322.png 


모든 것이 잘 진행되면 방금 만든 것과 동일한 사용자에게 전화하기 때문에 올바른 답변에 변화가 없어야 합니다. 등을 가볍게 두드리고 미들웨어 기능과 Get One route 작동!


경로 – 가입자 삭제 


이제 미들웨어가 작업을 수행하고 있음을 알았으므로 subscribers.js 경로 파일로 다시 전환하고 Delete로 시작하는 마지막 두 경로를 완료하십시오.

// Delete one subscriber

router.delete('/:id', getSubscriber, async (req, res) => {
  try {
    await res.subscriber.remove()
    res.json({ message: 'Deleted This Subscriber' })
  } catch(err) {
    res.status(500).json({ message: err.message })
  }
})


try 문을 연 다음 res.subscriber를 설정하기 전에 await 연산자를 연결 한 다음 remove() 메서드를 사용하여 res.subscriber 객체가 설정된 구독자를 삭제합니다. 그런 다음 JSON으로 응답 메시지를 전달하여 구독자를 성공적으로 삭제했음을 사용자에게 알리고 싶습니다.


res.json({ message: 'Deleted This Subscriber' }) 


항상 그렇듯이 캐치가 사용자에게 적절한 오류가 발생하면 이를 보내도록 합니다. 그게 전부입니다!


경로 – 구독자 업데이트 


업데이트 구독자 경로는 이 응용 프로그램이 완벽하게 작동하기 위해 작성해야 하는 마지막 것입니다! 코드에 들어가기 전에 이 경우 업데이트가 어떻게 작동 하는 지에 대한 일반적인 아이디어를 얻을 수 있습니다.

  • 사용자는 이름만 업데이트
  • 사용자는 채널만 업데이트
  • 사용자는 이름과 채널을 모두 업데이트합니다
  • 아니면 엉망이 되어 오류가 발생합니다.

우리의 요구 사항은 본질적으로 변경 사항이 있는지 확인하고 변경이 필요한 경우 적절히 업데이트 해야 합니다. 이제 코드에 :

// Update Subscriber

router.patch('/:id', getSubscriber, async (req, res) => {
  if (req.body.name != null) {
    res.subscriber.name = req.body.name
  }

  if (req.body.subscribedChannel != null) {
    res.subscriber.subscribedChannel = req.body.subscribedChannel
  }
  try {
    const updatedSubscriber = await res.subscriber.save()
    res.json(updatedSubscriber)
  } catch {
    res.status(400).json({ message: err.message })
  }

})


우리는 PATCH 메소드로 함수를 시작합니다. PATCH 메소드는 루트의 쉘을 처음 정의 할 때 논의했습니다. 이제 함수에 두 개의 if 문을 추가했습니다. 첫 번째 if 문은 사용자 요청 본문에서 오는 이름이 null이 아닌지 확인합니다. 이것은 null과 같으면 사용자가 경로 함수를 통해 이름에 대한 데이터를 전달하지 않았음을 의미하므로 중요한 검사입니다. 그들이 그렇다면 우리는 이 줄로 이동합니다 :


res.subscriber.name = req.body.name 


res.subscriber에서 가입자 이름을 설정하고 이름을 사용자가 요청에서 전달한 새 이름과 동일하게 설정하는 경우


동일한 논리가 다음과 같습니다.


res.subscriber.subscribedChannel = req.body.subscribedChannel 


사용자가 subscribedChannel을 업데이트했는지 확인하고 있는 경우 현재 subscribedChannel을 사용자의 요청에서 새로운 것과 동일한 순서로 변경합니다.


if 문을 확인한 후 함수에 새 변경 사항을 데이터베이스에 저장하도록 지시하려고 합니다. 이것은 try 문에서 쉽게 수행 할 수 있습니다. 여기서 res.subscriber 객체를 새로운 이름 및 / 또는 채널로 가져 와서 updateSubscriber라는 새 변수 내에서 save() 메서드를 추가합니다. 그런 다음이 새로운 updatedSubscriber 객체를 JSON 형식으로 사용자에게 전달하려고 합니다.

try {
const updatedSubscriber = await res.subscriber.save()
res.json(updatedSubscriber)
} 


이것이 subscribers.js 경로 파일에 필요한 모든 것이므로 여기서 잠시 멈추고 이 시점까지 모든 것을 갖추도록하겠습니다. 이 프로젝트의 github repo로 이동하여 아래의 최종 테스트로 넘어 가기 전에 코드가 정확하게 반영되는지 확인하십시오.


최종 시험 


마지막 두 경로를 완성했습니다. route.rest 파일로 이동하여 이 나쁜 소년을 테스트하고 제대로 작동하는지 확인하겠습니다.


삭제 요청은 GET 요청을 사용하는 대신 DELETE 요청을 자연스럽게 사용한다는 점을 제외하고는 Get One Subscriber 경로만큼 간단합니다. 데이터베이스에서 구독자 중 하나의 ID를 가져 와서 해당 테스트 경로를 만들어 보겠습니다.

###

DELETE http://localhost:3000/subscribers/5d3e0db7cb4be0bfc4c25ff9


이제‘요청 보내기’를 클릭하고 사용자가 성공적으로 삭제되었는지 확인하십시오.


l2do2uh9ivqlren4gp95.png 


오른쪽에 '삭제 된 구독자'라는 메시지가 표시되어 성공했음을 알 수 있습니다. 방금 삭제 한 것과 동일한 ID를 가져 와서 하나의 구독자 가져 오기 요청을 사용하여 요청하면 해당 구독자가 더 이상 데이터베이스에 없기 때문에 해당 구독자를 찾을 수 없음을 알려야 합니다.


duat7pwxz9cmd6yvdjsv.png 


마지막 요청은 데이터베이스에서 기존 가입자 정보를 업데이트 경로로 업데이트하는 것입니다. 방금 마지막 구독자를 삭제 했으므로 계속해서 새 구독자를 만들고 PATCH를 사용하여 업데이트 요청을 작성할 수 있습니다.

###

PATCH http://localhost:3000/subscribers/5d3e144ecb4be0bfc4c25ffa
Content-Type: application/json 

{
  "name": "Tommy"
}


위의 PATCH 요청을 실행하기 전에 새 구독자를 만들고 Lizzy라는 이름을 지정했습니다.


f86mz37ip99ylei0nauz.png 


위의 PATCH 요청을 실행하면 Lizzy의 이름이 Tommy로 변경되는 것을 볼 수 있습니다.


nj7cl7qtkto45nyikidq.png 


모든 것이 순조롭게 진행되면 Lizzy의 이름을 Tommy로 성공적으로 업데이트 할 수 있었습니다.


결론


이 튜토리얼이 여러분에게 도움이 되었기를 바랍니다. 우리는 많은 것들을 살펴 보았으므로 당신이 압도 감을 느끼면 완전히 이해할 수 있습니다. 그러나 우리는 방금 수많은 실제 응용 프로그램으로 변환되는 매우 멋진 백엔드 코드를 만들었습니다.