[英]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 响应中的lat
和lon
值需要作为第二个 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.js和onecall.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是的,您可以使用类似于MVC或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:基本上在这种模式中你有这样的结构:
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 或微服务:
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.