无论是web server框架还是rpc框架,接口作为服务的对外入口,其背后可能包含复杂的后端流程,不限于业务逻辑处理、数据处理&操作、基础能力调用等。所以接口和“后端流程”之间必然存在着映射交付关系。
路由机制
以下均以web框架为例,rpc框架相比web更为直接,即指定方法调用
http api 请求 和 rpc调用本质上都是通过网络完成通信双方交互。我们不局限在业内常见的平台化、微服务化中对两者的应用,其实可以这样泛化理解所有“交互”有如下要素:
通信双方约定好的通信规则。
统一的通信规则能够保证通信的准确性,避免二义性;
根据交互场景和限制条件选择合适的协议,例如app中前后端交互常用http/https,IoT场景中就可能使用MQTT/CoAP,可以提高通信效率,减低通信成本;
通信的任务就是传递信息,无非就是数据,结构化数据、非结构化数据都有相应的表示形式,辅之以众多协议,能够有效地被组织起来进行传输。例如,最常见的http请求get参数、json格式参数、rpc protobuf等
数据送达至何处。
这也是接口概念的关键,在计算机网络中
路由注册实现接口到控制器的映射,以此为基础完成后续处理流程
同时还可以注册中间件,构建请求处理过程的执行链路
路由注册方式多种,原理上归纳为以下几种:
基于配置(静态)
// For example, PHP framework register controller with Array
class ActionControllerConfig extends ActionBaseConfig {
public static ControllerConfig => array (
array(
'action_id' => 'action_name' // action唯一标识,后续用作router map key
'pattern' => '/^\/rest\/2\.0\/module\/operation/?params'// 框架规则不尽相同,本例为正则表达式 + 请求参数组合匹配
'path' => 'controller class path'
'controller_class' => 'controller1.class.php'
),
...
)
}
// 代码来源 https://github.com/go-chi/chi
r.Route("/parent/pattern", func(r Router) {
r.Use(middleware2.SetContextUser) // 设置中间件
r.Mount("/xxx1", NewXxx1Router())
r.Mount("/xxx2", NewXxx2Router(boot))
r.Mount("/xxx3", NewXxx3Router(boot))
r.Mount("/xxx4", NewXxx4Router(boot))
r.Mount("/xxx5", NewXxx5Router(boot))
})
基于反射、注解、动态代理(动态)
精确匹配
模式匹配
参数辅助匹配
最终路由注册产出结果主要如下两种形式(求见多识广的小伙伴补充~)
路由表
路由树
常用最左前缀匹配
……