Skip to content

Instantly share code, notes, and snippets.

@pjchender
Last active May 1, 2017 05:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pjchender/8479581bd7c5215c12e39fe4decb439d to your computer and use it in GitHub Desktop.
Save pjchender/8479581bd7c5215c12e39fe4decb439d to your computer and use it in GitHub Desktop.
[Express] Some boilerplate for Express
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 + ' ...')
})
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')
// })
// })
})
})
})
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
@pjchender
Copy link
Author

REST

  • REST 指的是 representational state transfer,是一種定義網路伺服器要如何回應的方式。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment