https://jeong-pro.tistory.com/68

 

웹 개발하면서 처리해야할 보안, 최소한의 방어, 정보보안

웹 애플리케이션 보안 처리, 해결책 웹 애플리케이션을 개발하면서 대부분 요구사항에 맞는 주요 기능을 개발하는데 열을 올린다. 주요 기능을 개발하는 것도 중요하지만 그것 못지 않게 아니면 더 중요한 것이 보..

jeong-pro.tistory.com

웹을 하면서 좋은 글을 찾아서 공유해본다.

'Node.js' 카테고리의 다른 글

Express ?  (0) 2019.09.03
Nodejs CRUD API 만들어보기 ( 초급 )  (0) 2019.08.29
REST – PUT vs POST  (0) 2019.08.28
간단한 Todolist Select API를 만들어보았다!  (0) 2019.08.26
Node.js로 hello world 출력해보기  (0) 2019.08.07

간단한 http 통신 코드입니다. 

이부분에서 require? cors? express? 너무 헷갈리시고 모르시는 분들을 위해 이 글을 써봤습니다.

var express = require('express')
const cors = require("cors");
const app = express();

var whiteList = [
    "http://localhost:3000"
]

app.use(cors(whiteList));

app.get('/', function(req, res) { 
    res.send('서버에서 값이 전달되었습니다.');
});

app.listen(5000, ()=> { 
    console.log(' 서버가 열렸습니다');
})

 

Express.js

Node.js에서는 MVC(Model-View-Controller) 패턴의 적용을 쉽게 해주는 여러 3rd-party 모듈들이 존재합니다. 그 중에 가장 인기있는 모듈이 바로 Express.js 입니다

 

어플리케이션

Express는 웹 및 모바일 애플리케이션을 위한 일련의 강력한 기능을 제공하는 간결하고 유연한 Node.js 웹 애플리케이션 프레임워크입니다.

API

자유롭게 활용할 수 있는 수많은 HTTP 유틸리티 메소드 및 미들웨어를 통해 쉽고 빠르게 강력한 API를 작성할 수 있습니다.

성능

Express는 기본적인 웹 애플리케이션 기능으로 구성된 얇은 계층을 제공하여, 여러분이 알고 있고 선호하는 Node.js 기능을 모호하게 만들지 않습니다.

 

Require() :

Node.js에서는 require 메서드를 통해 외부 모듈을 가져올 수 있습니다. Require 메서드는 node local object에 추가한 메서드로서 다음과 같이 파라미터로 추가할 모듈의 파일 경로 값을 받습니다.

 

CORS :

CORSCross Origin Resource Sharing의 약자로현재 도메인과 다른 도메인으로 리소스가 요청될 경우를 말한다. 예를 들어, 도메인 http://A.com 에서 읽어온 HTML페이지에서 다른 도메인 http://B.com/image.jpg를 요청하는 경우를 말한다. 이런 경우에 해당 리소스는 cross-origin HTTP 요청에 의해 요청된다보안 상의 이유로, 브라우저는 CORS를 제한하고 있다.

하지만 SPA(Single Page Application)의 경우에는, RESTful API를 기반으로 비동기 네트워크 통신을 하기 때문에 API 서버와 웹 페이지 서버가 다를 수 있다. 이런 경우에 API 서버로 요청을 할 시에 CORS 제한이 걸리게 된다.

 

 

'Node.js' 카테고리의 다른 글

보안 취약점을 잡자 ~!  (0) 2019.09.04
Nodejs CRUD API 만들어보기 ( 초급 )  (0) 2019.08.29
REST – PUT vs POST  (0) 2019.08.28
간단한 Todolist Select API를 만들어보았다!  (0) 2019.08.26
Node.js로 hello world 출력해보기  (0) 2019.08.07

안녕하세요 오늘은 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";

// MongoDB 모듈
import { TodoModel } from "../../database/models/todo"
import mongoDB from "../../database/mongodb";

// 서비스 모듈
// import { APIHelper } from "../helper";
import moment from 'moment';


/**
 * @class
 * @name TodoAPI
 * @description Todo 관련 API
 */
export default class TodoAPI {
  private readonly db: mongoDB;
  private readonly TODO_DB_ID = "todo";

  constructor() {
    this.db = mongoDB.root();
  }

  /**
   * @function throw
   * @description #1 /api/auth API에서 발생가능한 예외를 처리하는 메서드
   * @description #2 API_BASE에 상속
   */
  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);

      // todo update
      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);
        
        // SQL의 Select로 본다.
        // find : query로 검색된 결과를 보여준다. (return array)
        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 = {};
        
        // SQL의 Select로 본다.
        // find : query로 검색된 결과를 보여준다. (return array)
        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 });
    }
  }

    /**
   * @function delete
   * @access DELETE      
   * @description # todo 삭제.
   */
  public todoDel = async (req: any, res: express.Response) => {
    let result: CommunicationResult = new CommunicationResult();

    
    try {

      let query: any = {};
      // let todo: TodoModel = new TodoModel();
     
      // todo 삭제
      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),
        }
      };  
      
      //todo update
      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;
      }
      // DATE 값 예외처리 (검출)
      //CommunicationCode은 예외처리를 위한 컴포넌트 
      
      const date: Date = new Date(query.date);
      if(isNaN(date.getTime())) {
        result.set(CommunicationCode.FAIL_INVALID_DATA);
        result.msg = "date 파라미터가 유효하지 않습니다.";
        throw result;
      }
      //DATE 예외 처리 (유효)


      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 );
		
      //uid 값은 중복 방지, uid로 검색을 하기위해 uniqid라는 라이브러리를 사용했습니다.
      // https://www.npmjs.com/package/uniqid
      
      
      let insertQuery: any = {};
      insertQuery["id"] = uniqid();
      insertQuery["date"] = date;
      insertQuery["list"] = [];
      insertQuery["list"].push(list);
      
      //list에 push를 해주는 부분입니다.

      await this.db.insertOne(this.TODO_DB_ID, insertQuery);
      res.send({ _COM: result });
      
      // insertOne이라는 함수를 만들어서 인자값을 넣어줍니다 insertOne은 아래에서 설명하겠습니다.

    } 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> => {
        // Common.log(LogType.prompt, `${sID}: query: ${query}, Insert DB Data`);
        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);
        
        // SQL의 Select로 본다.
        // find : query로 검색된 결과를 보여준다. (return array)
        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 이라는 함수로 한개의 데이터 값을 찾습니다.

/**
     * @function findOne
     * @returns Promise<any>
     * @description DB에서 한 개의 데이터 값을 찾는다.
     * @tutorial OnlyKeyValue 주로 1개가 확실한 데이터를 찾는데 쓴다.
     * @param sID schema ID
     * @param query 찾을 검색문
     */
    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 = {};
        
        // SQL의 Select로 본다.
        // find : query로 검색된 결과를 보여준다. (return array)
        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함수

    /**
     * @function find
     * @returns Promise<any>
     * @description 찾는다. DB에서, 목적지를
     * @param sID schema ID
     * @param qKey Find Key, undefined의 경우 해당 collection의 전체 DOC을 검색한다.
     * @param qValue qKey에서 검색한 멤버의 찾을 조건. 정규식도 가능하다.
     */
    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);
                // resolve(cursor);
                // cursor.forEach((doc: any) => { docs.push(doc); })
                //     .then(value => { resolve(docs); })
                //     .catch(e => { reject(e); });
            } catch (e) {
                reject(e);
            }
        });
    }

 

Delete 함수

  /**
   * @function delete
   * @access DELETE      
   * @description # todo 삭제.
   */
  public todoDel = async (req: any, res: express.Response) => {
    let result: CommunicationResult = new CommunicationResult();

    
    try {

      let query: any = {};
      // let todo: TodoModel = new TodoModel();
     
      // todo 삭제
      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 함수

/**
     * @function delete
     * @returns Promise<any>
     * @description: 해당 스키마의 데이터를 수정한다.
     * @param sID : schema ID
     * @param query : 삭제할 조건
     * @param many(default false) : true로 바꿀 경우 관계된 모든 데이터를 삭제한다.
     * @param all(default false) : ※주의! true로 바꿀 경우 어떤 조건이든지 해당 스키마의 모든 데이터를 삭제한다.
     */
    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),
        }
      };  
      
      //todo update
      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함수

 /**
     * @function update
     * @returns Promise<any>
     * @description: 해당 스키마의 데이터를 수정한다.
     * @param sID schema ID
     * @param query : 수정할 조건
     * @param update : 수정할 조건
     * @param options : 수정할 조건
     * @param isMany : 수정을 여러개 할 지 여부
     */
    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;

 

