Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我应该选择代码重复还是使用api service-JS进行整合_Javascript_Api_Design Patterns_Architecture_Redundancy - Fatal编程技术网

Javascript 我应该选择代码重复还是使用api service-JS进行整合

Javascript 我应该选择代码重复还是使用api service-JS进行整合,javascript,api,design-patterns,architecture,redundancy,Javascript,Api,Design Patterns,Architecture,Redundancy,我正在一个大型CMS系统上工作,其中一个特定模块及其子模块利用相同的后端API。除了“文档类型”之外,每个子模块的端点完全相同 因此,我们遵循这样一种模式: api/path/v1/{document type} api/path/v1/{document type}/{id} api/path/v1/{document type}/{id}/versions 随着时间的推移,使用此API的模块数量不断增加,我只剩下许多实现7种CRUD方法的冗余API服务: getAllXs() {...} g

我正在一个大型CMS系统上工作,其中一个特定模块及其子模块利用相同的后端API。除了“文档类型”之外,每个子模块的端点完全相同

因此,我们遵循这样一种模式:

api/path/v1/{document type}

api/path/v1/{document type}/{id}

api/path/v1/{document type}/{id}/versions

随着时间的推移,使用此API的模块数量不断增加,我只剩下许多实现7种CRUD方法的冗余API服务:

getAllXs() {...}
getX(id) {...}
getXVersion(id, versionId) {...}

etc...
用一个像这样的单独方法

getAllXs() {
    let endpoint = BASE.URL + ENDPOINTS.X;
    let config = ...
    return http.get(endpoint, config)
        .then(response => response.data);
        .catch(...);

}
其中X将是特定文档类型的名称

我到了一个地步,我决定做一个单一的服务,并做这样的事情:

const BASE_URL = window.config.baseUrl + Const.API_ENDPOINT;
const ENDPOINTS = {
  "W": "/v1/W/",
  "X": "/v1/X/",
  "Y": "/v1/Y/",
  "Z": "/v1/Z/",
}

getAllDocuments(docType, config={}) {
  let endpoint = BASE_URL + ENDPOINTS[docType];
  return http.get(endpoint, config)
        .then(response => response.data);
        .catch(...);
}
...other methods
其中指定了类型,并使用映射的端点来构建路径

这将所有文档api服务减少到一个。这在代码方面更加简洁,但显然现在需要一个额外的参数,术语也更加通用:

getAllXs()-->getAllDocuments()

而且它的“防白痴性”也少了一点。目前的编写方式让我感到不安全的是,有6个模块使用这个API,每个服务中有7个相同的方法

我一直在问自己的问题是:

  • 我的动态功能是否接近反模式

  • 如果我有10多个模块使用相同的API会怎么样


如果您想提供更多原始版本的代码,那就需要更多的指向点

目前我只能说,一般来说,干燥原则是一个好主意(不总是,但……这是一个复杂的话题)。有很多关于干燥的文章。谷歌

您担心您的代码变得更加复杂。别担心。根据我的经验,新手程序员之所以惨败,正是因为他们放弃了干式原理。只是过了一段时间,当他们变得更强时,他们开始在接吻原则上失败。除了已经存在的3个参数之外,只有一个额外的参数不会增加太多的复杂性

我的动态功能是否接近反模式

“动态”——这就是函数存在的原因

如果我有10多个模块使用相同的API会怎么样

没错!如果你需要改变一些东西,你会有10多个机会打字,忘记一些东西,误读,等等,还有10多个工作要做。这是如果你不擦干你的代码


注:
getAllDocuments
的名称实际上比
getAllDocType1s
要好,如果这是您原始代码中的真实名称。

您的问题让我想到了一个常见的设计问题

当涉及到设计时,没有单一的真理来源,但是如果你在你正在构建的东西和价值中认识到ORM,我会给你一些灵感

这里是我在许多项目中使用过的普通ES6 ORM的过度简化(重用代码片段以提高可靠性)。这个设计的灵感来自于我在其他语言中使用的大量ORM框架

class ORM {
   constructor() {
      this.BASEURL = window.config.baseUrl + Const.API_ENDPOINT
      this.config = {foo:bar} // default config
   }

   getAll() {
      let endpoint = this.BASEURL + this.ENDPOINT
      return http.get(endpoint, this.config)
       .then(response => response.data)
       .catch(...)
   }

   get(id) {
      // ...
   }
}
以及该类的扩展示例(请注意具有特殊配置的一个)

因为你是在问这是否是反模式。我建议你阅读一些关于设计、原则和总体设计的书籍。您还将发现有关全局常量的代码气味,但这只有在窗口上下文中才会出现。我发现您已经走上了正确的道路,试图避免出现以下情况::-)


祝你好运,请毫不犹豫地提出更多问题,并在评论中添加更多细节

虽然我分享了x00的大部分答案,但我会考虑端点的静态程度

是否有机会模块“X”可以更改其任何端点定义?例如,您需要再传递一个查询参数。您的模块是否完全相同,没有改变的余地

如果答案是否定的,那就开始吧。要进行简单的更改,您必须重构整个代码库(如果您按照您建议的方式实现它的话)

如果答案是肯定的,那么,我认为您没有理由不实施拟议的动态功能。就我个人而言,我倾向于我的模块扩展和使用的服务,以防我想对它们做最小的更改。例如:

类MyGenericService{
构造函数(){
this.url=window.config.baseUrl;
}
异步getAllDocuments(配置){
返回http.get(this.url,config)
.然后(response=>response.data);
.捕获(…);
};
//……等等
}
这使得我的代码可以扩展和修改,只需要一个外卖,即每个模块需要维护一个文件,它有如下内容:

const BASE_URL = window.config.baseUrl + Const.API_ENDPOINT;
const ENDPOINTS = {
  "W": "/v1/W/",
  "X": "/v1/X/",
  "Y": "/v1/Y/",
  "Z": "/v1/Z/",
}

getAllDocuments(docType, config={}) {
  let endpoint = BASE_URL + ENDPOINTS[docType];
  return http.get(endpoint, config)
        .then(response => response.data);
        .catch(...);
}
...other methods
classxservice扩展了MyGenericService{
构造函数(){
this.url=window.config.baseUrl+'/v1/x';
}
}
如果维护这些额外文件的开销太大,您可以在MyGenericService的构造函数中接收端点的URL,您只需要在控制器中执行以下操作:

constmyxservice=newmygenericservice('/v1/x');
const myYService=new MyGenericService('/v1/y');
//…或者它可以使用您的端点url映射
//我真的不知道你的代码是如何构造的,只是给你一些想法
你有一些选择,希望对你有所帮助

getAllResponses()将是一个实际的示例。。。虽然我尽可能地遵守DRY,但由于添加了额外的参数/标志以适应不断增长的需求,使函数变得过于动态,我受到了影响。这就是为什么我在这里(一个接口将是完美的解决方案)。我倾向于冗余的主要原因是,在某些情况下,特定的文档api服务可能需要额外的头或参数。