NodeJS에서 소켓을 사용하여 전문 채팅 API 솔루션을 만드는 방법 [초보자 수준]
https://www.freecodecamp.org/news/create-a-professional-node-express/
채팅 응용 프로그램이 무대 뒤에서 어떻게 작동하는지 궁금한 적이 있습니까? 오늘은 MongoDB를 사용하여 NodeJS / ExpressJS 위에 빌드 된 REST + 소켓 기반 애플리케이션을 작성하는 방법에 대해 설명하겠습니다.
나는 지금이 기사의 내용을 일주일 이상 연구 해 왔으며, 그것이 누군가를 도울 수 있기를 바랍니다.
전제 조건
우리가 다룰 주제
일반
API
Bonus - API
시작하기 전에 다음 비디오에서 몇 가지 기본 사항을 다루고 싶었습니다.
ExpressJS의 기본 이해
경로는 무엇입니까? 컨트롤러? CORS (Cross Origin Resource Sharing)를 어떻게 허용합니까? 최종 사용자가 API 요청에서 JSON 형식으로 데이터를 보내도록 하려면 어떻게 해야 합니까?
이 비디오에서 이 모든 것 (REST 규칙 포함)에 대해 이야기합니다.
또한, 이 비디오의 전체 소스 코드에 대한 GitHub 링크가 있습니다 [0 장]
"Chapter 0"소스 코드에 대한 README.md를 살펴보십시오. 비디오에서 언급 한 모든 관련 학습 링크와 우편 배달부에 대한 놀라운 30 분 자습서가 있습니다.
API 엔드 포인트에 API 유효성 검사 추가
아래 비디오에서 "make-validation"이라는 라이브러리를 사용하여 사용자 정의 유효성 검사를 작성하는 방법을 배웁니다.
다음은 이 비디오의 전체 소스 코드에 대한 GitHub 링크입니다 [0 장].
다음은 make-validation 라이브러리 링크 [GitHub] [npm] [example]입니다.
이 튜토리얼의 전체 소스 코드는 여기에서 찾을 수 있습니다. 의견이 있으시면 http://twitter.com/adeelibr에서 저에게 연락하십시오. 이 튜토리얼을 좋아한다면 github 저장소에 별표를 남겨주세요.
ExpressJS의 기본 사항과 사용자 응답의 유효성을 검사하는 방법에 대해 알아 보겠습니다.
시작하기
chat-app라는 폴더를 만듭니다.
mkdir chat-app;
cd chat-app;
다음을 입력하여 프로젝트 루트 폴더에서 새 npm 프로젝트를 초기화하십시오.
npm init -y
다음 패키지를 설치하십시오.
npm i cors @withvoid/make-validation express jsonwebtoken mongoose morgan socket.io uuid --save;
npm i nodemon --save-dev;
그리고 package.json scripts 섹션에서 다음 두 스크립트를 추가하십시오.
"scripts": {
"start": "nodemon server/index.js",
"start:server": "node server/index.js"
},
package.json은 이제 다음과 같이 보일 것입니다 :
{
"name": "chapter-1-chat",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"start": "nodemon server/index.js",
"start:server": "node server/index.js"
},
"dependencies": {
"@withvoid/make-validation": "1.0.5",
"cors": "2.8.5",
"express": "4.16.1",
"jsonwebtoken": "8.5.1",
"mongoose": "5.9.18",
"morgan": "1.9.1",
"socket.io": "2.3.0",
"uuid": "8.1.0"
},
"devDependencies": {
"nodemon": "2.0.4"
}
}
이제 프로젝트의 루트 폴더에 server라는 새 폴더를 만듭니다.
cd chat-app;
mkdir server;
cd server;
서버 폴더 안에 index.js라는 파일을 만들고 다음 내용을 추가하십시오.
import http from "http";
import express from "express";
import logger from "morgan";
import cors from "cors";
// routes
import indexRouter from "./routes/index.js";
import userRouter from "./routes/user.js";
import chatRoomRouter from "./routes/chatRoom.js";
import deleteRouter from "./routes/delete.js";
// middlewares
import { decode } from './middlewares/jwt.js'
const app = express();
/** Get port from environment and store in Express. */
const port = process.env.PORT || "3000";
app.set("port", port);
app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use("/", indexRouter);
app.use("/users", userRouter);
app.use("/room", decode, chatRoomRouter);
app.use("/delete", deleteRouter);
/** catch 404 and forward to error handler */
app.use('*', (req, res) => {
return res.status(404).json({
success: false,
message: 'API endpoint doesnt exist'
})
});
/** Create HTTP server. */
const server = http.createServer(app);
/** Listen on provided port, on all network interfaces. */
server.listen(port);
/** Event listener for HTTP server "listening" event. */
server.on("listening", () => {
console.log(`Listening on port:: http://localhost:${port}/`)
});
indexRouter userRouter chatRoomRouter & deleteRouter의 경로를 추가해 봅시다.
프로젝트의 루트 폴더에 경로라는 폴더를 만듭니다. 경로 폴더 안에 다음 파일을 추가하십시오.
routes / index.js의 내용을 먼저 추가해 봅시다 :
import express from 'express';
// controllers
import users from '../controllers/user.js';
// middlewares
import { encode } from '../middlewares/jwt.js';
const router = express.Router();
router
.post('/login/:userId', encode, (req, res, next) => { });
export default router;
다음으로 routes / user.js에 컨텐츠를 추가해 봅시다 :
import express from 'express';
// controllers
import user from '../controllers/user.js';
const router = express.Router();
router
.get('/', user.onGetAllUsers)
.post('/', user.onCreateUser)
.get('/:id', user.onGetUserById)
.delete('/:id', user.onDeleteUserById)
export default router;
이제 route / chatRoom.js에 콘텐츠를 추가해 보겠습니다 :
import express from 'express';
// controllers
import chatRoom from '../controllers/chatRoom.js';
const router = express.Router();
router
.get('/', chatRoom.getRecentConversation)
.get('/:roomId', chatRoom.getConversationByRoomId)
.post('/initiate', chatRoom.initiate)
.post('/:roomId/message', chatRoom.postMessage)
.put('/:roomId/mark-read', chatRoom.markConversationReadByRoomId)
export default router;
마지막으로 routes / delete.js에 내용을 추가해 봅시다 :
import express from 'express';
// controllers
import deleteController from '../controllers/delete.js';
const router = express.Router();
router
.delete('/room/:roomId', deleteController.deleteRoomById)
.delete('/message/:messageId', deleteController.deleteMessageById)
export default router;
이제 경로가 만들어 졌으므로 각 경로에 대한 컨트롤러를 추가하겠습니다.
controllers라는 새 폴더를 만듭니다. 해당 폴더 안에 다음 파일을 작성하십시오.
controllers / user.js로 시작해 봅시다 :
export default {
onGetAllUsers: async (req, res) => { },
onGetUserById: async (req, res) => { },
onCreateUser: async (req, res) => { },
onDeleteUserById: async (req, res) => { },
}
다음으로 controllers / chatRoom.js에 컨텐츠를 추가하겠습니다 :
export default {
initiate: async (req, res) => { },
postMessage: async (req, res) => { },
getRecentConversation: async (req, res) => { },
getConversationByRoomId: async (req, res) => { },
markConversationReadByRoomId: async (req, res) => { },
}
마지막으로 controllers / delete.js에 컨텐츠를 추가해 봅시다 :
export default {
deleteRoomById: async (req, res) => {},
deleteMessageById: async (req, res) => {},
}
지금까지 각 경로에 빈 컨트롤러를 추가 했으므로 아직 많은 작업을 수행하지 않습니다. 약간의 기능을 추가하겠습니다.
한가지 더 – 미들웨어라는 새 폴더를 추가하고 그 폴더 안에 jwt.js라는 파일을 만듭니다. 그런 다음 다음 내용을 추가하십시오.
import jwt from 'jsonwebtoken';
export const decode = (req, res, next) => {}
export const encode = async (req, res, next) => {}
이 파일의 기능에 대해 조금 이야기하겠습니다. 지금은 무시하겠습니다.
우리는 다음과 같이 끝냈습니다.
위의 비디오에서 다루지 않은 지금까지 멋진 것은 없습니다.
응용 프로그램에서 MongoDB를 설정합시다
코드베이스에 MongoDB를 추가하기 전에 다음 중 하나를 실행하여 시스템에 설치되어 있는지 확인하십시오.
MongoDB 설치에 문제가 있는 경우 https://twitter.com/adeelibr으로 알려주십시오. 사용자 정의 안내서를 작성하거나 설치 비디오 안내서를 작성하겠습니다. :)
Robo3T를 MongoDB GUI로 사용하고 있습니다.
이제 MongoDB 인스턴스가 실행되고 Robo3T가 설치되어 있어야 합니다. (여러분이 좋아하는 GUI 클라이언트를 사용할 수 있습니다. Robo3T가 너무 좋아서 사용하고 있습니다. 또한 오픈 소스입니다.)
다음은 YouTube에서 내가 Robo3T를 6 분 소개하는 작은 비디오입니다.
MongoDB 인스턴스가 시작되면 코드에 MongoDB 통합을 시작하십시오.
루트 폴더에 config라는 새 폴더를 만듭니다. 해당 폴더 안에 index.js라는 파일을 만들고 다음 내용을 추가하십시오.
const config = {
db: {
url: 'localhost:27017',
name: 'chatdb'
}
}
export default config
일반적으로 MongoDB 인스턴스가 실행될 기본 포트는 27017입니다.
여기서는 데이터베이스 URL (db에 있음)과 chatdb 인 데이터베이스 이름에 대한 정보를 설정합니다 (원하는 대로 호출 할 수 있음).
그런 다음 config / mongo.js라는 새 파일을 만들고 다음 내용을 추가하십시오.
import mongoose from 'mongoose'
import config from './index.js'
const CONNECTION_URL = `mongodb://${config.db.url}/${config.db.name}`
mongoose.connect(CONNECTION_URL, {
useNewUrlParser: true,
useUnifiedTopology: true
})
mongoose.connection.on('connected', () => {
console.log('Mongo has connected succesfully')
})
mongoose.connection.on('reconnected', () => {
console.log('Mongo has reconnected')
})
mongoose.connection.on('error', error => {
console.log('Mongo connection has an error', error)
mongoose.disconnect()
})
mongoose.connection.on('disconnected', () => {
console.log('Mongo connection is disconnected')
})
다음과 같이 server / index.js 파일에서 config / mongo.js를 가져옵니다.
.
.
// mongo connection
import "./config/mongo.js";
// routes
import indexRouter from "./routes/index.js";
언제든지 길을 잃은 경우 이 자습서의 전체 소스 코드가 여기에 있습니다.
우리가 여기서 하고 있는 일을 단계별로 논의 해 보자.
먼저 config.js 파일을 config / mongo.js로 가져옵니다. 다음으로 다음과 같이 CONNECTION_URL에 값을 전달합니다.
const CONNECTION_URL = `mongodb://${config.db.url}/${config.db.name}`
그런 다음 CONNECTION_URL을 사용하여 다음을 수행하여 Mongo 연결을 형성합니다.
mongoose.connect(CONNECTION_URL, {
useNewUrlParser: true,
useUnifiedTopology: true
})
이것은 몽구스에게 Node / Express 애플리케이션으로 데이터베이스와 연결하도록 지시합니다.
몽고에 제공하는 옵션은 다음과 같습니다.
다음으로 몽구스 이벤트 핸들러를 다음과 같이 추가합니다.
mongoose.connection.on('connected', () => {
console.log('Mongo has connected succesfully')
})
mongoose.connection.on('reconnected', () => {
console.log('Mongo has reconnected')
})
mongoose.connection.on('error', error => {
console.log('Mongo connection has an error', error)
mongoose.disconnect()
})
mongoose.connection.on('disconnected', () => {
console.log('Mongo connection is disconnected')
})
이 작업을 완료하면 server / index.js 파일로 이동하여 config / mongo.js를 가져 오십시오. 그게 다야. 이제 다음을 입력하여 서버를 시작할 때
npm start;
다음과 같이 보일 것입니다 :
서버를 시작할 때 기록
이 메시지가 표시되면 Mongo를 애플리케이션에 성공적으로 추가 한 것입니다.
사용자를 위한 첫 번째 API 섹션을 설정하겠습니다
사용자를 위한 API 설정에는 이 튜토리얼에 대한 인증 토큰이 없습니다. 주요 초점은 여기서 채팅 애플리케이션에 대해 알려주는 것입니다.
User Modal Scheme
사용자 컬렉션을 위한 첫 번째 모델 (데이터베이스 체계)을 만들어 봅시다.
models이라는 새 폴더를 만듭니다. 해당 폴더 안에 User.js라는 파일을 만들고 다음 내용을 추가하십시오.
import mongoose from "mongoose";
import { v4 as uuidv4 } from "uuid";
export const USER_TYPES = {
CONSUMER: "consumer",
SUPPORT: "support",
};
const userSchema = new mongoose.Schema(
{
_id: {
type: String,
default: () => uuidv4().replace(/\-/g, ""),
},
firstName: String,
lastName: String,
type: String,
},
{
timestamps: true,
collection: "users",
}
);
export default mongoose.model("User", userSchema);
이것을 조각으로 나누자.
export const USER_TYPES = {
CONSUMER: "consumer",
SUPPORT: "support",
};
기본적으로 소비자와 지원의 두 가지 유형의 사용자가 있습니다. 프로그래밍 방식으로 API 및 DB 유효성 검사를 보장하기 위해 이 방법으로 작성했습니다. 나중에 설명하겠습니다.
다음으로 단일 문서 (객체 / 항목 / 항목 / 행)가 사용자 컬렉션 내부에서 어떻게 보이는지에 대한 스키마를 만듭니다 (컬렉션은 MySQL 테이블과 동일 함). 우리는 이것을 다음과 같이 정의합니다 :
const userSchema = new mongoose.Schema(
{
_id: {
type: String,
default: () => uuidv4().replace(/\-/g, ""),
},
firstName: String,
lastName: String,
type: String,
},
{
timestamps: true,
collection: "users",
}
);
여기서 우리는 mongoose에게 사용자 컬렉션의 단일 문서에 대해 구조가 다음과 같이 되기를 원한다고 말합니다.
{
id: String // will get random string by default thanks to uuidv4
firstName: String,
lastName: String,
type: String // this can be of 2 types consumer/support
}
스키마의 두 번째 부분에는 다음과 같은 것이 있습니다.
{
timestamps: true,
collection: "users",
}
타임 스탬프를 true로 설정하면 스키마에 createdAt 및 updatedAt 날짜 값이라는 두 가지가 추가됩니다. 새 항목을 만들 때마다 createdAt가 자동으로 업데이트 되고 mongoose를 사용하여 데이터베이스에서 항목을 업데이트하면 updatedAt가 업데이트 됩니다. 이 두 가지는 몽구스에 의해 자동으로 수행됩니다.
두 번째 부분은 수집입니다. 이것은 내 컬렉션 이름이 데이터베이스 내에 어떤 것을 보여줄 지를 보여줍니다. 사용자 이름을 지정하고 있습니다.
마지막으로 다음과 같이 객체를 내 보냅니다.
export default mongoose.model("User", userSchema);
따라서 mongoose.model은 2 개의 매개 변수를 사용합니다.
참고 :이 경우 사용자 인 모델 이름을 기반으로 스키마 섹션에 컬렉션 키를 추가하지 않습니다. 이 사용자 이름을 가져 와서 s를 추가하고 이름으로 모음을 작성합니다.
좋습니다. 이제 첫 번째 모델이 있습니다
어디에서나 붙어 있다면 소스 코드를 살펴보십시오.
등록된 댓글이 없습니다.