Api 当URI可以动态解析时,路由器有什么好处?

Api 当URI可以动态解析时,路由器有什么好处?,api,rest,routing,url-routing,Api,Rest,Routing,Url Routing,我正试图做出一个架构决策,我担心在设计一个基本的RESTAPI/框架时,我遗漏了一些关于URL路由/映射的重要内容 创建路由类和RESTAPI框架中常见的路由类,需要手动将URL映射到类和类方法(操作),似乎无法封装问题。当这一切都可以通过动态解析URL和拥有自动路由器或首页控制器来确定时 GEThttps://api.example.com/companies/ 获取所有公司列表的集合资源 GEThttps://api.example.com/companies/1 按ID获取单个公司 所有这

我正试图做出一个架构决策,我担心在设计一个基本的RESTAPI/框架时,我遗漏了一些关于URL路由/映射的重要内容

创建路由类和RESTAPI框架中常见的路由类,需要手动将URL映射到类和类方法(操作),似乎无法封装问题。当这一切都可以通过动态解析URL和拥有自动路由器或首页控制器来确定时

GEThttps://api.example.com/companies/

获取所有公司列表的集合资源

GEThttps://api.example.com/companies/1

按ID获取单个公司

所有这些似乎都遵循模板:
https://api.example.com///

好处1:URL解耦和抽象

我假设拥有一个典型路由类的一个纸面好处是,您可以从资源/物理类中解耦或抽象URL。所以你可以有任意的URL,比如
GEThttps://api.example.com/poo/
而不是
GEThttps://api.example.com/companies/
如果您愿意,它会吸引所有公司

但在我看到的几乎每个示例和用例中,都希望有一个与所需控制器匹配的URL,动作和参数,1:1

另一个可能的好处是,使用URL映射和典型的路由器,可以更容易地实现资源内的集合资源或嵌套资源。例如:

GEThttps://api.example.com/companies/1/users/

GEThttps://api.example.com/companies/1/users/1/

提出一个范例来动态解析它,以了解调用什么控制器来获取数据、使用什么参数以及在哪里使用它们,这可能是一个相当具有挑战性的问题。但我想我已经想出了一个标准的方法,可以使这个动态工作

而手动映射则很容易

我可以重新安排
GET的路线https://api.example.com/companies/1/users/
转到用户控制器而不是公司控制器,绕过它,只需将参数“1”设置为WHERE子句的公司id

好处1.1:与物理路径没有关联

优点1的补充是,开发人员可以完全更改URL方案和文件夹结构,而不会影响API,因为所有内容都是抽象映射的。如果我选择移动文件、文件夹、类或重命名它们,那么只需更改映射/路由即可

但仍然没有真正获得这一好处,因为即使您必须将整个API移动到另一个位置,.htaccess中的一个微不足道的更改也会立即修复这一问题

因此:

GEThttps://api.example.com/companies/

GEThttps://api.example.com/v1/companies/

不会影响代码,哪怕是一点点。即使使用动态路由器

好处2:控制公开哪些功能

我想象一个典型的路由器类给你的另一个好处是,相对于一个只解释和解析URL的动态路由器,它可以控制你想要向API消费者公开的功能。如果你只是动态地做每件事,你就有点脱裤子了,自动地让你的消费者访问整个系统

我认为这对动态路由器来说是一个可能的好处,因为这样您就不必手动定义并将所有路由映射到资源。一切都在那里,自动地。为了解决暴露问题,我可能会通过定义API消费者不允许使用的功能的黑名单来做相反的事情。我可能更省时,定义一个黑名单,然后用映射定义每个可用资源。再说一次,我想风险也更大。你甚至可以做一个白名单。。。这类似于典型的路由器,但根本不需要任何扩展逻辑。在将URL传递给动态路由器之前,系统将检查URL的列表。或者它可能只是动态路由器类的私有属性

好处3:当HTTP方法不太合适时

我看到的一个典型例子是,您需要执行一个与现有资源冲突的操作。让我解释一下

假设您希望通过在用户类中运行login函数来验证用户。但是现在,您不能执行
POSThttps://api.example.com/users/
具有凭据,因为这是为添加新用户保留的。相反,您需要以某种方式在用户类中运行login方法。您不想使用
POSThttps://api.example.com/users/login/
也可以,因为您使用的是HTTP方法以外的动词。然而,对于一个典型的路由器,您可以像前面所说的那样直接映射它。简单


url=>”https://api.example.com/tenant/“
控制器=>“用户”
操作=>“登录”
参数=>“api_密钥,api_密钥”

但是,我再一次看到了一个可行的选择。我可以创建另一个控制器,名为login或tenant,它实例化我的用户控制器,并运行login函数。因此,消费者只需
发布https://api.example.com/tenant/
,带有凭据,并带有错误。认证

虽然,为了让这个替代方案发挥作用,我必须实际创建另一个控制器,但使用URL映射器时,我不需要这样做。但是这种关注点、功能和资源的分离也很好。但是,也许这是主要的权衡,您是更愿意定义URL路由,还是必须为遇到的每个细微差别创建新类

W