NodeJS + Hapi.js 开发接口实践

836 阅读2分钟

「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战

前言

Hapi 是一个强大且健壮的框架,用于开发API。完善的插件系统和各种关键功能(例如输入验证、基于配置的功能、实现缓存、错误处理、日志记录等。
大家应该都使用过Express, Koa2 等 Node.js 的 WEB 框架,这类框架也可以用来开发API,但是跟这些框架相比 Hapi 是基础功能相对丰富的框架。开发人员更专注于业务,而不是花时间构建基础架构。配置驱动的模式,区别于传统的web服务器操作。

创建项目

  • 安装 node
  • 创建项目
  • 初始化 package.json 首先我们先安装 Hapi
npm i hapi

在根目录下创建一个server.js 文件

// server.js
const Hapi = require('hapi')

const server = Hapi.server({
    port: 3000,
    host: 'localhost'
})

const init = async () => {
    await server.start()
    console.log(`Server running at: ${server.info.uri}`)
}
init()

通过命令行 node server 就可以开启一个端口 3000 的服务

开发接口

增加一个路由

server.route({
    path: '/',
    method: 'GET',
    handler () {
      return 'Hapi world'
    }
})

浏览器打开 http://localhost:3000/ 你会看到一个 Hapi world

增加接口

// server.js
const init = async () => {
    server.route({
      path: '/api/hello',
      method: 'GET',
      handler () {
        return {
          code: 200,
          success: true,
          data: {
            msg: 'hello'
          }
        }
      }
    })
    await server.start()
    console.log(`Server running at: ${server.info.uri}`)
}

我们使用 Postman 请求 /api/hello 接口就可以进行测试了。

获取参数和Cookie

handler 会返回一个request 的参数,通过这个参数可以获取到客户端传递的参数

server.route({
  path: '/api/hello',
  method: 'GET',
  handler (request) {
    return {
      code: 200,
      success: true,
      data: request.query
    }
  }
})

客户端传什么参数,我直接返回给他。 request 还能通过request.state获取到请求头上的Cookie

配置

可能有些同学说,按照上面的步骤调用接口后会返回{"statusCode":400,"error":"Bad Request","message":"Invalid cookie value"}出现这种情况的话我们需要加个配置参数

const server = Hapi.server({
  port: 3000,
  host: '0.0.0.0',
  state: {
    strictHeader: false
  }
})

有时候我们需要跨域请求,可以在配置中增加 cors 属性

const server = Hapi.server({
  port: 3000,
  host: '0.0.0.0',
  state: {
    strictHeader: false
  },
  routes: {
    cors: {
        origin: ['*']
    }
  }
})

日志

日志对我来说是非常重要的,我们可以通过日志来记录接口请求的状态,所以我们需要加入日志系统。
安装 hapi-pinopino-pretty

npm i hapi-pino pino-pretty

注册

await server.register({
    plugin: require('hapi-pino'),
    options: {
        prettyPrint: true // 格式化输出
    }
})

请求接口时终端会打印出日志信息

[1642412649767] INFO (4143 on huangjianfengdeMacBook-Pro.local): request completed
    req: {
      "id": "1642412649765:huangjianfengdeMacBook-Pro.local:4143:kyii1nvv:10001",
      "method": "get",
      "url": "/api/hello",
      "headers": {
        "user-agent": "PostmanRuntime/7.28.4",
        "accept": "*/*",
        "cache-control": "no-cache",
        "postman-token": "c6ccd274-afff-47bd-a8b8-d7f27b23d02f",
        "host": "localhost:3000",
        "accept-encoding": "gzip, deflate, br",
        "connection": "keep-alive",
        "content-type": "application/x-www-form-urlencoded",
        "content-length": "24"
      },
      "remoteAddress": "127.0.0.1",
      "remotePort": 61608
    }
    res: {
      "statusCode": 200,
      "headers": {
        "content-type": "application/json; charset=utf-8",
        "vary": "origin",
        "access-control-expose-headers": "WWW-Authenticate,Server-Authorization",
        "cache-control": "no-cache",
        "content-length": 47,
        "accept-ranges": "bytes",
        "connection": "close"
      }
    }
    responseTime: 2
}

这样就很方便调试了