内容简介:使用 koa-generator 脚手架工具默认生成项目结构如下
初始化项目
使用 koa-generator 脚手架工具
npm install koa-generator -g #全局安装 koa2 demo #创建demo项目 cd demo && npm install #安装依赖
默认生成项目结构如下
修改配置
用脚手架生成的项目,默认是服务器渲染,即响应的是html视图。而我们要开发接口,响应的是json数据。所以要删除渲染视图的代码。增加响应json的配置。
首先删除views文件夹,接下来就是修改 app.js
1. 删除视图配置
以下是要删除的代码
const views = require('koa-views') app.use(views(__dirname + '/views', { extension: 'pug' }))
2. 修改路由的注册方式,通过遍历 routes
文件夹读取文件
const fs = require('fs') fs.readdirSync('./routes').forEach(route=> { let api = require(`./routes/${route}`) app.use(api.routes(), api.allowedMethods()) })
3. 添加jwt认证,同时过滤不需要认证的路由,如获取token
const jwt = require('koa-jwt') app.use(jwt({ secret: 'yourstr' }).unless({ path: [ /^\/$/, /\/token/, /\/wechat/, { url: /\/papers/, methods: ['GET'] } ] }));
4. 全局错误捕获并响应
// 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); } })
5. 跨域处理
当接口发布到线上,前端通过ajax请求时,会报跨域的错误。koa2使用 koa2-cors
这个库非常方便的实现了跨域配置,使用起来也很简单
const cors = require('koa2-cors'); app.use(cors());
连接数据库
我们使用 mongodb 数据库,在koa2中使用 mongoose
这个库来管理整个数据库的操作。
1. 创建配置文件
根目录下新建 config 文件夹,新建 mongo.js
// 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中引入
const mongoConf = require('./config/mongo'); mongoConf.connect();
连接数据库完成!
2. Schema 和 Model
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文件夹下每一个文件都要注册成为一个路由
1. 基本结构
一个基本的, 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
2. 请求参数验证
任何一次请求接口传来的参数,首先要在最前面做一次参数验证。如果请求参数不合法,那么直接返回错误信息,无需继续走下面的业务逻辑。
参数验证,推荐使用 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文档
3. 数据库操作
之前已经创建了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
运行与部署
1. pm2
应用启动文件是 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的进程日志
2. nginx配置
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; } }
此时你可以上传你的应用了!
3. 快速上传源码
一般上传源码的时候,可能会用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
这样配置上传效率非常高,一起试试吧!
本文由 杨成功
原创,更多原创文章关注杨成功的全栈之路
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 接口高并发压测入门实战
- SpringBoot实现通用的接口参数校验,注解实战
- 实战使用 Arthas 排查生产问题:实例方法接口调用
- Python实战---制作专属有声小说(调用百度语音合成接口)
- 原 荐 下单接口调优实战,性能提高10倍
- 乐字节-Java8核心特性实战-接口默认方法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Machine Learning in Action
Peter Harrington / Manning Publications / 2012-4-19 / GBP 29.99
It's been said that data is the new "dirt"—the raw material from which and on which you build the structures of the modern world. And like dirt, data can seem like a limitless, undifferentiated mass. ......一起来看看 《Machine Learning in Action》 这本书的介绍吧!