问题描述
上下文
我在我的 Scala 后端应用程序中定义了一些“客户端”接口,它们大致具有以下形状:
trait BackendClient {
def foo: FooClient
}
trait FooClient {
def doSomething(authToken: AuthNToken,request: MyBarRequest): Future[Unit]
def getSomething(authToken: AuthNToken,id: MyId): Future[MyResource]
}
我想在后端的方法签名中保留 authToken
以提醒实现他们应该检查每个方法调用的身份验证。
不过在前端,到处传递相同的令牌会很烦人,所以理想情况下我想要一个“经过身份验证的”客户端:
// Would like to auto-generate this given `FooClient`
trait AuthenticatedFooClient {
def doSomething(request: MyBarRequest): Future[Unit]
def getSomething(id: MyId): Future[MyResource]
}
// Auto-generating this too would be nice but not as important
class AuthenticatedFooClientImpl(authToken: AuthNToken,delegate: FooClient) extends AuthenticatedFooClient {
override def doSomething(request: MyBarRequest): Future[Unit] = delegate.doSomething(authToken,request)
override def getSomething(id: MyId): Future[MyResource] = delegate.getSoemthing(authToken,id)
}
这样我就可以在前端有这样的东西:
trait AuthenticatedBackendClient {
def foo: AuthenticatedFooClient
}
class FrontendAuthServiceImpl(backendClient: BackendClient) extends FrontendAuthService {
private val getTokenOrAuthenticate: Task[AuthNToken] = Task { ... }.memoizeOnSuccess
val backendClient: Task[AuthenticatedBackendClient] = for {
authToken <- getTokenOrAuthenticate
authenticatedFoo = new AuthenticatedFooClientImpl(authToken,backendClient.foo)
} yield new AuthenticatedBackendClient {
override def foo: AuthenticatedFooClient = authenticatedFoo
}
}
...
...
...
val someId: MyId = ...
val myResource: Task[MyResource] = for {
backendClient <- frontendAuthService.backendClient
myResource <- Task.fromFuture(backendClient.foo.getSomething(someId))
} yield myResource
问题
我不想手动维护我的客户端特征的 2 个副本,一个在方法中带有 auth 令牌,一个没有。
我很确定我可以编写自己的注释处理器(我知道宏在 Scala 中可能更惯用,但我从来没有真正开始学习它们)来生成我想要的代码,但这感觉就像是什么这应该可以用现有的库/工具解决。
具体来说,我感觉我应该能够生成一个与另一个 trait 相同的 trait,但会删除所有其他 trait 方法的第一个参数。
有什么想法吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)