一個類似ThinkPHP的Node.js框架——QuickNode

QuickNode

Node.js從QuickNode開始,讓restful接口開發更簡單!

PHP的MVC

作爲一名曾經的PHP開發者,我也有過三年多的thinkphp使用經驗,那是我學習PHP接觸的第一個MVC框架。ThinkPHP目前也算是國內最流行的PHP框架了吧,於我說來,該框架給我留下的最深的印象就是在創建新控制器和新方法時候的簡單便捷,以及她經典的/Controller/Action路由模式。

大學畢業後,我的工作轉向了前端,但作爲一個全棧,我依然負責一些後端開發和服務器運維,再使用了Node之後,我逐漸愛上了這一門簡潔而有精彩的語言,尤其是ES7的標準之後,TS的加成,讓我對JS,TS家族產生了濃厚的依賴,現在不管是做網站的API,手機app還是腳本我都會首選JS。

有過Node開發經驗的童鞋應該知道,Node的web框架雖然更加簡單,體積也更加小,但伴隨而來的也是模塊化帶來的凌亂的包,凌亂的代碼組織,繁瑣的配置,當你下載express之後依然需要針對請求接口來手動配置路由,十分麻煩。對於剛剛從php轉投node陣營的朋友需要一些學習成本的。並且這讓我一個習慣了使用MVC框架的PHP程序員表示十分頭大。此時最迫切的需求就是一個PHP程序員習慣的框架,類似ThinkPHP這樣的。

爲此我專門使用Node.js開發了一個仿ThinkPHP的簡易MVC框架,說他是MVC其實也不嚴格,這貨更像是一個node版的ThinkPHP,具備了ThinkPHP基本的功能,同時具備了restful的接口風格。

開始使用

我在github發佈了一個QuickNode,這就是我所述的仿ThinkPHP的Node MVC 框架。 但不是嚴格意義的MVC框架,所以我不會這麼定義這個框架。

QuickNode的使用方式和ThinkPHP如出一轍。

安裝Node

安裝最新版的node.js,基操,不做贅述,推薦官網下載。https://nodejs.org

git clone代碼基架

git clone https://github.com/devilyouwei/QuickNode.git

安裝package

進入下載好的項目目錄

npm install

好了,不報錯的話就是所有的外包安裝好了。

配置MySQL

進入Config目錄,配置db.json用以連接mysql,可以是本地也可以遠程的mysql服務器。

開始使用

node ./Server.js

使用supervisor調試

推薦使用supervisor,因爲node太蠢了,每次修改代碼都要重新運行命令,supervisor可以自動監視代碼的變動,一旦修改了代碼,即可自動運行最新的代碼,方便調試

npm -g install supervisor

supervisor ./Server.js

運行成功
案例

樣例

這裏給出一些案例,帶各位新手體驗一下如何創建一個API,以及如何訪問這個API,如何連接數據庫,如果你是PHP程序員的話,你會發現這和ThinkPHP真的非常相似。

創建控制器

首先在Controller目錄中創建一個文件,例如,Test.js,這就是一個JS的類文件,同樣也是一個控制器。

代碼如下:

class Test{
    static async test(req,res){
        return res.json({status:1,data:'test data',msg:'Successful data loaded'})
    }
}
module.exports=Test

接下打開瀏覽器進入:http://localhost:3000/Test/test

在這裏插入圖片描述
新控制器訪問成功了。

連接數據庫

在連接數據庫前,請先配置好db.json文件,確保獲得訪問數據庫的權限。

接下來示範連接數據庫的方式:

const db = require('./private/DB.js')
const $ = require('../private/tool.js')

class Config{
    static async query(req,res){
        let data = await db.query('select * from languages')
        return res.json({status:1,data:data,msg:'languages'})
    }
    static async insert(req,res){
        let body=req.body // 獲取post和get傳來的數據
        // 新增
        let data={
               title:body.title,
               rank:body.rank,
               time:$.date2stamp()
        }
        // 插入數據
        let id = await db.insert('type',data)
        if(id>0) return res.json({status:1,msg:'插入成功'})
        else return res.json({status:0,msg:'插入失敗,數據寫入錯誤'})
    }
}
module.exports=Config

更多數據庫的玩法請參考:https://www.npmjs.com/package/mysql

前端傳參

QuickNode允許GET和POST傳參,POST傳參建議使用form-data形式,前端需要使用new FormData()來初始化一個formdata的數據格式。

無論GET還是POST都是在req.body中獲取數據。

const db = require('./private/DB.js');

class Config{
    static async index(req,res){
        let id = req.body.id
        return res.end(`Id is:${id}`)

    }
}
module.exports=Config

在這裏插入圖片描述

前端代碼參考(vue):

import { Toast, Dialog } from 'vant'
import Mobile from 'mobile-detect'
import axios from 'axios'
import {i18n} from './plugins/i18n.js'

//const URL = 'http://localhost:3000' // 測試服
const URL = 'https://api.qbite.us' // 正式服
export default {
    // use axios
    async post (ctl, act, data = {}, load = false) {
        if(!ctl || !act) throw new Error('no controller or action')
        let url = `${URL}/${ctl}/${act}`
        let form = new FormData()
        for (let i in data) form.append(i, data[i])

        form.append('user', JSON.stringify(this.getUserInfo()))
        if (load) this.loading(load)
        try{
            let res = await axios({
                method: 'post',
                headers: { 'content-type': 'application/x-www-form-urlencoded' },
                url: url,
                data: form,
                responseType: 'json',
                changeOrigin: true // 允許跨域
            })
            res = res.data
            res.status = parseInt(res.status) || 0
            if(res.status == -1){
                localStorage.removeItem('user')
                await this.alert(i18n.t('noLogin'))
                return location.replace(`/?did=${localStorage.getItem('did')}`)
            }
            return res
        }catch(e){
            throw e
        }finally{
            if (load) this.loading(false)
        }
    },
    
    // use fetch, it can't compatible with old browser
    async post2(ctl='',act='',data={},load=false){
        if(!ctl || !act) throw new Error('no controller or action')
        let url = `${URL}/${ctl}/${act}`
        // 表單信息
        let form = new FormData()
        for (let i in data) form.append(i, data[i])
        // 餐桌ID
        form.append('did',localStorage.getItem('did')) // 桌子

        let request = new Request(url, {method: 'POST', body: form})
        try {
            if (load) this.loading(true)
            let res = await fetch(request).then(res => res.json())
            res.status = parseInt(res.status) || 0
            return res
        } catch (err) {
            throw err
        } finally {
            if (load) this.loading(false)
        }
    }
}

這裏介紹了兩種post方法,一種使用axios,一種使用最新的fetch API,無論哪種都要使用formdata格式來傳輸數據。

後記

QuickNode是從Qbyte LLC(US)公司商業項目“Qbite”中開源出來的一個後端框架,框架本身十分精簡和輕便,適合做restful接口,模式類似國內很多傳統的MVC框架。

Qbite是一個美國的線上線下點餐系統,目前所使用的後端框架支持就是QuickNode。QuickNode會在Qbite的持續使用中得到測試和更新。

該MVC框架目前尚未加入Model一塊,後續項目中會加入Model,各位小夥伴也可以fork我們項目提供方案和貢獻。

感謝各位對QuickNode的支持,喜歡的朋友請幫忙star一下下,你的star就是我們的動力,很高興您使用我們的項目。

https://github.com/devilyouwei/QuickNode

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章