Node.js로 Restful CRUD API 빌드
70978 단어 javascriptwebdevtutorialnode
목차
CRUD API는 무엇을 의미합니까?
CRUD 패러다임은
CREATE
, READ
, UPDATE
및 DELETE
네 가지 기본 데이터베이스 작업을 나타냅니다.따라서
CRUD API
라는 용어는 데이터베이스에서 create
, read
, update
및 delete
항목을 수행할 수 있는 API를 의미합니다. 이 예에서 엔터티는 직원입니다.시작하자
API 엔드포인트는 다음과 같습니다.
행동 양식
URL
설명
가져 오기
API/직원
모든 직원 가져오기
가져 오기
API/직원/ID
특정 직원 가져오기
게시하다
API/직원
새 직원 만들기
놓다
API/직원/ID
기존 직원 업데이트
삭제
API/직원/ID
기존 직원 삭제
저장소를 만들고 종속성을 설치합니다.
진입점은 server.js 파일입니다.
mkdir express-api
cd express-api
npm init
npm install express helmet morgan body-parser monk joi dotenv --save
npm install nodemon --save-dev
패키지 정보
express: 최소한의 유연한 Node.js 웹 애플리케이션 프레임워크입니다.
헬멧: 익스프레스 애플리케이션에서 HTTP 헤더를 보호하는 데 도움이 됩니다.
morgan: Node.js용 HTTP 요청 로거 미들웨어입니다. js
body-parser: 들어오는 요청 본문의 구문 분석을 담당합니다.
몽크: MongoDB 사용에 대한 상당한 사용성 향상을 제공하는 작은 계층입니다.
joi: 개체 스키마 설명 언어 및 개체 유효성 검사기입니다.
dotenv: .env 파일에서 환경 변수를 로드합니다.
nodemon: 디렉토리의 파일 변경이 감지되면 노드 응용 프로그램을 자동으로 다시 시작합니다.
Express 웹 서버 설정
./src/서버.js
const express = require('express');
const morgan = require('morgan');
const helmet = require('helmet');
const bodyParser = require('body-parser');
require('dotenv').config();
const app = express();
const monk = require('monk');
app.use(helmet());
app.use(morgan('dev'));
app.use(bodyParser.json());
const port = process.env.PORT || 8080;
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
.env 파일 생성 및 구성
./.env
여기에는 우리가 사용하는 모든 환경 변수가 포함됩니다.
TEST_DB_URL
변수는 데이터베이스에 테스트 데이터가 삽입되는 것을 방지하기 위한 테스트 케이스용입니다. 또한 원하는 포트 번호를 지정할 수 있습니다.DB_URL = localhost/my-employees
TEST_DB_URL = localhost/test-my-employees
PORT = 5000
./src/db/schema.js
데이터 스키마를 생성하고 속성
name
및 job
가 따라야 하는 유효성 검사 규칙을 정의합니다.const Joi = require('joi');
const schema = Joi.object({
name: Joi.string()
.min(3)
.max(30)
.required(),
job: Joi.string()
.min(3)
.max(30)
.required(),
})
module.exports = schema;
./src/db/connection.js
데이터베이스에 연결
const monk = require('monk');
let dbUrl = process.env.DB_URL;
if (process.env.NODE_ENV === 'test') {
dbUrl = process.env.TEST_DB_URL;
}
const db = monk(dbUrl);
module.exports = db;
./src/middlewares/index.js
오류를 처리하고 적절한 응답을 제공하는 오류 미들웨어를 만듭니다.
function notFound(req, res, next) {
res.status(404);
const error = new Error('Not Found', req.originalUrl);
next(error);
}
function errorHandler(err, req, res, next){
res.status(res.statusCode || 500);
res.json({
message: err.message,
stack: err.stack
});
}
module.exports = {
notFound,
errorHandler
}
./src/db/connection.js
, ./src/db/schema.js
및 ./src/middlewares/index.js
파일을 ./src/server.js
에서 가져옵니다.const express = require('express');
const morgan = require('morgan');
const helmet = require('helmet');
const bodyParser = require('body-parser');
const { notFound, errorHandler } = require('./middlewares');
require('dotenv').config();
const schema = require('./db/schema');
const db = require('./db/connection');
const employees = db.get('employees');
const app = express();
app.use(helmet());
app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(notFound);
app.use(errorHandler);
const port = process.env.PORT || 8080;
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
이제 API 엔드포인트를 코딩합니다.
const express = require('express');
const morgan = require('morgan');
const helmet = require('helmet');
const bodyParser = require('body-parser');
const { notFound, errorHandler } = require('./middlewares');
require('dotenv').config();
const schema = require('./db/schema');
const db = require('./db/connection');
const employees = db.get('employees');
const app = express();
app.use(helmet());
app.use(morgan('dev'));
app.use(bodyParser.json());
/* Get all employees */
app.get('/', async (req, res, next) => {
try {
const allEmployees = await employees.find({});
res.json(allEmployees);
} catch(error) {
next(error);
}
});
/* Get a specific employee */
app.get('/:id', async (req, res, next) => {
try {
const { id } = req.params;
const employee = await employees.findOne({
_id: id
});
if(!employee) {
const error = new Error('Employee does not exist');
return next(error);
}
res.json(employee);
} catch(error) {
next(error);
}
});
/* Create a new employee */
app.post('/', async (req, res, next) => {
try {
const { name, job } = req.body;
const result = await schema.validateAsync({ name, job });
const employee = await employees.findOne({
name,
})
// Employee already exists
if (employee) {
res.status(409); // conflict error
const error = new Error('Employee already exists');
return next(error);
}
const newuser = await employees.insert({
name,
job,
});
console.log('New employee has been created');
res.status(201).json(newuser);
} catch(error) {
next(error);
}
});
/* Update a specific employee */
app.put('/:id', async (req, res, next) => {
try {
const { id } = req.params;
const { name, job } = req.body;
const result = await schema.validateAsync({ name, job });
const employee = await employees.findOne({
_id: id
});
// Employee does not exist
if(!employee) {
return next();
}
const updatedEmployee = await employees.update({
_id: id,
}, {
$set: result},
{ upsert: true }
);
res.json(updatedEmployee);
} catch(error) {
next(error);
}
});
/* Delete a specific employee */
app.delete('/:id', async (req, res, next) => {
try {
const { id } = req.params;
const employee = await employees.findOne({
_id: id
});
// Employee does not exist
if(!employee) {
return next();
}
await employees.remove({
_id: id
});
res.json({
message: 'Success'
});
} catch(error) {
next(error);
}
});
app.use(notFound);
app.use(errorHandler);
const port = process.env.PORT || 8080;
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
package.json
파일로 이동하여 스크립트 섹션을 다음으로 바꿉니다."scripts": {
"start": "node src/server.js",
"dev": "nodemon src/server.js"
},
명령
npm start
은 Node.js 애플리케이션을 시작하고 명령npm run dev
은 Node.js 애플리케이션을 시작하지만 변경 사항이 nodemon에 의해 자동으로 모니터링된다는 유일한 차이점이 있습니다.우리는
./src/server.js
파일을 "분할"하고 ./src/app.js
파일을 생성합니다../src/app.js
const express = require('express');
const morgan = require('morgan');
const helmet = require('helmet');
const bodyParser = require('body-parser');
const { notFound, errorHandler } = require('./middlewares');
require('dotenv').config();
const schema = require('./db/schema');
const db = require('./db/connection');
const employees = db.get('employees');
const app = express();
app.use(helmet());
app.use(morgan('dev'));
app.use(bodyParser.json());
/* Get all employees */
app.get('/', async (req, res, next) => {
try {
const allEmployees = await employees.find({});
res.json(allEmployees);
} catch(error) {
next(error);
}
});
/* Get a specific employee */
app.get('/:id', async (req, res, next) => {
try {
const { id } = req.params;
const employee = await employees.findOne({
_id: id
});
if(!employee) {
const error = new Error('Employee does not exist');
return next(error);
}
res.json(employee);
} catch(error) {
next(error);
}
});
/* Create a new employee */
app.post('/', async (req, res, next) => {
try {
const { name, job } = req.body;
const result = await schema.validateAsync({ name, job });
const employee = await employees.findOne({
name,
})
// Employee already exists
if (employee) {
res.status(409); // conflict error
const error = new Error('Employee already exists');
return next(error);
}
const newuser = await employees.insert({
name,
job,
});
console.log('New employee has been created');
res.status(201).json(newuser);
} catch(error) {
next(error);
}
});
/* Update a specific employee */
app.put('/:id', async (req, res, next) => {
try {
const { id } = req.params;
const { name, job } = req.body;
const result = await schema.validateAsync({ name, job });
const employee = await employees.findOne({
_id: id
});
// Employee does not exist
if(!employee) {
return next();
}
const updatedEmployee = await employees.update({
_id: id,
}, {
$set: result},
{ upsert: true }
);
res.json(updatedEmployee);
} catch(error) {
next(error);
}
});
/* Delete a specific employee */
app.delete('/:id', async (req, res, next) => {
try {
const { id } = req.params;
const employee = await employees.findOne({
_id: id
});
// Employee does not exist
if(!employee) {
return next();
}
await employees.remove({
_id: id
});
res.json({
message: 'Success'
});
} catch(error) {
next(error);
}
});
app.use(notFound);
app.use(errorHandler);
module.exports = app;
./src/서버.js
const app = require('./app');
const port = process.env.PORT || 8080;
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
마지막 단계는 코드를 리팩토링하고
./src/routes/employees
를 생성하는 것입니다../src/routes/employees.js
const express = require('express');
const schema = require('../db/schema');
const db = require('../db/connection');
const employees = db.get('employees');
const router = express.Router();
/* Get all employees */
router.get('/', async (req, res, next) => {
try {
const allEmployees = await employees.find({});
res.json(allEmployees);
} catch (error) {
next(error);
}
});
/* Get a specific employee */
router.get('/:id', async (req, res, next) => {
try {
const { id } = req.params;
const employee = await employees.findOne({
_id: id,
});
if (!employee) {
const error = new Error('Employee does not exist');
return next(error);
}
res.json(employee);
} catch (error) {
next(error);
}
});
/* Create a new employee */
router.post('/', async (req, res, next) => {
try {
const { name, job } = req.body;
const result = await schema.validateAsync({ name, job });
const employee = await employees.findOne({
name,
});
// Employee already exists
if (employee) {
const error = new Error('Employee already exists');
res.status(409); // conflict error
return next(error);
}
const newuser = await employees.insert({
name,
job,
});
res.status(201).json(newuser);
} catch (error) {
next(error);
}
});
/* Update a specific employee */
router.put('/:id', async (req, res, next) => {
try {
const { id } = req.params;
const { name, job } = req.body;
const result = await schema.validateAsync({ name, job });
const employee = await employees.findOne({
_id: id,
});
// Employee does not exist
if (!employee) {
return next();
}
const updatedEmployee = await employees.update({
_id: id,
}, { $set: result },
{ upsert: true });
res.json(updatedEmployee);
} catch (error) {
next(error);
}
});
/* Delete a specific employee */
router.delete('/:id', async (req, res, next) => {
try {
const { id } = req.params;
const employee = await employees.findOne({
_id: id,
});
// Employee does not exist
if (!employee) {
return next();
}
await employees.remove({
_id: id,
});
res.json({
message: 'Employee has been deleted',
});
} catch (error) {
next(error);
}
});
module.exports = router;
./src/app.js 파일은 다음과 같습니다.
const express = require('express');
const morgan = require('morgan');
const helmet = require('helmet');
const bodyParser = require('body-parser');
const { notFound, errorHandler } = require('./middlewares');
const app = express();
require('dotenv').config();
app.use(helmet());
app.use(morgan('dev'));
app.use(bodyParser.json());
const employees = require('./routes/employees');
app.use('/api/employees', employees);
app.use(notFound);
app.use(errorHandler);
module.exports = app;
내 github 저장소express-api에서 전체 프로젝트를 확인할 수 있습니다.
Reference
이 문제에 관하여(Node.js로 Restful CRUD API 빌드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/zagaris/build-a-restful-crud-api-with-node-js-2334텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)