如何在Tapir中提取端点路径模板并传入serverLogic?
提取Tapir端点路径模板用于serverLogic的方法
Tapir本身没有内置的直接输入来获取端点路径模板,但可以通过以下几种方式实现需求:
方法一:利用端点的show方法提取
Tapir的Endpoint实例的show方法会返回端点的字符串描述,其中包含路径模板信息。你可以提取这部分内容后传入serverLogic:
// 定义端点 val createUserEndpoint: Endpoint[String, Unit, Unit, Unit] = endpoint.get.in("create-user" / path[String]("username")) // 提取路径模板:从show输出中截取路径部分 val pathTemplate = createUserEndpoint.show.split(" ").head // 在serverLogic中使用模板 val serverLogic = ServerLogic.success((username: String) => { println(s"处理请求,路径模板:$pathTemplate") () })
注意:show的输出格式可能随Tapir版本变化,需要根据实际输出调整字符串处理逻辑。
方法二:自定义输入类型关联模板
在定义端点时直接绑定路径模板,作为输入的一部分传入serverLogic,这种方式更可控:
import sttp.tapir._ import sttp.tapir.server.ServerEndpoint // 自定义输入结构,携带路径模板 case class PathWithTemplate[T](value: T, template: String) // 扩展输入构造方法 def pathWithTemplate[T](template: String)(implicit codec: Codec[String, T, CodecFormat.TextPlain]): EndpointInput[PathWithTemplate[T]] = { path[T].map(v => PathWithTemplate(v, template))(input => input.value) } // 使用自定义输入定义端点 val createUserEndpoint: Endpoint[PathWithTemplate[String], Unit, Unit, Unit] = endpoint.get.in(pathWithTemplate[String]("/create-user/{username}")) // 在serverLogic中直接获取模板 val serverLogic = ServerLogic.success((input: PathWithTemplate[String]) => { println(s"用户名:${input.value},路径模板:${input.template}") () })
方法三:解析端点路径段构建模板
通过访问端点的pathSegments属性,手动解析路径段类型并拼接出标准模板:
import sttp.tapir.{Endpoint, PathSegment} // 解析路径段生成模板的工具方法 def buildPathTemplate(endpoint: Endpoint[_, _, _, _]): String = { endpoint.pathSegments.map { case PathSegment.Fixed(value) => value case PathSegment.Capture(name, _, _) => s"{$name}" case PathSegment.MultiCapture(name, _, _) => s"{$name*}" }.mkString("/", "/", "") } // 使用示例 val createUserEndpoint = endpoint.get.in("create-user" / path[String]("username") / paths[List[String]]("files")) val pathTemplate = buildPathTemplate(createUserEndpoint) // 得到"/create-user/{username}/{files*}" // 传入serverLogic使用 val serverLogic = ServerLogic.success((inputs: (String, List[String])) => { val (username, files) = inputs println(s"路径模板:$pathTemplate,请求参数:$username, $files") () })
内容的提问来源于stack exchange,提问作者Matzz
相关产品推荐
相关产品推荐

