【问题标题】:How to use hapi js on Firebase Cloud Function?如何在 Firebase Cloud Function 上使用 hapi js?
【发布时间】:2019-11-06 12:36:57
【问题描述】:

我尝试向 an example 学习如何在 firebase 上使用 express 和车把。

对于express的方式,我们可以直接将“app”实例发送到“functions.https.onRequest”之类的......

const app = express();
...
app.get('/', (req, res) => {
    ...
});

exports.app = functions.https.onRequest(app);

See live functions

据我了解,它之所以有效,是因为“express”的行为类似于 http-node,因此它可以响应“http plain”。

hapi 相比,这里是 hello-world

const Hapi = require('hapi');
const server = new Hapi.Server();
server.connection({ 
    host: 'localhost', 
    port: 8000 
});

server.route({
    method: 'GET',
    path:'/hello', 
    handler: function (request, reply) {
        return reply('hello world');
    }
});

server.start((err) => {
    console.log('Server running at:', server.info.uri);
});

从 hapi 示例中,是否可以在 firebase 云功能上使用 hapi?

我可以在不启动 express 之类的服务器的情况下使用 hapi 吗?

【问题讨论】:

  • 你应该使用 hapi 或 express 与火基地。 Fire base Handels 为您路由,因此不需要路由框架。保持你的函数重量轻。如果你想渲染车把模板只需要车把。

标签: javascript node.js express firebase hapijs


【解决方案1】:

由于@dkolba 先生提供的博客,我将 Firebase 使用的 express API 与 hapijs API 混合在一起,因此代码很简单 您可以通过访问来调用 url hapijs 处理程序 http://localhost:5000/your-app-name/some-location/v1/hi

示例:http://localhost:5000/helloworld/us-central1/v1/hi

const Hapi = require('hapi');
const server = new Hapi.Server();
const functions = require('firebase-functions');

server.connection();

const options = {
    ops: {
        interval: 1000
    },
    reporters: {
        myConsoleReporter: [{
            module: 'good-squeeze',
            name: 'Squeeze',
            args: [{ log: '*', response: '*' }]
        }, {
            module: 'good-console'
        }, 'stdout']
     }
};

server.route({
    method: 'GET',
    path: '/hi',
    handler: function (request, reply) {
        reply({data:'helloworld'});
    }
});
server.register({
    register: require('good'),
    options,
}, (err) => {

    if (err) {
        return console.error(err);
    }

});



// Create and Deploy Your First Cloud Functions
// https://firebase.google.com/docs/functions/write-firebase-functions
exports.v1 = functions.https.onRequest((event, resp) => {
    const options = {
        method: event.httpMethod,
        url: event.path,
        payload: event.body,
        headers: event.headers,
        validate: false
    };
    console.log(options);
    server.inject(options, function (res) {
        const response = {
            statusCode: res.statusCode,
            body: res.result
        };
        resp.status(res.statusCode).send(res.result);
    });
    //resp.send("Hellworld");

});

【讨论】:

    【解决方案2】:

    看一下注入方法(最后一个代码示例):http://www.carbonatethis.com/hosting-a-serverless-hapi-js-api-with-aws-lambda/

    但是,我认为这是不可行的,因为您仍然需要保留快速应用实例的响应对象 Google Cloud Functions 提供给 http 触发函数,因为只有 @ 987654323@、redirect()end() 将用于响应传入的请求,而不是 hapi 的方法(请参阅https://firebase.google.com/docs/functions/http-events)。

    【讨论】:

      【解决方案3】:

      需要进行一些更改才能与 hapijs 18.x.x 兼容

      'use strict';
      
      const Hapi = require('@hapi/hapi')
      , functions = require('firebase-functions');
      
      const server = Hapi.server({
        routes: {cors: true},
      });
      
      server.register([ 
        {
          plugin: require('./src/plugins/tools'),
          routes: {
            prefix: '/tools'
          }
        }, 
      ]);
      
      server.route({
        method: 'GET',
        path: '/',
        handler: (request, h) => {
      
          return 'It worlks!';
        }
      });
      
      exports.v1 = functions.https.onRequest((event, resp) => {
        //resp: express.Response
      
        const options = {
          method: event.httpMethod,
          headers: event.headers,
          url: event.path,
          payload: event.body
        };
      
        return server
          .inject(options)
          .then(response => {
            delete response.headers['content-encoding']
            delete response.headers['transfer-encoding']
            response.headers['x-powered-by'] = 'hapijs'
            resp.set(response.headers);
            return resp.status(response.statusCode).send(response.result);
          })
          .catch(error => resp.status(500).send(error.message || "unknown error"));
      });
      

      【讨论】:

      • 为什么要删除上面的两个表头并添加新表头?
      • 为了防止双重gzip编码被应用到我们的响应中
      猜你喜欢
      • 2018-09-09
      • 2018-01-24
      • 2021-11-24
      • 1970-01-01
      • 2021-01-06
      • 2020-10-26
      • 1970-01-01
      • 2018-10-01
      相关资源
      最近更新 更多