NodeJS Rest API - 调用外部 API 的正确位置在哪里
Posted
技术标签:
【中文标题】NodeJS Rest API - 调用外部 API 的正确位置在哪里【英文标题】:NodeJS Rest API - where is the right place to call external API 【发布时间】:2022-01-21 16:25:15 【问题描述】: 我在 Node.JS 中编写 Rest API,它使用 mysql 数据库但也使用外部 API,我需要在其中获取一些数据。我正在使用 Express 和“路由器、中间件、控制器、模型”架构,但我不确定调用外部 API 的正确解决方案是什么。在每个请求中,我都会发送外部 API 所需的令牌。我展示了我现在所拥有的并尝试描述我目前所面临的问题(请阅读代码中的 cmets。)
(另外,如果你有一些文章或教程描述了如何在使用路由器、中间件、控制器、模型架构的节点中正确编写 Rest API,请告诉我)
这是主要的 index.js
const express = require("express");
const dotenv = require('dotenv');
const cors = require("cors");
const HttpException = require('./utils/HttpException.utils');
const errorMiddleware = require('./middleware/error.middleware');
const userRouter = require('./routes/user.route');
const axios = require("axios");
// Init express
const app = express();
// Init environment
dotenv.config();
// parse requests of content-type: application/json
// parses incoming requests with JSON payloads
app.use(express.json());
// enabling cors for all requests by using cors middleware
app.use(cors());
// Enable pre-flight
app.options("*", cors());
const port = Number(process.env.PORT || 3331);
app.use(`/api/v1/users`, userRouter);
// This is an solution that works but I thinks is and nasty way how to do it
// You can see here how I need to call external API
app.get('/api/v1/test', (req, res, next) =>
const token = req.headers.token;
const respond = await axios.get(EXTERNAL_API_ENDPOINT,
headers:
cookie: `token=$token`
);
);
// 404 error
app.all('*', (req, res, next) =>
const err = new HttpException(404, 'Endpoint Not Found');
next(err);
);
// Error middleware
app.use(errorMiddleware);
// starting the server
app.listen(port, () =>
console.log(`Server running on port $port!`));
module.exports = app;
user.route.js
const express = require('express');
const router = express.Router();
const userModel = require('../models/user.model');
const awaitHandlerFactory = require('../middleware/awaitHandlerFactory.middleware');
router.get('/currentUser', awaitHandlerFactory(userModel.getCurrentUser));
router.get('/logout');
module.exports = router;
我还有一个 Auth 中间件来检查令牌验证,我需要调用外部 API 来验证用户。
Auth.middleware.js
const HttpException = require('../utils/HttpException.utils');
const UserModel = require('../models/user.model');
const dotenv = require('dotenv');
dotenv.config();
const auth = (roles) =>
return async function (req, res, next)
try
const token = req.headers.token;
if (!token)
throw new HttpException(401, 'Access denied. No credentials sent!');
/* here I need call the external API and think that I should call it from
UserModal?, but I can't because Modal doesn't have req (should I sent it
in function parmas? like this?)*/
const user = await UserModel.getCurrentUser(token, params);
if (!user)
throw new HttpException(401, 'Authentication failed!');
if(!user.active || user.active !== 'Y')
throw new HttpException(401, `User $user.userName is not active!`);
// if the user role don't have the permission to do this action.
// the user will get this error
if (roles.length && !roles.includes(user.role))
throw new HttpException(401, 'Unauthorized');
// if the user has permissions
req.currentUser = user;
next();
catch (e)
e.status = 401;
next(e);
module.exports = auth;
我不确定如何处理这个问题。我必须提供令牌和一些数据来调用外部 API。我不确定,如果我应该调用模型或通过控制器(或中间件?)来做。 我应该在哪里以及如何做,为什么?谢谢!
【问题讨论】:
【参考方案1】:在我看来还不错。真的取决于是否需要每次请求都进行 API 调用。假设用户向您的 API 发出请求,然后向外部 API 发出请求以验证该用户,您将需要来自每个请求的身份验证令牌。
不过,您可以更好地组织代码。例如:
?api
┣ ?控制器
┃ ┗ ?test.js
┣ ?服务
┃ ┗ ?EXTERNAL_API_ENDPOINT.js
┗ ?index.js
api/services/EXTERNAL_API_ENDPOINT.js
const axios = require("axios");
async function getService(token)
return axios.get(EXTERNAL_API_ENDPOINT,
headers: cookie: `token=$token`
);
module.exports = getService;
api/controllers/test.js
const getService = require("../services/EXTERNAL_API_ENDPOINT");
async function test(req, res, next)
const token = req.headers.token;
const respond = await getService(token)
module.exports = test;
api/index.js
const test = require("./controllers/test");
app.get('/api/v1/test', test);
【讨论】:
以上是关于NodeJS Rest API - 调用外部 API 的正确位置在哪里的主要内容,如果未能解决你的问题,请参考以下文章
使用nodejs和rest api调用和express进行异步处理-序列错误
Express 和 Nodejs:调用外部 API 的最佳方式
Magento 使用 OAuth 通过 REST API 到 NodeJS
在节点中创建 REST API 时,如何将来自对外部网站的请求的 http 响应流式传输到原始 api 调用?