안녕하세요 오늘은 Nodejs CRUD API 를 만들어 볼 것 입니다.
일단 스키마먼저 보여드리겠습니다. 제일 기본적인 todolist의 CRUD를 구현할 것 입니다.
export class TodoModel {
date : Date ;
list: [];
constructor (id: string = "" ) {
this .date = new Date ();
this .list = [];
}
}
전체코드입니다.
import express, { NextFunction } from "express" ;
import * as _ from "lodash" ;
import uniqid from 'uniqid' ;
import Common, {
CommunicationCode,
CommunicationResult,
LogType
} from "../../common/common" ;
import { TodoModel } from "../../database/models/todo"
import mongoDB from "../../database/mongodb" ;
import moment from 'moment' ;
export default class TodoAPI {
private readonly db: mongoDB;
private readonly TODO_DB_ID = "todo" ;
constructor ( ) {
this .db = mongoDB.root();
}
public throw = (
err: Error ,
req: express.Request,
res: express.Response,
next: NextFunction
) => {
Common.log(LogType.sev_error, `exception Error : ${err} ` );
};
public todoAdd = async (req: any, res : express.Response) => {
let result: CommunicationResult = new CommunicationResult();
try {
let query: any = req.body.query;
if (query.date == undefined ) {
result.set(CommunicationCode.FAIL_EMPTY_PARAMETER);
result.msg = "date 파라미터를 검출하지 못했습니다." ;
throw result;
}
const date: Date = new Date (query.date);
if (isNaN (date.getTime())) {
result.set(CommunicationCode.FAIL_INVALID_DATA);
result.msg = "date 파라미터가 유효하지 않습니다." ;
throw result;
}
let list: any = {};
list["uid" ] = uniqid();
console .log("uid : " , list["uid" ]);
list["checked" ] = (query.checked == undefined ) ? false : query.checked;
list["label" ] = (query.label == undefined ) ? "" : query.label;
list["start" ] = (query.start == undefined ) ? new Date () :new Date ( query.start ) ;
list["end" ] = (query.end == undefined ) ? new Date () :new Date ( query.end );
let insertQuery: any = {};
insertQuery["id" ] = uniqid();
insertQuery["date" ] = date;
insertQuery["list" ] = [];
insertQuery["list" ].push(list);
await this .db.insertOne(this .TODO_DB_ID, insertQuery);
res.send({ _COM : result });
} catch (e) {
if (e instanceof CommunicationResult) {
result = e;
Common.log(LogType.error, `[/api/todo/add], try ~ catch : ${e.msg} ` );
} else {
result.set(CommunicationCode.FAIL_UNKNOWN);
result.msg = e.message;
Common.log(LogType.sev_error, `[/api/todo/add], try ~ catch : ${e} ` );
}
res.send({ _COM : result });
}
};
public todolist = async (req: express.Request, res : express.Response) => {
let result: CommunicationResult = new CommunicationResult();
try {
const param_date: any = req.query.date;
let query: any = {};
if (param_date != null ) {
const start: Date = new Date (param_date + " 00:00:00" );
const end: Date = new Date (param_date + " 23:59:59" );
query["date" ] = {
$gte : start,
$lte : end
};
}
else {
result.set(CommunicationCode.FAIL_EMPTY_PARAMETER);
result.msg = "파라미터를 검출하지 못했습니다." ;
throw result;
}
console .log("query : " , query);
const todo: TodoModel = await this .db.findOne(this .TODO_DB_ID, query);
if (todo == undefined ) {
result.set(CommunicationCode.DB_FAIL_NO_DATA);
result.msg = "데이터가 없음." ;
throw result;
}
let searchQuery: any = {};
searchQuery["date" ] = {
$gte : ( req.query.start != undefined ) ? moment(req.query.start).toDate() : moment("1970-01-01" ).toDate(),
$lte : (req.query.end != undefined ) ? moment(req.query.end).toDate() : moment("2999-12-31" ).toDate()
};
res.send({ _COM : result, data : {
date : todo.date,
todo : todo,
}});
} catch (e) {
if (e instanceof CommunicationResult) {
result = e;
Common.log(LogType.error, `[/api/todo/todolist], try ~ catch : ${e.msg} ` );
} else {
result.set(CommunicationCode.FAIL_UNKNOWN);
result.msg = e.message;
Common.log(LogType.sev_error, `[/api/todo/todolist], try ~ catch : ${e} ` );
}
res.send({ _COM : result });
}
}
public todolistAll = async (req: express.Request, res : express.Response) => {
let result: CommunicationResult = new CommunicationResult();
try {
console .log("Date:" ,new Date ());
let query: any = {};
const todo: TodoModel = await this .db.find(this .TODO_DB_ID, query);
res.send({ _COM : result, data : todo});
} catch (e) {
if (e instanceof CommunicationResult) {
result = e;
Common.log(LogType.error, `[/api/todo/todolist], try ~ catch : ${e.msg} ` );
} else {
result.set(CommunicationCode.FAIL_UNKNOWN);
result.msg = e.message;
Common.log(LogType.sev_error, `[/api/todo/todolist], try ~ catch : ${e} ` );
}
res.send({ _COM : result });
}
}
public todoDel = async (req: any, res : express.Response) => {
let result: CommunicationResult = new CommunicationResult();
try {
let query: any = {};
await this .db.delete(this .TODO_DB_ID, query);
res.send({ _COM : result });
} catch (e) {
if (e instanceof CommunicationResult) {
result = e;
Common.log(LogType.error, `[/api/todo/delete], try ~ catch : ${e.msg} ` );
} else {
result.set(CommunicationCode.FAIL_UNKNOWN);
result.msg = e.message;
Common.log(LogType.sev_error, `[/api/todo/delete], try ~ catch : ${e} ` );
}
res.send({ _COM : result });
}
};
public todoUpdate = async (req: any, res : express.Response) => {
let result: CommunicationResult = new CommunicationResult();
try {
const id = req.body.query.id;
if (id == undefined ) {
result.set(CommunicationCode.FAIL_EMPTY_PARAMETER);
result.msg = "파라미터를 검출하지 못했습니다." ;
throw result;
}
const list = req.body.query.list;
if (list == undefined ) {
result.set(CommunicationCode.FAIL_EMPTY_PARAMETER);
result.msg = "파라미터를 검출하지 못했습니다." ;
throw result;
}
const uid = list.uid;
if (uid == undefined ) {
result.set(CommunicationCode.FAIL_EMPTY_PARAMETER);
result.msg = "파라미터를 검출하지 못했습니다." ;
throw result;
}
const start: Date = new Date (list.start);
if (isNaN (start.getTime())) {
result.set(CommunicationCode.FAIL_INVALID_DATA);
result.msg = "start 파라미터가 유효하지 않습니다." ;
throw result;
}
const end: Date = new Date (list.end);
if (isNaN (end.getTime())) {
result.set(CommunicationCode.FAIL_INVALID_DATA);
result.msg = "end 파라미터가 유효하지 않습니다." ;
throw result;
}
let query: any = {
id : id,
list : {
$elemMatch : {
uid : uid
}
}
};
const data = await this .db.findOne(this .TODO_DB_ID, query);
if (data == undefined ) {
result.set(CommunicationCode.DB_FAIL_NO_DATA);
result.msg = "검출된 데이터가 없습니다." ;
throw result;
}
console .log("data.list : " , data.list);
let update: any = {
$set : {
"list.$.label" : list.label == undefined ? data.list[0 ].label : list.label,
"list.$.checked" : list.checked == undefined ? data.list[0 ].checked : list.checked,
"list.$.start" : list.start == undefined ? data.list[0 ].start : new Date (list.start),
"list.$.end" : list.end == undefined ? data.list[0 ].end : new Date (list.end),
}
};
await this .db.update(this .TODO_DB_ID, query, update);
res.send({ _COM : result });
} catch (e) {
if (e instanceof CommunicationResult) {
result = e;
Common.log(LogType.error, `[/api/todo/update], try ~ catch : ${e.msg} ` );
} else {
result.set(CommunicationCode.FAIL_UNKNOWN);
result.msg = e.message;
Common.log(LogType.sev_error, `[/api/todo/update], try ~ catch : ${e} ` );
}
res.send({ _COM : result });
}
};
}
이제 하나하나 분석해보겠습니다.
제일 첫번째로 Add 먼저 보겠습니다.
public todoAdd = async (req: any, res : express.Response) => {
let result: CommunicationResult = new CommunicationResult();
try {
let query: any = req.body.query;
if (query.date == undefined ) {
result.set(CommunicationCode.FAIL_EMPTY_PARAMETER);
result.msg = "date 파라미터를 검출하지 못했습니다." ;
throw result;
}
const date: Date = new Date (query.date);
if (isNaN (date.getTime())) {
result.set(CommunicationCode.FAIL_INVALID_DATA);
result.msg = "date 파라미터가 유효하지 않습니다." ;
throw result;
}
let list: any = {};
list["uid" ] = uniqid();
console .log("uid : " , list["uid" ]);
list["checked" ] = (query.checked == undefined ) ? false : query.checked;
list["label" ] = (query.label == undefined ) ? "" : query.label;
list["start" ] = (query.start == undefined ) ? new Date () :new Date ( query.start ) ;
list["end" ] = (query.end == undefined ) ? new Date () :new Date ( query.end );
let insertQuery: any = {};
insertQuery["id" ] = uniqid();
insertQuery["date" ] = date;
insertQuery["list" ] = [];
insertQuery["list" ].push(list);
await this .db.insertOne(this .TODO_DB_ID, insertQuery);
res.send({ _COM : result });
} catch (e) {
if (e instanceof CommunicationResult) {
result = e;
Common.log(LogType.error, `[/api/todo/add], try ~ catch : ${e.msg} ` );
} else {
result.set(CommunicationCode.FAIL_UNKNOWN);
result.msg = e.message;
Common.log(LogType.sev_error, `[/api/todo/add], try ~ catch : ${e} ` );
}
res.send({ _COM : result });
}
};
insertOne이라는 함수를 보여드리겠습니다.
mongoose 라이브러리를 사용하여 실질적으로 mongoDB에 값을 저장하는 코드입니다.
public insertOne = (sID: string, query : any, options?: any, index?: any): Promise <any> => {
return new Promise ((resolve: any, reject: any ) => {
try {
const collection: mongoose.Collection = this .mongooseDB.collection(sID);
collection.insertOne(query, options, (error: MongoError, result: InsertOneWriteOpResult ) => {
if (error) { reject(error); }
else {
resolve(result);
}
});
} catch (e) { reject(e); }
});
}
Add의 결과값입니다.
그럼 이제 SelectOne 을 보겠습니다.
Data 하나만 검색하는 함수
public todolist = async (req: express.Request, res : express.Response) => {
let result: CommunicationResult = new CommunicationResult();
try {
const param_date: any = req.query.date;
let query: any = {};
if (param_date != null ) {
const start: Date = new Date (param_date + " 00:00:00" );
const end: Date = new Date (param_date + " 23:59:59" );
query["date" ] = {
$gte : start,
$lte : end
};
}
else {
result.set(CommunicationCode.FAIL_EMPTY_PARAMETER);
result.msg = "파라미터를 검출하지 못했습니다." ;
throw result;
}
console .log("query : " , query);
const todo: TodoModel = await this .db.findOne(this .TODO_DB_ID, query);
if (todo == undefined ) {
result.set(CommunicationCode.DB_FAIL_NO_DATA);
result.msg = "데이터가 없음." ;
throw result;
}
let searchQuery: any = {};
searchQuery["date" ] = {
$gte : ( req.query.start != undefined ) ? moment(req.query.start).toDate() : moment("1970-01-01" ).toDate(),
$lte : (req.query.end != undefined ) ? moment(req.query.end).toDate() : moment("2999-12-31" ).toDate()
};
res.send({ _COM : result, data : {
date : todo.date,
todo : todo,
}});
} catch (e) {
if (e instanceof CommunicationResult) {
result = e;
Common.log(LogType.error, `[/api/todo/todolist], try ~ catch : ${e.msg} ` );
} else {
result.set(CommunicationCode.FAIL_UNKNOWN);
result.msg = e.message;
Common.log(LogType.sev_error, `[/api/todo/todolist], try ~ catch : ${e} ` );
}
res.send({ _COM : result });
}
}
findOne 이라는 함수로 한개의 데이터 값을 찾습니다.
public findOne = (sID: string, query : any, options : FindOneOptions = {}): Promise <any> => {
return new Promise ((resolve: any, reject: any ) => {
try {
let collection: mongoose.Collection = this .mongooseDB.collection(sID);
collection.findOne(query, options).then(value => { resolve(value); }).catch(e => { reject(e); });
} catch (e) {
reject(e);
}
});
}
Data 전체를 검색하는 함수
public todolistAll = async (req: express.Request, res : express.Response) => {
let result: CommunicationResult = new CommunicationResult();
try {
console .log("Date:" ,new Date ());
let query: any = {};
const todo: TodoModel = await this .db.find(this .TODO_DB_ID, query);
res.send({ _COM : result, data : todo});
} catch (e) {
if (e instanceof CommunicationResult) {
result = e;
Common.log(LogType.error, `[/api/todo/todolist], try ~ catch : ${e.msg} ` );
} else {
result.set(CommunicationCode.FAIL_UNKNOWN);
result.msg = e.message;
Common.log(LogType.sev_error, `[/api/todo/todolist], try ~ catch : ${e} ` );
}
res.send({ _COM : result });
}
}
find함수
public find = (sID: string, query : any, options : any = {}, _sort : any = {}, _skip : number = -1 , _limit : number = -1 ): Promise <any> => {
return new Promise (async (resolve: any, reject : any) => {
try {
let collection: mongoose.Collection = this .mongooseDB.collection(sID, { _prettyShell : true });
let cursor: Cursor<any> = collection.find(query, options);
if (cursor == undefined ) {
resolve([]);
}
else {
if (_skip != -1 && _limit != -1 ) {
cursor = collection.find(query, options).sort(_sort).skip(_skip).limit(_limit);
}
else if (_skip != -1 ) {
cursor = collection.find(query, options).sort(_sort).skip(_skip);
}
else if (_limit != -1 ) {
cursor = collection.find(query, options).sort(_sort).limit(_limit);
}
else {
cursor = collection.find(query, options).sort(_sort);
}
}
let docs: Array <any> = await cursor.toArray();
resolve(docs);
} catch (e) {
reject(e);
}
});
}
Delete 함수
public todoDel = async (req: any, res : express.Response) => {
let result: CommunicationResult = new CommunicationResult();
try {
let query: any = {};
await this .db.delete(this .TODO_DB_ID, query);
res.send({ _COM : result });
} catch (e) {
if (e instanceof CommunicationResult) {
result = e;
Common.log(LogType.error, `[/api/todo/delete], try ~ catch : ${e.msg} ` );
} else {
result.set(CommunicationCode.FAIL_UNKNOWN);
result.msg = e.message;
Common.log(LogType.sev_error, `[/api/todo/delete], try ~ catch : ${e} ` );
}
res.send({ _COM : result });
}
};
delete 함수
public delete = (sID: string, query : any, options : any = {}, many : boolean = false ): Promise <any> => {
return new Promise <any>((resolve: any, reject: any ) => {
let collection: mongoose.Collection = this .mongooseDB.collection(sID);
if (query == undefined ) {
reject("Query Empty" );
} else if (!many) {
collection.deleteOne(query, options, (error: MongoError, result: DeleteWriteOpResultObject ) => {
if (error) { reject(error); }
else { resolve(result); }
});
} else {
collection.deleteMany(query, options, (error: MongoError, result: DeleteWriteOpResultObject ) => {
if (error) { reject(error); }
else { resolve(result); }
});
}
});
}
Update 함수
public todoUpdate = async (req: any, res : express.Response) => {
let result: CommunicationResult = new CommunicationResult();
try {
const id = req.body.query.id;
if (id == undefined ) {
result.set(CommunicationCode.FAIL_EMPTY_PARAMETER);
result.msg = "파라미터를 검출하지 못했습니다." ;
throw result;
}
const list = req.body.query.list;
if (list == undefined ) {
result.set(CommunicationCode.FAIL_EMPTY_PARAMETER);
result.msg = "파라미터를 검출하지 못했습니다." ;
throw result;
}
const uid = list.uid;
if (uid == undefined ) {
result.set(CommunicationCode.FAIL_EMPTY_PARAMETER);
result.msg = "파라미터를 검출하지 못했습니다." ;
throw result;
}
const start: Date = new Date (list.start);
if (isNaN (start.getTime())) {
result.set(CommunicationCode.FAIL_INVALID_DATA);
result.msg = "start 파라미터가 유효하지 않습니다." ;
throw result;
}
const end: Date = new Date (list.end);
if (isNaN (end.getTime())) {
result.set(CommunicationCode.FAIL_INVALID_DATA);
result.msg = "end 파라미터가 유효하지 않습니다." ;
throw result;
}
let query: any = {
id : id,
list : {
$elemMatch : {
uid : uid
}
}
};
const data = await this .db.findOne(this .TODO_DB_ID, query);
if (data == undefined ) {
result.set(CommunicationCode.DB_FAIL_NO_DATA);
result.msg = "검출된 데이터가 없습니다." ;
throw result;
}
console .log("data.list : " , data.list);
let update: any = {
$set : {
"list.$.label" : list.label == undefined ? data.list[0 ].label : list.label,
"list.$.checked" : list.checked == undefined ? data.list[0 ].checked : list.checked,
"list.$.start" : list.start == undefined ? data.list[0 ].start : new Date (list.start),
"list.$.end" : list.end == undefined ? data.list[0 ].end : new Date (list.end),
}
};
await this .db.update(this .TODO_DB_ID, query, update);
res.send({ _COM : result });
} catch (e) {
if (e instanceof CommunicationResult) {
result = e;
Common.log(LogType.error, `[/api/todo/update], try ~ catch : ${e.msg} ` );
} else {
result.set(CommunicationCode.FAIL_UNKNOWN);
result.msg = e.message;
Common.log(LogType.sev_error, `[/api/todo/update], try ~ catch : ${e} ` );
}
res.send({ _COM : result });
}
};
update함수
public update = (sID: string, query : any, update : any, options : any = {}, isMany : boolean = false ): Promise <any> => {
return new Promise <any>((resolve: any, reject: any ) => {
try {
if (!isMany) {
let collection: mongoose.Collection = this .mongooseDB.collection(sID);
collection.updateOne(query, update, options, (error: any, res: any ) => {
if (error) { reject(error); }
else { resolve(res); }
});
} else {
let collection: mongoose.Collection = this .mongooseDB.collection(sID);
collection.updateMany(query, update, options, (error: any, res: any ) => {
if (error) { reject(error); }
else { resolve(res); }
});
}
} catch (e) {
resolve(e);
}
});
}
index.ts
import express from "express" ;
import { Router } from "express-serve-static-core" ;
import TodoAPI from "./todo" ;
const todo = new TodoAPI();
const router: Router = express.Router();
router.use(todo.throw);
router.post("/todoAdd" ,todo.todoAdd);
router.get("/todolist" , todo.todolist);
router.get("/todolistAll" , todo.todolistAll);
router.delete("/todoDel" ,todo.todoDel);
router.post("/todoUpdate" ,todo.todoUpdate);
export = router;
감사합니다:)