一个类似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
一个类似ThinkPHP的Node.js框架——QuickNode的更多相关文章
- 【转】node.js框架比较
我偶然间看到这篇文章,转这个文章并没有什么含义,仅仅是感觉总结的不错,对于新学node的友友们来说希望这篇文章为大家对 Node.js 后端框架选型带来一些帮助,学习不再迷茫,也是让我有个保存,以后参 ...
- 13 款惊艳的 Node.js 框架——第2部分
[编者按]本文作者为 Peter Wayner,主要介绍13款至精至简的 Node.js 框架,帮助你简化高速网站.丰富 API 以及实时应用的开发流程.本文系国内 ITOM 管理平台 OneAPM ...
- 初探 Node.js 框架:eggjs (环境搭配篇)
eggjs 是一个优秀的 Node.js 框架 概述:为什么标题上说 eggjs 是一个优秀的 Node.js 框架(可跳过)? 换言之,我们为什么选择 eggjs 进行开发而不是之前初学时使用的 E ...
- Node.js 框架
Node.js的是一个JavaScript平台,它允许你建立大型的Web应用程序. Node.js的框架平台使用JavaScript作为它的脚本语言来构建可伸缩的应用. 当涉及到Web应用程序的开发 ...
- LoopBack – 开源的,可扩展的 Node.js 框架
LoopBack 是建立在 Express 基础上的开源 Node.js 框架,专门为 Mobile,Web 和其他设备做了优化.LoopBack 能够连接到多个数据源,使用 Node.js 编写业务 ...
- node.js框架express的安装
node.js框架express的安装 首先假定你已经安装了 Node.js,接下来为你的应用创建一个目录,然后进入此目录并将其作为当前工作目录. $ mkdir myapp $ cd myapp 通 ...
- 不可错过的Node.js框架
前言 Node.js是由Ryan Dahl于2009年创建的.它是一个开源的跨平台运行时环境,用于开发服务器端和网络应用程序,它是基于Google Chrome V8 JavaScript引擎构建的. ...
- 13 款惊艳的 Node.js 框架——第1部分
[编者按]本文作者为 Peter Wayner,主要介绍13款至精至简的 Node.js 框架,帮助你简化高速网站.丰富 API 以及实时应用的开发流程.本文系国内 ITOM 管理平台 OneAPM ...
- Node.js 框架对比之 Express VS Koa
背景 上图是一个典型的采用 Node.js 开发 web 应用的前后端结构,下面介绍一下 Node 服务层在其中的作用以及使用 Node.js 的一些优劣. Node 服务层作用: 请求代理 传统做法 ...
随机推荐
- jquery 第一节 什么是jQuery
简单来说,jQuery就是javascript的一个框架,也可以说是javascript的一个库.
- L0,L1,L2正则化浅析
在机器学习的概念中,我们经常听到L0,L1,L2正则化,本文对这几种正则化做简单总结. 1.概念 L0正则化的值是模型参数中非零参数的个数. L1正则化表示各个参数绝对值之和. L2正则化标识各个参数 ...
- Struts 2 的常规配置
Struts 2 的默认配置文件是struts.xml,该文件应该放在Web应用的类加载路径下,通常就是放在WEB-INF/classes路径下. struts.xml文件的最大作用是配置Action ...
- PAT Basic 1034 有理数四则运算(20) [数学问题-分数的四则运算]
题目 本题要求编写程序,计算2个有理数的和.差.积.商. 输⼊格式: 输⼊在⼀⾏中按照"a1/b1 a2/b2"的格式给出两个分数形式的有理数,其中分⼦和分⺟全是整型范围内的整数, ...
- PAT Basic 1047 编程团体赛(20) [Hash散列]
题目 编程团体赛的规则为:每个参赛队由若⼲队员组成:所有队员独⽴⽐赛:参赛队的成绩为所有队员的成绩和:成绩最⾼的队获胜.现给定所有队员的⽐赛成绩,请你编写程序找出冠军队. 输⼊格式: 输⼊第⼀⾏给出⼀ ...
- android studio compile api implementation 区别
compile与api 二者等同,无区别 implementation与compile或implementation与api implementation编译的依赖只作用于当前的module.即APP ...
- java使用io流读取windows文件乱码问题
出现原因: 在IDEA中,使用 FileReader 读取项目中的文本文件.由于IDEA的设置,都是默认的 UTF-8 编码,所以没有任何 问题. 但是,当读取Windows系统中创建的文本文件时,由 ...
- vue wangeditor3封装
<script src="wangEditor/3.1.1/wangEditor.min.js"></script> Vue.component('my ...
- SMO算法--SVM(3)
SMO算法--SVM(3) 利用SMO算法解决这个问题: SMO算法的基本思路: SMO算法是一种启发式的算法(别管启发式这个术语, 感兴趣可了解), 如果所有变量的解都满足最优化的KKT条件, 那么 ...
- php 接口中常用的aes加密
<?php /** * Aes 对称加密 */ class Aes { public $key; public function __construct($key){ $this->key ...