先參考(抄襲)一下express的api
app.use(...);
router.get(url,...)
router.post(url,...)
對比原生的node http模塊,express這些API非常好用了,并且use方法,可以把功能代碼拆分出來,比如body-parser router 都是拆成中間件的形式,完成自己的功能的
試著手寫一個(gè)server實(shí)現(xiàn)這些功能,開發(fā)一個(gè)能用一些實(shí)用的API的server,而不是原生NodeAPI

app
app是傳入HTTP.createServer的handeler,那它肯定是這樣一個(gè)函數(shù)
const app = (req, res) => {
...
}
用于執(zhí)行use注冊的中間件,把url分發(fā)給router路由(其實(shí)這是router該干的事,app只處理use的中間件)
實(shí)現(xiàn)app.use
用中間件的時(shí)候,中間件中都有3個(gè)參數(shù),req,res,next,前兩個(gè)簡單,從app作用域就能拿到,那么next()調(diào)用呢,next調(diào)用時(shí),也有3個(gè)參數(shù),reqresnext,其中next是下一環(huán)節(jié)的中間件。
想了半天,給注冊的中間件數(shù)組們一個(gè)排序,創(chuàng)建了一個(gè)next方法按序調(diào)用。。。(應(yīng)該不太對,不過實(shí)現(xiàn)了)
const app = (req, res) => {
// json api
res.json = json
console.log('start', req.method, req.url, req.query)
// 反著給他們幫定next參數(shù)
function next(index) {
console.log('next' + index, req.url, req.query)
app.actions[index].call(this, req, res, next.bind(this, index + 1))
}
app.actions[0](req, res, next.bind(this, 1));
}
app.actions = []
// 實(shí)現(xiàn)注冊中間件
app.use = (handler) => {
app.actions.push(handler)
}
module.exports = app
// json
function json(object) {
this.writeHeader(200, { 'Content-Type': 'application/json;charset=UTF-8' })
this.write(JSON.stringify(object))
this.end()
}
router
router的功能是用來分發(fā)url給 router.get 或 router.post 注冊的handler
那簡單,用if判斷一下就好了
const router = (req, res, next) => {
const { method, url } = req
if (method === 'GET') {
router.getRoutes[url](req, res, next)
} else if (method === 'POST') {
router.postRoutes[url](req, res, next)
}
}
router.getRoutes = {}
router.postRoutes = {}
router.get = (path, handler) => {
router.getRoutes[path] = handler
}
router.post = (path, handler) => {
router.postRoutes[path] = handler
}
module.exports = router
中間件
寫好了app.use,就可以瘋狂的以中間件的形式寫server的功能了
queryString
原始的message.url 是帶著參數(shù)的,要在這個(gè)環(huán)節(jié)給拆出來,用正則表達(dá)式替換就可以了
let { REG_URL } = require('./CONST') ///(?!=\?)(\/.+)\?(.+)/
// 處理querystring中的參數(shù)
module.exports = function (req, res, next) {
const url = req.url.replace(REG_URL, '$1')
const querys = req.url.replace(REG_URL, '$2').split('&')
const query = {}
querys.forEach(item => {
const [key, value] = item.split('=')
query[key] = value
})
req.url = url
req.query = query
next()
}
body-parser
body-parser太難寫了,看了半天api文檔也沒明白咋取,知道的朋友給我留言,謝謝你們了。
好在寫了app.use,直接use第三方的body-parser模塊就可以實(shí)現(xiàn)了。

還行,第三方模塊可以用,最基本的流程跑通了
over 沒處理報(bào)錯(cuò)