감사합니다:)

'Node.js' 카테고리의 다른 글

보안 취약점을 잡자 ~!  (0) 2019.09.04
Express ?  (0) 2019.09.03
REST – PUT vs POST  (0) 2019.08.28
간단한 Todolist Select API를 만들어보았다!  (0) 2019.08.26
Node.js로 hello world 출력해보기  (0) 2019.08.07

많은 사람들 이 시스템을 설계 할 때 HTTP PUT과 POST 방법 중 하나를 선택하는 데 어려움을 겪고 있습니다 . 그러나 RFC 2616 은 두 가지를 구별하는 데있어 매우 분명하지만 복잡한 표현은 많은 사람들에게 혼란을 줍니당 

 

PUT POST
RFC-2616 PUT은 동봉 된 엔터티에 대한 메서드 요청이 제공된 Request-URI 아래에 저장되어 있음을 분명히 언급합니다 . Request-URI가 이미 존재하는 리소스를 참조하는 경우 – 업데이트 작업이 수행되고, 그렇지 않으면 Request-URI가 유효한 리소스 URI 인 경우 작성 작업이 수행됩니다 (클라이언트가 리소스 식별자를 결정할 수 있다고 가정).  POST방법은 origin 서버가 요청에 포함 된 엔티티를 요청 라인의 Request-URI에 의해 식별 된 자원의 새로운 하위 항목으로 수락하도록 요청하는 데 사용됩니다. 이는 본질적으로 POSTrequest-URI가 콜렉션 URI 여야 함을 의미합니다 .
PUT/test/test{test-id} POST/test
PUT메소드는 idempotent 입니다. 따라서 재시도 요청을 여러 번 보내는 경우 단일 요청 수정과 동일해야합니다. POST는 idempotent 아닙니다. 따라서 요청을 N 번 재 시도하면 서버에서 N 개의 서로 다른 URI로 N 개의 자원을 갖게됩니다.
PUT이미 자원 콜렉션의 일부인 단일 자원을 수정하려는 경우에 사용하십시오 . PUT은 리소스를 완전히 대체합니다. 요청이 자원의 일부를 업데이트하는 경우 PATCH를 사용하십시오. POST자원 콜렉션에서 하위 자원을 추가하려는 경우에 사용 하세요 .
PUT idempotent  이지만 응답을 캐시하지 않습니다. 응답에 적절한 Cache-Control 또는 Expires 헤더 필드가 포함되어 있지 않으면 이 메소드에 대한 응답을 캐시 할 수 없습니다 . 그러나 303 (기타 참조) 응답을 사용하여 사용자 에이전트가 캐시 가능한 자원을 검색하도록 지시 할 수 있습니다.
일반적으로 실제로는 항상 PUTUPDATE 조작에 권장 항상 POST CREATE 조작에 사용 권장

idempotent : 멱등(冪等)은 수학이나 전산학에서 연산의 한 성질을 나타내는 것으로, 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 의미함.

PUT vs POST : 예제

네트워크 애플리케이션을 설계한다고 가정 해 봅시다. 사용시기 POST및 사용시 기를보다 잘 이해하기 위해 URI와 그 목적을 나열 해 보겠습니다 PUT.

GET / device-management / devices : 모든 장치 가져 오기 POST / device-management / devices : 새 장치 만들기 GET / device-management / devices / {id} : "id" PUT / device-management /로 식별 된 장치 정보 가져 오기 devices / {id} : "id"로 식별 된 장치 정보 업데이트 DELETE / device-management / devices / {id} : "id"로 장치 삭제

 

참고 URL : https://restfulapi.net/rest-put-vs-post/

'Node.js' 카테고리의 다른 글

Express ?  (0) 2019.09.03
Nodejs CRUD API 만들어보기 ( 초급 )  (0) 2019.08.29
간단한 Todolist Select API를 만들어보았다!  (0) 2019.08.26
Node.js로 hello world 출력해보기  (0) 2019.08.07
노드 JS 설치해보기  (0) 2019.07.30

+ Recent posts