javascript - 如何在函数式编程范式中动态调用 API
问题描述
我的应用程序接收来自人类客户端的 http 请求。
我的应用程序只需要调用 12 个 API 中的一个 API,这取决于它接收到的输入中的一个特定数据。
我的第一个想法当然是
// requestPrice.js
const service = req.body.service
const APIs = {
ser1: callAPI1,
ser2: callAPI2,
ser3: callAPI3,
// ...
ser12: callAPI12,
}
return APIs[service](req.body)
这工作正常,但我想需要一些重构以使其符合 SOLID。通常在 OOP 中,我可能会使用其中一种设计模式,例如策略或责任链。
但是我使用的函数式编程有点不同。
我想过做以下事情:
// ser1.js
export default callAPI(data) {
// code 1
}
// ser2.js
export default callAPI(data) {
// code 2
}
// ser3.js
export default callAPI(data) {
// code 3
}
//...
// ser12.js
export default callAPI(data) {
// code 12
}
// requestPrice.js
const service = req.body.service
const api = require(`./${service}`)
return api(req.body)
这看起来比第一个版本好得多,因为它更好地遵循单一责任原则。另外,我猜它也遵循 Open/Closed 原则,因为requestPrice.js
如果要添加第 13 个 api,它不会改变。另一方面,我应该能够轻松地对文件进行单元测试,requestPrice.js
因为req
可以注入。
这样做是否符合 SOLID 原则,还是有更好更清洁的方法?
解决方案
我建议使用工厂方法(在 FP 中实现为柯里化函数),以便决定调用哪个服务以及在每个服务中做什么是分开的。request.body 应该传递给返回的 impl 函数。
function createService(body) {
if(checkInput(body) == [something]) return service1;
else if(checkInput(body) == [something2]) return service2;
..
}
function service1(body) {..}
function service2(body) {..}
..
let service = createService(req.body);
service(request.body);
我没有把它放在不同的文件中,但你可以这样做。现在 createService 可以在不同的模块中。并且每个 impl(service1、service2 等)都可以在自己的单独文件中,并且 service 的调用者不需要知道要调用哪个 impl,从而保持依赖倒置。高级模块不知道低级模块。:)
推荐阅读
- python-3.x - Matplotlib 条形图条间距
- vb.net - VB.NET 将数组与 Outlook 邮件项目附件列表中的文件名值进行比较仅匹配一次,而应该发生更多匹配
- bazel - Bazel Starlark:如何以程序方式生成 BUILD 文件?
- amazon-web-services - AWS - 防止管理员用户提升自己的权限
- node.js - 尝试运行节点脚本以分配 Waves 节点和租用者的收入。但是获取套接字挂起错误,在节点脚本的 HTTP 调用中
- requirejs - 是否可以在客户端运行 FFmpeg 或类似的库?
- visual-studio - 删除github仓库后上传到github
- python-3.x - 如何在 python 中使用 Microsoft Graph API 创建计划任务?
- python - 如何根据 Python 中的条件将另一个数据帧中的值分配给当前数据帧?
- c++ - 将指针传递给链表时出现分段错误