poemyear / pickpic

2 stars 0 forks source link

Server Preparation Guide #8

Open poemyear opened 5 years ago

poemyear commented 5 years ago

Install

Platform & Database

Node.js

brew install nodejs

mongodb

  • mongodb install guide blog $ brew install mongodb $ sudo mkdir /data/db $ sudo chown $USER /data/db $ mongod new terminal $ mongo

    NPM modules

express

npm install express

multer

npm install multer https://wayhome25.github.io/nodejs/2017/02/21/nodejs-15-file-upload/

body-parser

npm install body-parser

npm install cookie-parser npm install morgan

mongoose

npm install mongoose https://javafa.gitbooks.io/nodejs_server_basic/content/chapter12.html

poemyear commented 5 years ago

기본 서버 실행 구조

실행 파일 (main)

bin/www

File: app.js

express 객체 생성

var express = require('express');
var app = express();

모듈 export

module.exports = app;

File: bin/www

app.js 에서 export한 모듈 로드하여 서버 실행

var app = require('../app');
var server = http.createServer(app);
server.listen(port);
poemyear commented 5 years ago

Router 구조

Router: routes/users/index.js

controller는 비즈니스로직을 분리하기 위해 모듈로 분리한 것으로 우선 이해하지 않고 스킵 https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/users/index.js#L1-L7

https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/users/index.js#L13 Path: / 에 대해 GET, POST 메소드를 등록하고 Path: /:id 에 대해 /asdfasdf 으로 요청이 들어올 경우 req.params.id에 asdfadsf이 매핑됨 이 모듈을 export 하고 app.js에서 로드한다

File: app.js

routes/users/index 라우터 모듈을 로드하여
/users 으로 요청이 들어오면 이 모듈이 처리하도록 넘긴다.

var usersRouter = require('./routes/users/index');
var app = express();
app.use('/users', usersRouter);

Controller

위 index.js 에서 contoller을 로드한 이후에 함수를 호출하여 넘기는데, 지정한 path에 GET / POST 요청이 들어오면 callback함수를 Controller 에 정의하여 함수를 넘겨줌

https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/users/index.js#L5 즉. 위 코드는 아래 함수로 이어짐 https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/users/controller.js#L5-L8 마찬가지로 여기도 db 모듈로 만들어서 db 관련 로직은 db.fetchUsers 에서 처리하도록 함수를 넘김

poemyear commented 5 years ago

Router

위 Route 구조대로 현재는 event, user 라우터를 등록해서 API를 만들어놓은 상태 (API Spec)

https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/app.js#L9-L11 https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/app.js#L30-L31

Events API

https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/events/index.js#L26-L35

Users API

https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/users/index.js#L5-L11

poemyear commented 5 years ago

Multer

파일 업로드 처리를 위해 Multer를 사용했는데, multer 사용한 upload example을 따로 남겨둠

Storage 지정 (diskStorage)

multer모듈이 파일을 받아서 처리할 때에 콜백을 등록해준다. 파일 저장 위치 (destination)과 파일명 변경 규칙 등을 지정할 수 있음 아래 코드는 upload_example/ 하위에 저장되고, 파일명은 파일명-timestamp.확장자 으로 변경하도록 되어있음 https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/upload_example.js#L3-L15

multer 객체 생성

위에서 생성한 storage를 셋팅한 객체 생성 https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/upload_example.js#L17-L22

POST method에서 사용

다수의 multipart data 를 받을 경우 array를, 한개의 파일은 single을 사용하라고 multer 가이드에 나옴 아래코드는 파일을 전송할 때에 Key: userfile 으로 업로드한 파일들에 대해서 위에서 만든 multer 객체로 처리하라 정도로 이해가 됨 그러면 storage 에서 지정한 콜백들을 거치고 나서, 마지막에 지정된 콜백함수로 들어감 이건 예제 파일이고, 실제 사용하는 코드인 event/index.js 에서는 콜백함수를 controller.js 의 함수로 넘김 https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/upload_example.js#L30-L36

