【问题标题】:How to call other REST APIs from your node micro-service and send the result as a response?如何从您的节点微服务调用其他 REST API 并将结果作为响应发送?
【发布时间】:2017-12-11 10:01:09
【问题描述】:

我目前正在尝试实现 BFF(前端架构的后端)。

使用request-promise 库我可以成功命中其他微服务,但无法将结果作为 BFF 微服务的响应返回。

每次它返回这个结果 Promise { pending } 挂起状态,有人可以帮我解决这个问题吗?

我的主要问题是知道如何从我们正在命中的另一个微服务将数据接收到 BFF 微服务中,并从正在命中另一个微服务的微服务返回结果。

或者如果有人可以帮助我知道如何从任何承诺的.then 内部访问结果?

流程是这样的:

client(ios/android)===(sends request)==>BFF Microservice==>BP microservice

(BFF 微服务处理请求并根据从其他微服务收到的结果返回响应)

调用另一个微服务的微服务代码:

import yagmodel from '../../lib/models/yag-model'
import {errorsList} from '../../lib/errors/errorsList'
import request from 'request-promise'
import config from 'config'

//template below to call the REST APIs of other microservices.

export async function getAllBP (req,res) {
    let yagresponse// this varaible is defined to get data from inside(rs.then )

    const username= req.swagger.params.username.value
    const authheader= req.swagger.params.Authorization.value
    console.log("Authorization:"+authheader)

    let rs= await yagmodel.bp(username,authheader)
    console.log(rs)

    rs.then((response)=>{
        // console.log(response.body)
        yagresponse=response.body
        //console.log(rsp)
    }).catch((err)=>{
        console.log(err)
        console.log('errorstatuscode:'+err.statusCode)
    })

    res.status(200).send(yagresponse) 
}

yag-model.js代码:

import {errorsList} from '../../lib/errors/errorsList'
import request from 'request-promise'

module.exports.bp = async function getBP(username,authheader){
    const options={
        uri: `http://localhost:4000/Health/BP/`+username,
        json: true,
        resolveWithFullResponse: true,
        headers: {
            'Content-Type': 'application/json; charset=utf-8',
            'Accept': 'application/json; charset=utf-8',
            'Authorization':authheader
        },
        method: 'GET'
    }

    return request(options).then ((response)=>{
        return response.body        
    }).catch((err)=>{
        console.log(err)
        console.log('errorstatuscode:'+err.statusCode)
    })
}

【问题讨论】:

    标签: node.js backend microservices es6-promise request-promise


    【解决方案1】:

    当你只能使用 await 时,我认为你可以将 await 运算符与 Promise 混合使用。

    我创建了您的代码的简化版本:

    yag-model.js

    const request = require('request-promise');
    
    module.exports.bp = async function getBP () {
    
        const options = {
    
            uri: `https://api.postcodes.io/random/postcodes`,
            json: true,
            resolveWithFullResponse: true,
            method: 'GET'
        };
    
        return request(options).then((response) => {
    
            return response.body
    
        }).catch((err) => {
            console.log(err);
            console.log('errorstatuscode:' + err.statusCode)
        })
    };

    示例中的 usgae bf.js

    const yagmodel = require('./yag-model');
    
    async function getAll(){
        const result = await yagmodel.bp();
        console.log(result);
    };
    
    getAll();

    结果是我的控制台上的响应。

    F:\Projekty\Learn\lear-node>node bf
    { status: 200,
    result:
     { postcode: 'BH23 5DA',
       quality: 1,
       eastings: 420912,
    

    我建议查看来自 Axel Rauschmayer 博士的关于 asunc 函数 http://exploringjs.com/es2016-es2017/ch_async-functions.html 的精彩资源

    【讨论】:

    • 感谢 Lukasz 分享了这篇很棒的文章,它确实帮助我提高了知识并理清了概念,你们真的拯救了我在办公室的一天 :)
    【解决方案2】:

    请不要混淆从 request-promise 和异步函数返回的承诺。 异步函数可以等待来获得已解决的承诺并使您的代码看起来不错。

    我相信让人们解决他们自己的问题,并引导他们一路走来,这样只是为了确保你没有从你的这行中的已解决承诺中获得回报:

    console.log(rs)
    

    此外,通过查看您的 sn-p,您将从 request-promise 的 thenable 中返回一个 response.body。您无法从响应正文中捕获任何响应错误,对吧?

    我强烈建议您遵循一种模式,在这种模式下,您将捕获错误(应该在哪里)并在您这样做时显示正确的消息。将您的 await 调用包装在 try/catch 中可以帮助从 request-promise 中捕获未捕获的错误。

    和平!

    【讨论】:

    • 感谢您的洞察力 Hawkes,它终于工作了“让 rs=await yagmodel.bp(username,authheader)”本身从 BP 微服务返回预期的 JSON 对象结果,我不需要处理这个在我的控制器文件中再次承诺。 Łukasz Szewczak 在他的回答中也提到了同样的事情。再次感谢你们分享知识和澄清概念,你们真的拯救了我在办公室的一天。
    • @GautamMalik:如果您觉得有用,请接受答案!
    【解决方案3】:

    你有两个 promise,那么你可以使用两个 await 来解决它们。

    export async function getAllBP (req,res) {
        let yagresponse// this varaible is defined to get data from inside(rs.then )
    
        const username= req.swagger.params.username.value
        const authheader= req.swagger.params.Authorization.value
        console.log("Authorization:"+authheader)
    
        let rs= await yagmodel.bp(username,authheader)
        console.log(rs)
    
        let response= await rs()
    
        res.status(200).send(response);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-31
      • 1970-01-01
      • 2019-08-27
      • 2016-03-27
      • 2020-11-03
      • 1970-01-01
      • 2022-01-01
      相关资源
      最近更新 更多