简体   繁体   English

如何使用 Node 将数据从一个 API 请求传递到另一个请求

[英]How to pass data from one API request to another with Node

I have a working sample however I am sure it can be refactored for improvement.我有一个工作示例,但我相信它可以重构以进行改进。 The project is a Weather app built with React, Node/Express and OpenWeather API .该项目是一个使用 React、Node/Express 和OpenWeather API构建的天气应用程序。 Basically the lat and lon values from first API response are needed as params in second API request.基本上,第一个 API 响应中的latlon值需要作为第二个 API 请求中的参数。 Reason for having Node server is to hide API key in browser.使用 Node 服务器的原因是在浏览器中隐藏 API 键。 :) :)

Here is a breakdown of folder structure(only includes relevant files):这是文件夹结构的细分(仅包括相关文件):

weather-app/天气应用/
... ...
src/来源/
hooks/挂钩/
useForecast.js使用预测.js
... ...
index.js索引.js
routes/路线/
weather.js天气.js
onecall.js onecall.js

Here are the breakdown of each file(only includes relevant codes):以下是每个文件的细目(仅包括相关代码):

index.js(express entry file): index.js(快速入口文件):

app.use('/weather', require('./routes/weather'))
app.use('/onecall', require('./routes/onecall'))

weather.js(1st API call): weather.js(第一个 API 电话):

router.get('/', async (req, res, next) => { 
  try {
    const params = new URLSearchParams({
      ...url.parse(req.url, true).query, //location value from useForecast.js 
      appid: API_KEY
    })

    const apiRes = await needle('get', `${BASE_URL}/weather?${params}`) //api.openweathermap.org/data/2.5/weather?q=somecity&appid={API_KEY}
    const data = apiRes.body //data will be used in useForecast.js

    res.status(200).json(data)
  } catch(error) {
    next(error)
  }
}) 

onecall.js(2nd API call): onecall.js(第二次 API 通话):

router.get('/', async (req, res, next) => {
  try {
    const params = new URLSearchParams({
      ...url.parse(req.url, true).query, //lat and lat value from useForecast.js
      appid: API_KEY 
    })

    const apiRes = await needle('get', `${BASE_URL}/onecall?${params}`) //api.openweathermap.org/data/2.5/onecall?lat={lat}&lon={lon}&appid={API_KEY}
    const data = apiRes.body //data will be used in useForecast.js

    res.status(200).json(data)
  } catch (error) {
    next(error)
  }
})

useForecast.js(hook call from React): useForecast.js(来自 React 的挂钩调用):

const useForecast = () => {
  ...    
  const getCoordinates = async location => {   
    const { data } = await axios(`/weather?q=${location.value}`) //url from weather.js

    if(data.cod === '404' || !data) {
      setError(data.message)
      setLoading(false)
      return
    }

    return data
  }

  const getForecastData = async (lat, lon) => {
    const { data } = await axios(`/onecall?lat=${lat}&lon=${lon}`) //url from onecall.js

    if(data.cod === '400' || !data) {
      setError('something went wrong')
      setLoading(false)
      return
    }

    return data
  }     
 ... 
}  

Can both calls in weather.js and onecall.js be refactored and combined into one? weather.jsonecall.js中的调用都可以重构合并为一个吗? If so would changes in useForecast.js have to be made also?如果是这样,还必须对useForecast.js进行更改吗?

Thanks in advance!!!提前致谢!!!

Yes, you can do it using a architecture pattern similar to MVC or MVCS是的,您可以使用类似于MVCMVCS的架构模式来实现

MVCS MVCS

Used in server side rendering applications or in a simple terms: used in previous generation webs (java, python, php, etc) .用于服务器端渲染应用程序或简单来说:用于上一代网络(java、python、php 等) Modern webs(react, angular, vue, etc) don't use this.现代网络(react、angular、vue 等)不使用它。 Basically in this pattern you have this structure:基本上在这种模式中你有这样的结构:

