Making a Tapir secure endpoint proxyable

Hello,

I’m interested in taking an existing secure Tapir endpoint, and being able to use its inputs to check a table and proxy to the same endpoint on another server if need be. For public endpoints, I think Tapir would work well for this. You can take the endpoint definition, and essentially do

val getUserEndPoint = endpoint
  .in("api" / "users" / path[UserId]("userId"))
  .get
  .out(jsonBody[User])

def proxyEndpointServerLogicSuccess[...](
  endpoint: Endpoint[_, I, _, O, _]
)(
  extractServerInfo: I => ServerInfo
)(
  f: PRINCIPAL => INPUT => Future[OUTPUT]
): ServerEndpoint.Full[...] = {
  // 1. look up which server the data lives on, based on the request inputs
  // 2. if it's a different server, construct an sttp client and call the other
  //     server with the inputs from our current request, and return the output
  // 3. otherwise, run our local server logic using the `f` function
  ...
}
def getUserInfo(userId: UserId): ServerInfo = ???

val getUserServerEndpoint =
  proxyEndpoint(getUserEndPoint)(getUserInfo) { _ => userId =>
  // look up user, return json body for them, etc.
  ...
}

Unfortunately, secure endpoints also need their security inputs passed when calling via the client, and I can’t seem to find a way to implement a serverLogicSuccess under the hood that will do that, since security inputs are handled totally separately from the regular endpoint inputs.

Anyone have advice on how to be able to achieve that similar thing for secure endpoints? Do I need to duplicate the security inputs into the main inputs? or would something like extractFromRequest under the hood and rewriting the HTTP request be a better solution (if I am looking to do this logic endpoint-by-endpoint)?

I’m not sure I follow the problem - for secure endpoints, you’d do a .serverSecurityLogicSuccess followed by .serverLogicSuccess? The first function might be an identity one, or anything else for that matter. So PRINCIPAL might be equal to A in terms of the type parameters.