使用 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
這樣配置上傳效率很是高,一塊兒試試吧!
本文由
楊成功
原創,更多原創文章關注
楊成功的全棧之路