使用 koa-generator 脚手架工具html
npm install koa-generator -g #全局安装 koa2 demo #建立demo项目 cd demo && npm install #安装依赖
默认生成项目结构以下前端
用脚手架生成的项目,默认是服务器渲染,即响应的是html视图。而咱们要开发接口,响应的是json数据。因此要删除渲染视图的代码。增长响应json的配置。node
首先删除views文件夹,接下来就是修改 app.jslinux
如下是要删除的代码nginx
const views = require('koa-views') app.use(views(__dirname + '/views', { extension: 'pug' }))
routes
文件夹读取文件const fs = require('fs') fs.readdirSync('./routes').forEach(route=> { let api = require(`./routes/${route}`) app.use(api.routes(), api.allowedMethods()) })
const jwt = require('koa-jwt') app.use(jwt({ secret: 'yourstr' }).unless({ path: [ /^\/$/, /\/token/, /\/wechat/, { url: /\/papers/, methods: ['GET'] } ] }));
// error app.use(async (ctx, next) => { try { await next() } catch(err) { ctx.status = err.statusCode || err.status || 500; ctx.body = err.message ctx.app.emit('error', err, ctx); } })
当接口发布到线上,前端经过ajax请求时,会报跨域的错误。koa2使用koa2-cors
这个库很是方便的实现了跨域配置,使用起来也很简单git
const cors = require('koa2-cors'); app.use(cors());
咱们使用mongodb数据库,在koa2中使用mongoose
这个库来管理整个数据库的操做。github
根目录下新建config文件夹,新建mongo.jsajax
// config/mongo.js const mongoose = require('mongoose').set('debug', true); const options = { autoReconnect: true } // username 数据库用户名 // password 数据库密码 // localhost 数据库ip // dbname 数据库名称 const url = 'mongodb://username:password@localhost:27017/dbname' module.exports = { connect: ()=> { mongoose.connect(url,options) let db = mongoose.connection db.on('error', console.error.bind(console, '链接错误:')); db.once('open', ()=> { console.log('mongodb connect suucess'); }) } }
而后在app.js中引入mongodb
const mongoConf = require('./config/mongo'); mongoConf.connect();
链接数据库完成!数据库
mongoose有两个核心概念,Schema
和Model
。Schema是预先定义的数据库模型骨架,定义集合存储的数据结构;Model是依据Schema构造生成的模型,有数据库操做的能力。
下面是案例,新建一个用户集合:
根目录下新建models文件夹,新建users.js
const mongoose = require('mongoose'); mongoose.Promise = global.Promise; const Schema = mongoose.Schema const ObjectId = mongoose.Types.ObjectId // Schema const usersSchema = new Schema({ _id: { type: ObjectId }, // 默认生成,不加也能够 username: { type: String, required: [true,'username不能为空'] }, sex: { type: String, enum: ['man','woman'], required: [true,'sex不能为空'] }, age: { type: Number required: [true,'age不能为空'] }, avatar: { type: String, default: '' } }) // Model const users = mongoose.model('users',usersSchema); module.exports = users;
这样,一个用户集合的model就建好了,接下来在路由中直接引入这个model,就能够进行数据库操做了
按照app.js的配置,routes文件夹下每个文件都要注册成为一个路由
一个基本的, RESTful风格的用户增查改删接口路由文件以下,包含了增查改删的通用写法
const router = require('koa-router')() router.prefix('/users') router.get('/', function (ctx, next) { ctx.body = '获取全部用户' }) router.get('/:id', function (ctx, next) { let id = ctx.params.id ctx.body = '获取单个用户' }) router.post('/', function (ctx, next) { let data = ctx.request.body ctx.body = '新增用户' }) router.put('/:id', function (ctx, next) { let id = ctx.params.id ctx.body = '修改用户信息' }) router.delete('/:id', function (ctx, next) { let id = ctx.params.id ctx.body = '删除用户' }) module.exports = router
任何一次请求接口传来的参数,首先要在最前面作一次参数验证。若是请求参数不合法,那么直接返回错误信息,无需继续走下面的业务逻辑。
参数验证,推荐使用 Joi 这个库,它是 hapijs 内置的参数验证模块,也是使用Schema定义数据结构。
好比建立用户接口,对用户传来的数据进行验证
const Joi = require('joi') router.post('/', function (ctx, next) { let data = ctx.request.body let schema = Joi.object().keys({ username: Joi.string().required(), sex: Joi.string().required(), age: Joi.number().required() }) let result = Joi.validate(data, schema); if(result.error) { return ctx.body = result.error.details } let reqdata = result.value; #通过验证后的数据 })
这样就完成了一个简单的验证,具体验证请看joi文档
以前已经建立了users的model,如今咱们能够直接在路由文件中使用该模块,进行数据库操做
// 引入上一步建立的model const Users = require('../models/users'); router.get('/', async (ctx, next)=> { ctx.body = await Users.find() }) router.get('/:_id', async (ctx, next)=> { let _id = ctx.params._id ctx.body = await Users.findOne({_id}) }) // 建立用户 router.post('/', async (ctx, next)=> { let data = ctx.request.body ctx.body = await Users.create(data) }) router.put('/:_id', async (ctx, next)=> { let _id = ctx.params._id let data = ctx.request.body ctx.body = await Users.update({_id}, { $set: data }, { runValidators: true }) }) router.delete('/:_id', async (ctx, next)=> { let _id = ctx.params._id ctx.body = await Users.deleteOne({_id}) })
这是基本的增查改删的操做。这里用到了koa2最大的亮点,就是async
,await
异步处理方案。只要await 后面返回的是 promise,就能够直接使用。这比在 express 框架上使用 then 方法处理要优雅的多的多。
上一步讲的请求参数验证,是第一层验证。其实在model操做中,数据进入数据库时,也会进行一层验证,就是mongoose的Schema定义的数据类型和字段,若是不匹配,则会拒绝写入并返回错误。这就是mongoose的好处之一,能够防止写入不规范的数据。
这里不作mongoose的详解,附上文档地址:mongoose
应用启动文件是 www/bin
,因此咱们能够经过 node www/bin
开启动应用,默认是9000端口。
这样启动会有一个问题,就是在修改代码以后,程序不会自动运行最新的代码,须要手动断开从新启动。
pm2的诞生就是用来解决这个问题。他是一个nodejs应用程序管理器,经过pm2启动nodejs应用,开启监听模式,它就能够自动监听文件变化重启应用。
固然pm2的做用还有不少,首先启动应用:
pm2 start --name koa2 bin/www --watch
结果以下:
而后能够删除或重启:
pm2 list # 查看进程列表 pm2 restart koa2 # 重启名称为koa2的应用 pm2 delete koa2 # 删除名称为koa2的进程 pm2 logs koa2 # 查看名称为koa2的进程日志
koa2应用在linux服务端部署,首先须要pm2来启动应用。可是koa2项目启动通常不使用80端口,因此在线上部署时,还须要nginx作反向代理以及域名配置。
配置以下:
server { listen 80; server_name api.xxxxx.com; location / { proxy_pass http://127.0.0.1:9000; #兼容scoket.io proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; } }
这样访问 api.xxxxx.com 就能访问koa2的应用了!
若是是https
,须要修改下配置:
server { listen 80; server_name api.xxxxx.com; rewrite ^(.*) https://$host$1 permanent; } server { listen 443 ssl; server_name api.ruidoc.com; ssl on; ssl_certificate 1_api.xxxxx.com_bundle.crt; #ssl证书 ssl_certificate_key 2_api.xxxxx.com.key; location / { proxy_pass http://127.0.0.1:9000; #兼容scoket.io proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; } }
此时你能够上传你的应用了!
通常上传源码的时候,可能会用ftp服务之类的。若是是Mac用户,那么能够配置一条快捷命令,直接上传,方便省事
rsync -avz ./* root@1.23.45.67:/home/api
root 是服务器用户名;
1.23.45.67 是服务器IP地址;
/home/api 是源码在服务器的存放路径
而后输入服务器密码,就能够快速上传了,并且只会上传修改过的源码,很是快速。
还能够将命令配置到package.json
文件的scripts下,如
"scripts": { "upload": "rsync -avz ./* root@1.23.45.67:/home/api" }
此时你能够这样上传:
npm run upload
这样配置上传效率很是高,一块儿试试吧!
本文由
杨成功
原创,更多原创文章关注
杨成功的全栈之路