同一端点的多租户实现

Multi tenant implementations of the same endpoint

我有一个用 Go 编写的 API 服务器,它为不同的租户做一些工作。 我有许多端点应该根据调用它的租户实现不同的代码,例如:

s.GET("/api/orders", a.getOrders)

将调用 a.getOrders 处理程序,在其工作后将为所有租户 returns 相同的 JSON 结构,但获取数据的实现可能不同(有时对于tenant 我需要调用另一个 web 服务,另一个我需要查询不同的数据库表等...)。 我正在考虑为每个租户创建不同的包,所以我将有一个 common(对于常见的实现),tenanta(对于租户 A 的特定实现),tenantbtenantc 等等...现在,我的问题是:哪种方法是处理“重定向”的最佳方式? 我能想到的第一件事(可能是坏事)是在我的 a.getOrders 处理程序中放置一个开关并从会话中解析 tenantID 或 url:

switch tenantID {
   case "tenanta":
       tenanta.getOrders()
   case "tenantb":
       tenantb.getOrders()
   case "tenantc":
       tenantc.getOrders()
   default:
       common.getOrders()
}

显然它可能会很快变长(目前我必须处理 20 多个租户)。 有没有更好的方法来处理这种情况?

谢谢

你可以做一个类似

的租户界面
type tenant interface{
    getOrders() Orders
}

现在您可以声明任意数量的实现此接口的租户

package main

import (
    "fmt"
)

type tenant interface {
    getOrders()
}

type TenantA struct {
}

func (t TenantA) getOrders() {
    fmt.Println("Tenant A")
}

var tenantMap = map[string]tenant{
    "T-A": TenantA{},
}

func main() {
    fmt.Println("Hello")
    teneantTest := "T-A"
    
    curTeneant, ok := tenantMap[teneantTest]
    if !ok {
        fmt.Println("Not Found")
        return
    }
    
    curTeneant.getOrders()
}

现在你所有的租户都遵循相同的界面,如果所有租户都定义了最少的函数集,这将是编译时可测试的

这也会导致更清晰的抽象