如何在Tapir成功响应中返回自定义HTTP状态码?
在Tapir中为成功响应设置自定义HTTP状态码的代码示例
固定自定义状态码示例
如果接口成功响应需要固定返回某个非200的状态码(比如创建资源后返回201 Created),可以直接在endpoint定义中通过statusCode方法指定:
首先添加必要的SBT依赖:
libraryDependencies ++= Seq( "com.softwaremill.sttp.tapir" %% "tapir-core" % "1.9.6", "com.softwaremill.sttp.tapir" %% "tapir-akka-http-server" % "1.9.6", "com.softwaremill.sttp.tapir" %% "tapir-json-circe" % "1.9.6" )
然后编写接口定义和后端实现:
import sttp.tapir._ import sttp.tapir.json.circe._ import sttp.model.StatusCode import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.server.Route import sttp.tapir.server.akkahttp.AkkaHttpServerInterpreter import scala.concurrent.ExecutionContextExecutor import scala.io.StdIn // 定义响应数据结构 case class CreatedResource(id: String, name: String) // 定义POST接口:创建资源,成功返回201状态码和资源信息 val createResourceEndpoint: Endpoint[Unit, Unit, CreatedResource, Any] = endpoint .post .in("resources") .out(statusCode(StatusCode.Created)) // 指定成功响应的状态码 .out(jsonBody[CreatedResource]) object TapirCustomStatusDemo extends App { implicit val system: ActorSystem = ActorSystem("TapirDemoSystem") implicit val ec: ExecutionContextExecutor = system.dispatcher // 实现接口逻辑 val createResourceRoute: Route = AkkaHttpServerInterpreter().toRoute(createResourceEndpoint.serverLogicSuccess { _ => // 模拟资源创建逻辑 Right(CreatedResource("res-001", "Sample Resource")) }) // 启动Akka HTTP服务器 val binding = Http().newServerAt("localhost", 8080).bind(createResourceRoute) println("Server running on http://localhost:8080\nPress Enter to stop...") StdIn.readLine() binding.flatMap(_.unbind()).onComplete(_ => system.terminate()) }
动态自定义状态码示例
如果需要根据业务逻辑动态返回不同的成功状态码,可以将StatusCode作为响应输出的一部分,在逻辑中返回对应的状态码和数据:
// 定义支持动态状态码的接口 val dynamicStatusEndpoint: Endpoint[String, Unit, (StatusCode, CreatedResource), Any] = endpoint .get .in("resources" / path[String]("id")) .out(statusCode) // 从响应元组中提取状态码 .out(jsonBody[CreatedResource]) // 实现动态状态逻辑 val dynamicRoute: Route = AkkaHttpServerInterpreter().toRoute(dynamicStatusEndpoint.serverLogicSuccess { resourceId => resourceId match { case "existing" => Right((StatusCode.Ok, CreatedResource("existing", "Pre-existing Resource"))) case "new" => Right((StatusCode.Created, CreatedResource("new", "Newly Created Resource"))) case _ => Right((StatusCode.Accepted, CreatedResource(resourceId, "Pending Creation"))) } })
关键说明
statusCode(StatusCode.XXX)用于固定指定成功响应的状态码,覆盖默认的200 OK- 动态状态码场景下,需要将
StatusCode加入响应输出,业务逻辑返回(StatusCode, 响应数据)的元组,Tapir会自动解析并设置对应的HTTP状态码
内容的提问来源于stack exchange,提问作者martyn
相关产品推荐
相关产品推荐

