Last active
May 1, 2017 05:18
-
-
Save pjchender/8479581bd7c5215c12e39fe4decb439d to your computer and use it in GitHub Desktop.
[Express] Some boilerplate for Express
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require('express') | |
const app = express() | |
const routes = require('./routes') | |
const jsonParser = require('body-parser').json | |
const logger = require('morgan') | |
app.use(jsonParser()) | |
app.use(logger('common')) // 給我們 prettify 後的 logger | |
app.use('/questions', routes) // 這個 middleware 只處理來自 '/questions' | |
/** | |
* Get request and send response | |
**/ | |
** | |
* Demo for get data from GET and POST | |
*/ | |
const express = require('express') | |
const app = express() | |
const jsonParser = require('body-parser').json | |
app.use(jsonParser()) | |
app.use((req, res, next) => { | |
console.log(req.body.color) // req.body 可以取得 POST 的 body(但要先 parser 過) | |
next() | |
}) | |
app.use((req, res, next) => { | |
req.myMessage = 'Hello, middleware 2' // send variable to other middleware | |
next() | |
}) | |
app.use((req, res, next) => { | |
console.log('color', req.query.color) // req.query 可以取得 URL ? 後的內容 | |
next() | |
}) | |
app.use((req, res, next) => { | |
console.log(req.myMessage) // get variable from previous middleware | |
next() | |
}) | |
app.use('/different/:id', (req, res, next) => { | |
console.log(req.params.id) // req.params.id 可以取得 URL 中的參數(:variable) | |
next() | |
}) | |
// catch 404 and forward to error handler | |
app.use((req, res, next) => { | |
let err = new Error('Not found (404)') | |
err.status = 404 | |
next(err) // 將錯誤訊息傳送給 error handler | |
}) | |
// Error Handler | |
app.use((err, req, res, next) => { | |
res.status(err.status || 500) // 如果有給 err.status 則顯示,否則顯示 500(internal server error) | |
res.json({ | |
error: { | |
message: err.message | |
} | |
}) | |
}) | |
// Listen for the server | |
const port = process.env.PORT || 3000 | |
app.listen(port, () => { | |
console.log('Express is listening on port ' + port + ' ...') | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const mongoose = require('mongoose') | |
// -- 1. 和 mongoDB 連線 -- | |
mongoose.connect('mongodb://localhost:27017/bookworm') | |
var db = mongoose.connection // 將連線的物件儲存,並可監聽事件 | |
// -- 2. 處理連線錯誤的情況 -- | |
db.on('error', (err) => { | |
console.error('connection error:', err) | |
}) | |
// -- 3. 成功連線要執行的動作 -- | |
db.once('open', () => { | |
console.log('db connection successful') | |
// All database communication goes here | |
// -- 4.1 建立 Schema (用來描述 document) -- | |
var Schema = mongoose.Schema | |
var AnimalSchema = new Schema({ | |
type: { | |
type: String, | |
default: 'notype' | |
}, | |
size: { | |
type: String, | |
default: 'nosize' | |
}, | |
color: { | |
type: String, | |
default: 'notype' | |
}, | |
mass: { | |
type: Number, | |
default: 0 | |
}, | |
name: { | |
type: String, // 記得 S 大寫 | |
default: 'noname', // 預設值 | |
required: true, // 表示為必填欄位,若缺少此欄位,mongoDB 不會建立此 document 並會回傳 error | |
trim: true, // 去除掉不必要的空白 | |
unique: true // 確認這個 email 的值沒有在其他 document 中出現過(也就是沒有相同的 email) | |
} | |
}) | |
// --4.2 可以為 Schema 添加 method(要在 compile 前),類似 instance method | |
AnimalSchema.methods.getType = function () { | |
// 這裡的 this 指透過這個 function constructor 建立的物件 | |
console.log('This animal is a/an', this.type) | |
} | |
AnimalSchema.methods.findSameColor = function (callback) { | |
return this.model('Animal').find({color: this.color}, callback) | |
} | |
// --4.3 prehook | |
AnimalSchema.pre('save', function (next) { | |
// this 指稱的是要被儲存的 document | |
// 記得不要用 arrow function | |
if (this.mass >= 100) { | |
this.size = 'big' | |
} else if (this.mass >= 5 && this.mass < 100) { | |
this.size = 'medium' | |
} else { | |
this.size = 'small' | |
} | |
next() | |
}) | |
// --4.4 建立 statics method,類似 class method | |
AnimalSchema.statics.findSize = function (size, callback) { | |
// this 指稱的是 collection (Animal) | |
// callback 表示找到之後要執行的動作 | |
return this.find({size: size}, callback) | |
} | |
// -- 5. Compile Schema 變成 Model -- | |
// 利用 AnimalSchema 來建立一個 model (用來建立和儲存 document) | |
var Animal = mongoose.model('Animal', AnimalSchema) // 它會在 mongo 中建立名為 animals 的 collections | |
// -- 6. 建立 document -- | |
// 利用 Animal 建立 animal documnet | |
var elephant = new Animal({ | |
type: 'elephant', | |
size: 'big', | |
color: 'gray', | |
mass: 6000, | |
name: 'Lawrence' | |
}) | |
// console.log(elephant.type) // 'elephant' | |
// elephant.getType() // 'This animal is a/an elephant' | |
var whale = new Animal({ | |
type: 'whale', | |
size: 'big', | |
color: 'blue', | |
mass: 6000, | |
name: 'Whawha' | |
}) | |
var goldfish = new Animal({}) // 以預設值建立一筆資料 | |
// 一次建立多筆 documents | |
var animalData = [ | |
{ | |
type: 'mouse', | |
color: 'gray', | |
mass: 0.034, | |
name: 'Marvin' | |
}, | |
{ | |
type: 'nutria', | |
color: 'brown', | |
mass: 6.35, | |
name: 'Gretchen' | |
}, | |
{ | |
type: 'wolf', | |
color: 'gray', | |
mass: 45, | |
name: 'Iris' | |
}, | |
elephant, | |
whale, | |
goldfish | |
] | |
// 透過 remove 刪除 collection 中的所有 document, | |
// 由於 remove 也是非同步的,因此我們要把 save 放到 callback 中 | |
// 1. 先刪除 collcetion 中的所有 documents | |
Animal.remove({}, () => { | |
console.log('removed successed') | |
// 2. 一次儲存多筆 document | |
Animal.create(animalData, (err, animals) => { | |
// 3.1 利用 instance method 列出和 elephant 相同顏色的動物 | |
if (err) console.log(err) | |
Animal.findOne({type: 'elephant'}, function (err, elephant) { | |
if (err) console.log(err) | |
elephant.findSameColor(function (err, animals) { | |
if (err) console.log(err) | |
console.log('findSameColor', animals) | |
db.close(() => { | |
console.log('db closed') | |
}) | |
}) | |
}) | |
// 3.2 利用 statics method 列出 {size: 'big'} 的 document | |
// Animal.findSize('big', (err, animals) => { | |
// if (err) console.log(err) | |
// animals = animals.map((animal) => { | |
// return ({name: animal.name, type: animal.type, size: animal.size}) | |
// }) | |
// console.log(animals) | |
// // 4. 關閉連線 | |
// db.close(() => { | |
// console.log('db connection closed') | |
// }) | |
// }) | |
}) | |
}) | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require('express') | |
const router = express.Router() | |
/** | |
* SomeNote: | |
* 因為在 app.js 中是套用 app.use('/qustions', routes),所以這個 router 的根目錄為 '/questions' | |
*/ | |
// GET '/questions',Routes for question collection | |
router.get('/', (req, res) => { | |
res.json({response: 'You send me a GET request'}) // 這會結束 req cycle | |
}) | |
// POST '/questions',Routes for creating questions | |
router.post('/', (req, res) => { | |
res.json({ | |
response: 'You send me a POST request', | |
body: req.body | |
}) | |
}) | |
// GET '/questions/:qID',Routes for specific question | |
router.get('/:qID', (req, res) => { | |
res.json({ | |
response: 'You send me a GET request for ID ' + req.params.id | |
}) | |
}) | |
// POST '/questions/:qID/answers,Routes for creating answers | |
router.post('/:qID/answers', (req, res) => { | |
res.json({ | |
response: 'You send me a POST requst to /answers', | |
questionId: req.params.qID, | |
body: req.body | |
}) | |
}) | |
// PUT '/questions/:qID/answers/:aID',Edit a specific answer | |
router.put('/:qID/answers/:aID', (req, res) => { | |
res.json({ | |
response: 'You send me a PUT request to /answers', | |
questionId: req.params.qID, | |
answerId: req.params.aID, | |
body: req.body | |
}) | |
}) | |
// DELETE '/questions/:qID/answers/:aID',Delete a specific answer | |
router.delete('/:qID/answers/:aID', (req, res) => { | |
res.json({ | |
response: 'You send me a DELETE request to /answers', | |
questionId: req.params.qID, | |
answerId: req.params.aID | |
}) | |
}) | |
// Vote on a specific answer | |
// POST '/questions/:qID/answers/:aID/vote-up' | |
// POST '/questions/:qID/answers/:aID/vote-down' | |
router.post('/:qID/answers/:aID/vote-:dir', (req, res) => { | |
res.json({ | |
response: 'You send me a POST request to /vote=' + req.params.dir, | |
questionId: req.params.qID, | |
answerId: req.params.aID, | |
vote: req.params.dir | |
}) | |
}) | |
module.exports = router |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
REST