請按照官方文檔初始化一個simple工程項目,按照以下步驟學習便可,若有不懂的請參考官方文檔。node
根據以下步驟進行控制的建立,在執行Post操做的時候會出現invalid csrf token錯誤。須要禁止此特性。git
/** * @param {Egg.Application} app - egg application */ module.exports = app => { const { router, controller, } = app; router.get('/', controller.home.index); // 新建資源路由 router.resources('SystemUser', '/system/user', controller.system.user); };
控制器controller.system.user,對應的是controller目錄下的system目錄裏面的user.js文件github
const Controller = require('egg').Controller; class SystemUserController extends Controller { async index() { const { ctx, } = this; ctx.body = 'hello ! this is SystemUserController'; } } module.exports = SystemUserController;
訪問地址:localhost:7001/system/usernpm
const Controller = require('egg').Controller; class SystemUserController extends Controller { async index() { const { ctx, } = this; ctx.body = 'hello ! this is SystemUserController'; } async create() { const ctx = this.ctx; const user = ctx.request.body; ctx.body = user; } } module.exports = SystemUserController;
POST方法訪問網址:localhost:7001/system/user 會提示invalid csrf token錯誤。api
// config\config.default.js // 關閉csrf驗證 config.security = { csrf: { enable: false, }, };
在上面的例子中,咱們經過表單提交了任何數據,都會回顯到界面上,若是是數據須要存儲或者作其餘業務處理,則須要對用戶輸入的數據進行驗證。
egg提供了egg-validate插件進行表單驗證數據結構
cnpm install egg-validate --save
/** @type Egg.EggPlugin */ module.exports = { // had enabled by egg // static: { // enable: true, // } validate: { enable: true, package: 'egg-validate', }, };
首先建立一個規則,這裏咱們定義username是字符串並且是必須的,最大長度爲8個字符。
定義password爲字符串且必須,最小長度爲6個字符。
ctx.validate(createRule, ctx.request.body);
經過上述語句進行參數檢查
更多規則請參考:https://github.com/node-modul...app
const Controller = require('egg').Controller; // 定義本接口的請求參數的驗證規則 const createRule = { username: { type: 'string', required: true, max: 8, }, password: { type: 'string', required: true, min: 6, }, }; class SystemUserController extends Controller { async index() { const { ctx, } = this; ctx.body = 'hello ! this is SystemUserController'; } async create() { const ctx = this.ctx; // 驗證輸入參數是否符合預期格式 ctx.validate(createRule, ctx.request.body); const user = ctx.request.body; ctx.body = user; } } module.exports = SystemUserController;
使用POSTMAN提交任意字段,則會提示Validation Failed (code: invalid_param)
如何查看具體錯誤信息呢。下面將定義統一錯誤處理的中間件進行錯誤處理。框架
在項目的app目錄中建立middleware目錄,此目錄中能夠建立中間件。async
'use strict'; module.exports = () => { return async function errorHandler(ctx, next) { try { await next(); } catch (err) { // 控制檯輸出 console.error('MiddleWare errorHandler', err); // 全部的異常都在 app 上觸發一個 error 事件,框架會記錄一條錯誤日誌 ctx.app.emit('error', err, ctx); // status 若是沒有,則統一爲500 const status = err.status || 500; // 若是是500錯誤,且是生產環境,則統一顯示「Internal Server Error」 const error = status === 500 && ctx.app.config.env === 'prod' ? 'Internal Server Error' : err; // 改變上下文狀態代碼 ctx.status = status; // 從 error 對象上讀出各個屬性,設置到響應中 ctx.body = { error, }; } }; };
文件configconfig.default.js中學習
// add your middleware config here config.middleware = [];
將其修改成包含你建立的中間件
// add your middleware config here // errorHandler 統一錯誤處理 config.middleware = [ 'errorHandler' ]; // errorHandler 只在/api上生效 config.errorHandler = { match: '/api', };
如上所示,能夠設置錯誤處理中間件在什麼URL上面起做用。這裏咱們使用/api
先使用原來的路由訪問:localhost:7001/system/user
錯誤提示依舊
變動路由:打開文件:approuter.js
// router.resources('SystemUser', '/system/user', controller.system.user); router.resources('SystemUser', '/api/v1/system/user', controller.system.user);
再次訪問:localhost:7001/api/v1/system/user
提示信息會變成:
{"error":{"message":"Validation Failed","code":"invalid_param","errors":[{"message":"required","field":"username","code":"missing_field"},{"message":"required","field":"password","code":"missing_field"}]}}
在上面顯示錯誤信息中,能夠看到規範的Json數據,若是開發接口,咱們就須要定義統一的數據結構,以便客戶端進行解析。
在API開發中,能夠定義接口的標準返回格式。經過框架擴展方式定義返回數據格式是一個很是方便的方法。
在app目錄中建立extend目錄,對egg的內置對象Helper進行擴展便可。
文件:app/extend/helper.js
'use strict'; module.exports = { /** * 調用正常狀況的返回數據封裝 * @param {Object} ctx - context * @param {*} msg - message * @param {*} data - 數據 */ success(ctx, msg, data) { ctx.body = { code: 0, msg, data, }; ctx.status = 200; }, /** * 處理失敗,處理傳入的失敗緣由 * @param {*} ctx - context * @param {Object} res - 返回的狀態數據 */ fail(ctx, res) { ctx.body = { code: res.code, msg: res.msg, data: res.data, }; ctx.status = 200; }, };
// 從 error 對象上讀出各個屬性,設置到響應中 // ctx.body = { // error, // }; // 格式化返回錯誤信息 ctx.helper.fail(ctx, { code: status, msg: error.message, data: error.errors, });
再次訪問:localhost:7001/api/v1/system/user
提示信息會變成:
{ "code": 422, "msg": "Validation Failed", "data": [ { "message": "required", "field": "username", "code": "missing_field" }, { "message": "required", "field": "password", "code": "missing_field" } ] }
async create() { const ctx = this.ctx; // 驗證輸入參數是否符合預期格式 ctx.validate(createRule, ctx.request.body); const user = ctx.request.body; // ctx.body = user; this.ctx.helper.success(this.ctx, 'ok', user); }
提交知足要求的數據,測試正確的返回數據
username testuser
password 1234567890
提交後將返回標準的數據格式
{ "code": 0, "msg": "ok", "data": { "username": "testuser", "password": "1234567890" } }