摘要:最近一直在學習,有點的基礎以為會容易呢,但是全英文的,不同于的實現方式,看起來大寫的懵啊,整理此文,希望能夠幫助到一些想要入門的新人。,項目啟動成功。若要在路徑中命名參數,只需用將其包裝。
最近一直在學習hapiJs,有點koa2的基礎以為會容易呢,但是全英文的API,不同于koa2的實現方式,看起來大寫的懵啊,整理此文,希望能夠幫助到一些想要入門hapi的新人。
1、搭建項目1.1 首先我們創建一個目錄‘hapiDemo’作為項目目錄,輸入命令:
makdir hapiDemo。
1.2 打開項目目錄,初始化,命令如下:
cd hapiDemo, 初始化:npm init,
1.3 項目基礎配置:
安裝hapi: npm install --save hapi;
項目使用了ES6語法安裝babel: npm intall --save hapi;
npm start默認是的啟動文件是sever.js,本項目是index.js,修改啟動命令,
下文中還是用了一些插件,請自行安裝。
1.4 初始化并安裝hapi是第一步,hapiDemo 項目的基礎項目結構如下圖:
這些文件的作用是:
config:配置文件目錄,db_config:數據庫的配置信息,plugin_config:注冊插件的相關信息
controllers:controllers下是業務邏輯
models:model 層
public:靜態文件
routes:路由信息
log:日志信息
index.js:項目啟動入口文件
server.js:服務配置信息
2、hapi start2.1 創建啟動服務配置文件server.js,輸入一下代碼:
const Hapi = require("hapi"); //Create a hapi server var server = new Hapi.Server(); /**************server config********/ let connectionOptions={ port: 3333, host: "localhost" }; server.connection(connectionOptions); // Export the server to be required elsewhere. module.exports = server;
2.2 配置完服務文件,現在我們來啟動服務,先新建一個index.js文件:
const server=require("./server"); server.start(err=>{ if(err) throw err; console.log( `Server running at: ${server.info.uri}`); }); 輸入node啟動命令:npm start 將會顯示:Server running at: http://localhost:3333。OK,項目啟動成功。 我們在瀏覽器中輸入url:http://localhost:3333,
找不到路由。
3.1 將路由文件放在routes文件夾里,我們將創建多個路由,分模塊創建,首先修改server.js文件,新增如下代碼:
const route=require("./routes"); // Add the server routes route.forEach(function(api){ server.route(api); });
在routes新建index.js,每新增一個路由文件,在index.js文件中引入。
module.exports=[ require(__dirname+"/helloWorld.js"), require(__dirname+"/login.js"), require(__dirname+"/file.js"), require(__dirname+"/auth.js") ]
3.2 定義路由需要三個基礎元素:path,method,handler。Methods的選項可以是任何有效的HTTP方法,也可以是方法數組。path選項必須是字符串,盡管它可以包含命名參數。若要在路徑中命名參數,只需用{ }將其包裝。handler選項是一個函數,它接受兩個參數:request和request。
在routes里新建一個helloWorld.js:
let index={ method: "GET", path: "/", handler: function(request, reply){ reply("hello,world"); } }; let hello={ method: ["GET", "POST"], path: "/hello/{user?}", handler: function (request, reply) { reply("Hello " + encodeURIComponent(request.params.user) + "!"); } }; module.exports=[index,hello];
保存重啟服務,在瀏覽器中訪問,顯示如下:
更多用法請查看api:https://hapijs.com/api#route-...
一般在nodeJS中,我們加載一個插件,安裝后使用require 插件名稱就OK了,但是在hapiJS中,需要通過server.register()方法引入。
以下文中使用處理靜態文件的插件 inert 舉例:
server.register(require("inert"), (err) => { if (err) { console.error("Failed to load a plugin:", err); } });
但不是所有的插件都需要使用server.register()引入,直接使用require即可。
為什么使用server.register()引用,我至今不是很清楚。
在本項目中,我把所有的插架配置放在了config/plugin_config.js中:
const SwaggerOptions = { info: { "title": "hapiDemo API Documentation", "version": "0.0.1" } }; const goodOptions = { ops: { interval: 1000 }, reporters: { myConsoleReporter: [{ module: "good-squeeze", name: "Squeeze", args: [{ log: "*", response: "*" }] }, { module: "good-console" }, "stdout"], myFileReporter: [{ module: "good-squeeze", name: "Squeeze", args: [{ log: "*", response: "*" ,request:"*"}] }, { module: "good-squeeze", name: "SafeJson" }, { module: "good-file", args: ["./log/fixtures/awesome_log"] }], myHTTPReporter: [{ module: "good-squeeze", name: "Squeeze", args: [{ error: "*" }] }, { module: "good-http", args: ["http://prod.logs:3000", { wreck: { headers: { "x-api-key": 12345 } } }] }] } }; module.exports = [ { register:require("good"), goodOptions, }, { register:require("hapi-auth-jwt2") }, { register:require("inert") }, { register:require("hapi-auth-basic") }, { register:require("./../auth") }, { "register": require("hapi-swagger"), "options": SwaggerOptions }, { register:require("vision") } ];
在server.js中:
const plugins=require("./config/plugin_config"); //Register all plugins server.register(plugins, function (err) { if (err) { throw err; // something bad happened loading a plugin } });5 渲染靜態文件和視圖
5.1 在Web應用程序中,不可避免地,需要提供一個簡單的文件,圖片或者靜態html。在hapi 中使用 inert 插件來處理靜態文件。
npm install --save inert
在routes文件夾中創建一個file.js:
let static={ method: "GET", path: "/staticFile", handler: function (request, reply) { reply.file("./public/static.html"); } }; module.exports=static;
在public文件夾下新增一個static.html的文件,內容隨意。保存然后運行。
5.2 hapi 可以使用模板渲染,hapi默認使用的是handlebars,要開始視圖,首先我們必須在服務器上配置至少一個模板引擎。這是通過使用server.views方法做的,修改server.js文件:
server.register(plugins, function (err) { server.views({ engines: { "html": { module: require("handlebars") } }, relativeTo:__dirname, path:"public/templates" }); if (err) { throw err; // something bad happened loading a plugin } });
加載 vision 插件,它增加了模板渲染支持哈啤。
更多配置項:https://hapijs.com/tutorials/...
渲染勢圖,在file.js文件中新增路由:
let temp={ method: "GET", path: "/view", config: { auth: false, handler: function (request, reply) { reply.view("login"); } } }; module.exports=[static,temp];
login的內容自行填充
6 訪問數據庫在web應用程序中,我們可能寫特別多數據庫訪問層的代碼,數據庫保存,刪除,讀取,那hapi如何訪問數據庫呢?本demo以MySQL為例。
不懂數據庫的程序員不是好程序員,但是我早早就把數據庫的一點皮毛還給了老師,我選擇Node的ORM框架Sequelize來操作數據庫。
hapi-sequelize插件對sequelize做了很簡單的封裝,但是它對Hapi和sequelize的版本有要求,在本項目中沒有使用,有興趣的的可以研究 https://github.com/danecando/...
6.1 在server.js添加代碼:
const models=require("./models"); //Connect database var initDb = function(){ var sequelize = models.sequelize; //Determine if the database connection is successful sequelize.sync({force: false}).then(function() { console.log("connection successed"); }).catch(function(err){ console.log("connection failed due to error: %s", err); }); }; initDb();
6.2 使用Sequelize操作MySQL需要先做兩件準備工作,
(1)創建一個sequelize對象實例,連接數據庫,在models新增index.js,代碼如下:
const fs = require("fs"); const path = require("path"); const Sequelize = require("sequelize"); const config = require("../config/db_config"); let db = {}; //創建一個sequelize對象實例,連接數據庫 let sequelize = new Sequelize(config.database, config.username, config.password,{ host: config.host, dialect: "mysql", pool: { max: 5, min: 0, idle: 30000 } }); fs .readdirSync(__dirname) .filter(function(file) { return (file.indexOf(".") !== 0) && (file !== "index.js"); }) .forEach(function(file) { var model = sequelize["import"](path.join(__dirname, file)); db[model.name] = model; }); db.sequelize = sequelize; db.Sequelize = Sequelize; module.exports = db;
db_config文件是數據庫的配置信息。
(2)定義模型文件user(在本項目中主要是實現登陸),告訴Sequelize如何映射數據庫表。
module.exports = function(sequelize, DataTypes) { var User = sequelize.define("User", { id:{ type: DataTypes.INTEGER, primaryKey: true }, user_no:DataTypes.STRING, old_kn_userid:DataTypes.STRING, nickname:DataTypes.STRING, password:DataTypes.STRING, }, { freezeTableName: true, // Model 對應的表名將與model名相同 timestamps: false }); return User; };
更多Sequelize的學習可以參考:https://itbilu.com/nodejs/npm...
6.3 經過配置后,接下來我們可以在路由handler中使用這個實例啦。
新建一個login.js:
const Joi=require("joi"); const controllers=require("../controllers"); let login2={ method: "get", path: "/tologin2", config: { validate:{ query: { nickname:Joi.min(6).max(30)required(),//校驗 } }, id: "login2" }, handler: controllers.user.login2, }; module.exports=login2;
joi 是 hapijs 自帶的數據校驗模塊,他已經高度封裝常用的校驗功能,更多用法:https://github.com/hapijs/joi...。
6.4 接下來我們就要訪問數據庫啦。
(1)新建index.js
const requireDirectory = require("require-directory"); module.exports = requireDirectory(module);
require-directory的作用是遞歸遍歷指定目錄,require()每個文件,并返回一個包含這些模塊嵌套的hash結構。
(2)user.js:
let models=require("../models") module.exports={ login2:function(request,reply){ let userInfo=models.User.findOne({ where:{ nickname: request.query.nickname } }).then(function(result){ let reponseMess={}; if(result!==null){ reponseMess={ code:1, message:"已經在數據庫中查詢到" } }else{ reponseMess={ code:-1, message:"未已經在數據庫中查詢到" } } reply(reponseMess); }); } };
簡單的demo查詢,用戶是否已存在
7 自動生成swagger文檔使用hapi寫api時,有種代碼既文檔的感覺,而且這些代碼也真的可以自動生成swagger文檔。
使用hapi插件hapi-swagger,簡單配置下插件,先修改下plugin_config.js文件:
const SwaggerOptions = { info: { "title": "hapiDemo API Documentation", "version": "0.0.1" } }; module.exports = [ { "register": require("hapi-swagger"), "options": SwaggerOptions }, ];
然后修改/tologin2:
let login2={ method: "get", path: "/tologin2", config: { auth:false, description: "Routing with parameters", notes: "login api", tags: ["api"],//寫上這句,開啟生成swagger功能 validate:{ query: { nickname:Joi.required(), } }, id: "login2" }, handler: controllers.user.login2, };
運行,打開 http://localhost:3333/documen...
8 測試未完待續……
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/87111.html
摘要:里面的驗證是基于和這兩個概念的。另一方面,是一個預先配置的命名的實例。注冊了一個插件該插件創建了一個命名為的。執行上述文件,訪問。在彈出的登錄框中輸入用戶名及密碼,頁面將展示如果報錯,可使用模塊替代,其余代碼無需改變。 hapi里面的Authentication(驗證)是基于scheme和strategies這兩個概念的。你可以把scheme理解為一個通用型的驗證,是那種基礎的,概要的...
摘要:框架,用官網的簡介來說就是是構建應用程序和服務的豐富框架,它使開發人員能夠專注于編寫可重用的應用程序邏輯,而不是花時間構建基礎設施。用自己的話簡單來說,就是個類似,之類的服務基礎框架。同時全局環境直接獲取。 showImg(https://segmentfault.com/img/bVbrV3m?w=572&h=350); hapi框架,用官網的簡介來說就是:Hapi是構建應用程序和...
摘要:框架,用官網的簡介來說就是是構建應用程序和服務的豐富框架,它使開發人員能夠專注于編寫可重用的應用程序邏輯,而不是花時間構建基礎設施。用自己的話簡單來說,就是個類似,之類的服務基礎框架。 showImg(https://segmentfault.com/img/bVbrV3m?w=572&h=350); hapi框架,用官網的簡介來說就是:Hapi是構建應用程序和服務的豐富框架,它使開...
閱讀 2169·2021-11-11 16:55
閱讀 1692·2019-08-30 15:54
閱讀 2822·2019-08-30 15:53
閱讀 2216·2019-08-30 15:44
閱讀 1156·2019-08-30 15:43
閱讀 970·2019-08-30 11:22
閱讀 1947·2019-08-29 17:20
閱讀 1572·2019-08-29 16:56