Skip to content

动态路由的实现方式

566字约2分钟

2024-10-12

请求分析

一个请求都包含哪些信息? , 若要完成核心的主干逻辑,必须首先分析清楚这个问题。 或许有人会觉得,作为资深研发人员,天天和这些信息打交道,有什么可分析的,实则不然。 一次清晰彻底的分析,有助于理清思路,规划后续行动。一次清晰彻底的分析胜过无数次模棱两可的学习。 接下来我们来分析下,一个请求具体是如何组成的。

curl --location --request POST 'http://localhost/foo/bar?from=test' \
--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)' \
--header 'Content-Type: application/json' \
--header 'Cookie: cookie1=val1' \
--data-raw '{
    "foo": "foo",
    "bar": "bar",
}'

上述是一个简单的curl请求,核心包含如下几部分 :请求方法请求路由请求header请求BODY

其中请求路由可以再起细分为如下几个部分 :接口协议接口域名接口路径QUERY参数

那么决定接口访问是否404, 影响因素有哪些呢?

  • 接口路径 : 接口路径需要拼写正确, 若拼写错误, 则404
  • 请求方法 : 接口请求方法需要和预期一致, 若不一致, 则404

eg. 存在 POST /foo/bar 接口, 访问 POST /foo/barr , 结果 404; 访问 GET /foo/bar 结果404

NoRoute实现

基于此,上一小节提到的动态路由处理逻辑可以完善 :

route := gin.Default()
router.NoRoute(func(ctx *gin.context) {
    // 这里放置拦截到未注册路由的处理逻辑
    // 具体如何实现,基于业务诉求自由实现
    // 在网关动态路由场景下,后续会具体解释如何实现动态路由
    var (
        err error
        apiConfig *apiConfig
    )
    // 确认接口确实注册
    if apiConfig, err = getApiConfig(ctx.Request.RequestURI); nil != err || nil == apiConfig {
       	// 接口未注册
        ctx.Status(http.StatusNotFound)
        ctx.Abort()
        return
    }
    if apiConfig.Status != "USING" {
        // 接口非启用状态
        ctx.Status(http.StatusNotFound)
        ctx.Abort()
        return
    }
    if apiConfig.Method != ctx.Request.Method {
        // 请求接口的方法与注册的方法不一致
        ctx.Status(http.StatusMethodNotAllowed)
        ctx.Abort()
        return
    }
    // 基础验证通过, 处理一些其他逻辑
})

说明

路由存在, 请求方法错误, 在 HTTP 标准规范中应该是 405 Method Not Allowed , 本文中解释为 404 , 是基于 GIN 框架的行为体系下进行的解析。