app.js

static을 쓰면 path를 정적으로 지정하여 쓸 수 있다는데 정확히는 무슨말인지 이해못함 여튼 위의 예제 코드는 /upload 으로 요청시 해당 라우터로 전달됨 https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/app.js#L32-L33


for uploading on browser

아래는 browser에서 업로드 가능하도록 연동하기위한 코드, upload/show으로 들어오면 view/board 를 뿌려준다. https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/upload_example.js#L25-L27

board.pug

pug가 무슨확장자 인지 모르겠는데 여튼 page하나를 뿌려준다 file 3개를 인풋으로 받아서 모두 Key:userfile 으로 하여 multipart/form-data 형식으로 upload_example/create 에다가 POST 요청을 한다는 소리임

결국 위에서 정의한 POST로 호출한다는건데 browser통해서 호출하겠다는 뜻임, 지금 보니까 app.js에서 /upload_example 으로 패스 등록해야하는데 /upload 로 되어있어서 동작하진 않을듯

https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/views/board.pug#L2-L11

poemyear commented 5 years ago

DB (Mongoose)

DB 코드는 리팩토링을 다시해야하는데 이해를 위한 구조 핵심을 설명하겠음

Load module & DB Connect

https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/db.js#L1 DB에 연결하는 함수 https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/db.js#L25-L35

DB연결은 서버가 1회 접속하면 되므로 app.js에서 connect 함수를 호출하도록 한다 https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/app.js#L17-L18

Schema

mongo DB는 원래 schema-less 하게 사용하는 구조임 그렇지만 사람들은 RDBMS에 익숙하고? 프로그래밍 관점에서 Schema가 정해져 있어야 에러 디텍트가 편해서? mongoose에서 컴파일단(?)에서 가상적으로 Schema를 정의해서 그에 맞춰 document를 가공하여 mongodb에 관리하는 방식을 사용함

https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/db.js#L13-L15 위와 같이 정의한다 mongoose에서 User 으로 사용할 Schema는 { name: String } 구조를 갖는 document 이다. 그리고 이 mongoose model 객체를 node js 코드내에서 User로 사용하겠다 (var User). 라는 뜻

mongodb에 저장되는 document는 아래와 같은 구조로 생성이 됨, _id는 mongodb 고유 id, __v는 version? 자동으로 붙음. name 이 내가 지정한 Schema field 이다

  {
        "_id": "5d57d2bcb0027e6d257713ac",
        "name": "hyeonsoo",
        "__v": 0
    }

Schema.funciton: find()

위에서 var User 으로 정의한 mongoose model 으로부터 find() 함수를 호출한다 그럼 var User는 mongoose의 User라는 스키마에 해당하고, mongoose가 mongodb에서 User 스키마에 맞는 문서들을 기준으로 find() 동작을 수행한다

https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/db.js#L131-L134 find(), findOne(). findById(),,, 등의 함수를 지원하는데 find()는 조건을 만족하는 document를 모두 가져오는 것임

핵심은 지정한 Schema 객체에 대해 함수를 호출하여 동일 Schema 한정 documents 들을 기준으로 query하는 것

User.find() 실행 결과

[
    {
        "_id": "5d57d2bcb0027e6d257713ac",
        "name": "hyeonsoo",
        "__v": 0
    },
    {
        "_id": "5d57d4a12911d36eeb8024db",
        "name": "bakyuns",
        "__v": 0
    },
    {
        "_id": "5d57d4a42911d36eeb8024dc",
        "name": "jimi",
        "__v": 0
    }
]

이외에도 Event, Vote Schema를 생성해두었음, 위의 User가 조금 이해가 된다면 아래 Schema도 이해해보면 됨 https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/db.js#L17-L22 https://github.com/poemyear/pickpic/blob/729fc98f0aef2f0c145b47a1cbd8a0a643aab9df/pickpicServer/routes/db.js#L4-L11

poemyear commented 5 years ago
brew install imagemagick graphicsmagick
npm install imagemagick graphicsmagick --save