Skip to content

Instantly share code, notes, and snippets.

@soujiro32167
Created May 7, 2020 14:29
Show Gist options
  • Save soujiro32167/b0a59d8953f0a1b50565272d345e1ce8 to your computer and use it in GitHub Desktop.
Save soujiro32167/b0a59d8953f0a1b50565272d345e1ce8 to your computer and use it in GitHub Desktop.
Extracting a static redoc site from Tapir
import java.nio.file.Paths
import cats.effect.{ ExitCode, IO, IOApp }
import DocUtils._
import sttp.tapir.Endpoint
object Docs extends IOApp {
private val title = "Le API"
private val version = "1.0"
// aggregate your endpoints here, no need for the server logic
private val docEndpoints: List[Endpoint[_, _, _, _]] = ???
val routes = redocRoutes(title, version, docEndpoints)
override def run(args: List[String]): IO[ExitCode] = {
val rootPath = args.headOption.map(Paths.get(_))
generate(title, version, docEndpoints)
.flatMap { case (html, yaml) => createFiles(rootPath, html, yaml) }
.map(_ => ExitCode.Success)
}
}
import java.nio.file.{ Files, Path, Paths }
import cats.effect.{ ContextShift, IO }
import org.http4s.{ HttpRoutes, Request }
import sttp.tapir.Endpoint
import sttp.tapir.redoc.http4s.RedocHttp4s
import sttp.tapir.openapi.circe.yaml._
import sttp.tapir.docs.openapi._
object DocUtils {
val yamlFile = "docs.yaml"
val htmlFile = "index.html"
type HTML = String
type Yaml = String
def redocRoutes(title: String, version: String, endpoints: List[Endpoint[_, _, _, _]])(implicit cs: ContextShift[IO]): HttpRoutes[IO] =
new RedocHttp4s(title, endpoints.toOpenAPI(title, version).toYaml, yamlFile).routes[IO]
def generate(title: String, version: String, endpoints: List[Endpoint[_, _, _, _]])(implicit cs: ContextShift[IO]): IO[(HTML, Yaml)] = {
val yaml = endpoints.toOpenAPI(title, version).toYaml
val routes = new RedocHttp4s(title, yaml, yamlFile).routes[IO]
routes.run(Request()).semiflatMap(_.as[String]).value.map(html => html.get -> yaml)
}
def createFiles(rootPath: Option[Path], html: HTML, yaml: Yaml): IO[Unit] =
for {
dir <- IO(Files.createDirectories(rootPath.getOrElse(Paths.get("docs"))))
_ <- IO(Files.write(dir.resolve(htmlFile), html.getBytes))
_ <- IO(Files.write(dir.resolve(yamlFile), yaml.getBytes))
} yield ()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment