最近一直在学习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 start

2.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 处理路由

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];

保存重启服务,在浏览器中访问,显示如下:

4 加载插件

一般在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,

};

8 测试

未完待续……

php hapijs,hapi 起步相关推荐

  1. laravel框架中文手册_node.js 后端框架star 排名 2020年11月更新,fastify 超 egg

    发布时间以首个版本发布(0.x)为准. 第一名: express 50.8k (2010年1月发布) 目前star 和下载量最高的老牌框架. https://github.com/expressjs/ ...

  2. node.js基于JavaScript语言新兴框架

    node.js基于JavaScript语言,不在单用学习一门新的语言,从而降低了陌生语言的门槛,同时js语言在web前端开发至关重要,特别HTML5必须使用,前后台语言统一,不仅可以实现程序员全栈开发 ...

  3. Node.js的Web后端开发调研

    1. nodejs写后端优缺点(讲解nodejs与js区别) 1.1 Node.js是什么 Node.js 是一个开源与跨平台的 JavaScript 运行时环境 在浏览器外运行 V8 JavaScr ...

  4. 搭建公众号自动回复功能

    程序员爱炫技,写个公众号文章,都想拿点技术整整[自动回复]:程序员爱偷懒,什么都想做个[自动化],最好所有事情系统都给做了,点点手指头就能达到目标. 今天的主角是如何搭建一个公众号自动回复功能.整个流 ...

  5. Hapi.js 起步 - 写给前端开发的 Node Web 框架入门

    为什么选择 Hapi 或许你已经使用过 Express, Koa2 等 Node.js 的 WEB 框架,在构建 WEB 应用程序时,你的工作仅仅是产出 RESTFUL API,或者通过 Node 调 ...

  6. hapi入门简介(入门实践)----净土小沙弥学hapi.js_第二篇

    编写前的准备 熟悉node语法,并且安装node和npm. 开始编写hapijs 1.在工作目录打开cmd(shift+鼠标右键->选择"在此处打开PowerShell窗口" ...

  7. HapiJS开发手册

    HapiJS开发手册 作者:chszs,转载需注明.博客主页: http://blog.csdn.net/chszs 一.HapiJS介绍 HapiJS是一个开源的.基于Node.js的应用框架,它适 ...

  8. 从试用到使用:计算机视觉产业新一轮发展的起步年

    参加 2018 AI开发者大会,请点击官网报名 CSDN 出品的<2018-2019 中国人工智能产业路线图>V2.0 版即将重磅面世! V1.0 版发布以来,我们有幸得到了诸多读者朋友及 ...

  9. react中试用leaflet简单起步

    写在最前边,前不久的一个项目中要做一个地图的数据可视化需求.项目中用到了 Leaflet.项目到现在功能已经基本实现,现在写下来做一下记录.Demo是用 create-react-app 搭建的.源码 ...

  10. ajax hapi上传文件,javascript – hapi.js Cors Pre-flight不返回Access-Control-Allow-Origin标头...

    我使用(Dropzone js)上传了ajax文件.它将文件发送到我的hapi服务器.我意识到浏览器发送了一个PREFLIGHT OPTIONS METHOD.但我的hapi服务器似乎没有发送正确的响 ...

最新文章

  1. ASP.NET中Web DataGrid的使用指南-转
  2. 5.计算机发展个人理解-电路终究是电路 软件如何控制硬件 代码如何操作硬件 硬件是怎么执行代码 代码如何执行 软件与硬件如何交互 计算机思维 抽象 封装 规范 屏蔽 协议分层...
  3. .NET系统学习----Globalization Resources
  4. python自动源码_谷歌推出Tangent开源库,在Python源代码上做自动微分
  5. 字典-字典的增删改查常用操作
  6. input发送a.jax_Java REST JAX-RS 2.0 –如何处理日期,时间和时间戳记数据类型
  7. java中程序执行顺序
  8. ‘cnpm‘ 不是内部或外部命令,也不是可运行的程序
  9. confirm + if 逻辑判断 -代码篇
  10. linux系统上tftp服务器的安装配置
  11. 一个斐波那契数列题 HDU 2041
  12. 2021-2025年中国乙酰丙酸乙酯行业市场供需与战略研究报告
  13. 【操作系统】实时调度
  14. 开关稳压集成电路电源
  15. ︰【】奥立诚生物科技 奥立诚生物科技研发的华龙6号蜈蚣 成养殖行业的亮点
  16. Array Shrinking(CodeForces - 1312E )
  17. 小兮码 linux版本,【图片】单字利器:二笔顶功——小兮码【输入法吧】_百度贴吧...
  18. 不想安装环境,我如何与前端工程师远程协作开发?
  19. 适合所有手环的app_一只手环就能指导运动?Keep 想做你手腕上的魔鬼教练
  20. matlab 更换坐标轴_matlab怎么调整坐标轴范围-Matlab修改坐标轴标注范围的方法 - 河东软件园...

热门文章

  1. D3D9学习笔记之基础几何体的深入应用(一)
  2. 纪念三毛辞世20周年——《三毛经典语录》
  3. java后端工程师主流技术
  4. PyCharm的Requirement already satisfied 解决方法
  5. repository ‘Gradle Libs‘ was added by unknown code
  6. 【产品】使用 Axure 做产品原型设计
  7. 深入理解Amazon Alexa Skill(一)
  8. vue-composition-api.mjs:1:7: ERROR: No matching export in “node_modules/vue/dist/vue.runtime.esm-bun
  9. MySQL中Index与Key的区别
  10. 扫雷游戏C语言编程实现