如何在函数式编程范例中动态调用 API
How to call an API dynamically in functional programming paradigm
我的应用程序接收来自 humain 客户端的 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 原则,我猜,因为如果要添加第 13 个 api,requestPrice.js
不会改变。
另一方面,我应该能够轻松地对文件 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等)都可以在自己单独的文件中,服务的调用者不需要知道调用哪个impl,因此保持了依赖倒置。高层模块不知道底层模块。 :)
我的应用程序接收来自 humain 客户端的 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 原则,我猜,因为如果要添加第 13 个 api,requestPrice.js
不会改变。
另一方面,我应该能够轻松地对文件 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等)都可以在自己单独的文件中,服务的调用者不需要知道调用哪个impl,因此保持了依赖倒置。高层模块不知道底层模块。 :)