在此处输入图像描述

  • V means View : html, templates, etc V 表示视图:html、模板等
  • C means Controller : server side in charge of return just data like json,xml,etc or view merged it with data ( https://expressjs.com/en/resources/template-engines.html ) C 表示Controller :服务器端负责返回数据,如 json、xml 等,或查看将其与数据合并 ( https://expressjs.com/en/resources/template-engines.8841064 )65788
  • S means Service : implements the logic. S 表示服务:实现逻辑。 Controller uses one of several services to orchestrate the operation Controller 使用几种服务之一来编排操作
  • M means Model : abstraction of the database or datasource to be read or write. M 表示Model :要读取或写入的数据库或数据源的抽象。

MSR MSR

I don't know if I'm creating this, but is the same as MVCS but for apis or microservices in which views or pages don't exist:我不知道我是否正在创建它,但它与 MVCS 相同,但对于不存在视图或页面的 api 或微服务:

  • R means Rest controller . R 表示Rest controller Route in yous nodejs case在你的 nodejs 案例中路由
  • S means Service . S 表示服务 Javascript class or module with logic. Javascript class 或带逻辑的模块。 Rest controller uses one of several services to orchestrate the operation Rest controller 使用几种服务之一来编排操作
  • M means Model : abstraction of the database, external apis or any datasource (file, etc) to be read or write. M 表示Model :数据库、外部 API 或任何要读取或写入的数据源(文件等)的抽象。

Model-Service-Rest in nodejs nodejs 中的模型服务休息

Service.js with logic具有逻辑的 Service.js

const Service = () => {

  this.getCoordinates = async function(location){
    try {
      const params = new URLSearchParams({
        q:location, 
        appid: API_KEY
      })

      const apiRes = await needle('get', `${BASE_URL}/weather?${params}`) //api.openweathermap.org/data/2.5/weather?q=somecity&appid={API_KEY}
      const data = apiRes.body 
      return data;
    } catch(error) {
      throw error;
    }
  }

  this.getForecastData = async function(lat, lon){
    try {
      const params = new URLSearchParams({
        lat:lat,
        lon:lon,
        appid: API_KEY
      })

      const apiRes = await needle('get', `${BASE_URL}/weather?${params}`) //api.openweathermap.org/data/2.5/weather?q=somecity&appid={API_KEY}
      const data = apiRes.body
      return data;
    } catch(error) {
      throw error;
    }
  }
  
}

Routes.js路由.js

router.get('/forecast-data', async (req, res, next) => { 
  var coordinates = await this.service.getCoordinates(req.query.q);
  var forecastData = await this.service.getForecastData(req.query.lat, req.query.lon);
  res.status(200).json(forecastData)
}) 

If another web required only the coordinates, you could re-use the service如果另一个 web 只需要坐标,您可以重新使用该服务

router.get('/coordinates', async (req, res, next) => { 
  var coordinates = await this.service.getCoordinates(req.query.q);
  res.status(200).json(coordinates)
}) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何将数据从一个发布请求api发送到node.js中的另一个发布请求api? - how can i send the data from one post request api to another post request api in node.js? Node.js将值从一个api传递到另一个 - Node.js pass values from one api to another 如何通过 onclick 和 node.js 将数据从一页传递到另一页并表达? - How to pass data from one page to another by onclick with node.js and express? 如何使用Request-Promise将一个API的响应作为另一个API中的请求参数传递 - How do I pass the response of one API as a request param in another API using Request-Promise 如何将变量从一个ejs传递到节点js中的另一个ejs - how to pass variable from one ejs to another ejs in node js 如何在NodeJS中将多部分请求从一台服务器传递到另一台服务器? - How to pass multipart request from one server to another in NodeJS? 节点从API请求数据,将数据推送到数组。 然后使用该新数组运行另一个请求 - Node request data from API, push data to array. Then run another request using that new array 如何在Nodejs中将变量从一个API传递到另一个 - How to pass variable from one API to another in Nodejs 如果有人点击节点 js api,如何将数据从节点 js 传递到 Angular 1.x? - How to pass data form node js to Angular 1.x, if some one is hitting node js api? 如何使用expressjs将数据从一个路由传递到另一个nodejs - How to pass data from one route to another nodejs with expressjs
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM