Last active
June 15, 2024 17:18
-
-
Save dacr/1fc311878e5a575161a4b7ddb8a61411 to your computer and use it in GitHub Desktop.
tapir with iron/jsoniter for data validity and better documentation / published by https://github.com/dacr/code-examples-manager #a98827ba-f873-4597-8321-57c5b0f37a6a/13a8a6d8fa369d29757432f7ce24713f83c9acfb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// summary : tapir with iron/jsoniter for data validity and better documentation | |
// keywords : scala, zio, tapir, iron, jsoniter, @testable, @exclusive | |
// publish : gist | |
// authors : David Crosson | |
// license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2) | |
// id : a98827ba-f873-4597-8321-57c5b0f37a6a | |
// created-on : 2024-06-07T07:57:09+02:00 | |
// managed-by : https://github.com/dacr/code-examples-manager | |
// run-with : scala-cli $file | |
// test-with : curl -L http://127.0.0.1:8080/hello/david | |
// --------------------- | |
//> using scala "3.4.2" | |
//> using dep "com.softwaremill.sttp.tapir::tapir-zio:1.10.9" | |
//> using dep "com.softwaremill.sttp.tapir::tapir-zio-http-server:1.10.9" | |
//> using dep "com.softwaremill.sttp.tapir::tapir-iron:1.10.9" | |
//> using dep "com.softwaremill.sttp.tapir::tapir-jsoniter-scala:1.10.9" | |
//> using dep "com.softwaremill.sttp.tapir::tapir-swagger-ui-bundle:1.10.9" | |
//> using dep "io.github.iltotore::iron-jsoniter:2.5.0" | |
//> using dep "com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-core:2.30.1" | |
//> using dep "com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-macros:2.30.1" | |
// --------------------- | |
import zio.* | |
import zio.http.Server | |
import com.github.plokhotnyuk.jsoniter_scala.macros.* | |
import com.github.plokhotnyuk.jsoniter_scala.core.* | |
import io.github.iltotore.iron.* | |
import io.github.iltotore.iron.constraint.all.* | |
import io.github.iltotore.iron.jsoniter.given | |
import sttp.tapir.ztapir.* | |
import sttp.tapir.server.ziohttp.ZioHttpInterpreter | |
import sttp.tapir.swagger.bundle.SwaggerInterpreter | |
import sttp.tapir.json.jsoniter.* | |
import sttp.tapir.Schema | |
import sttp.tapir.generic.auto.* | |
import sttp.tapir.codec.iron.given | |
import sttp.apispec.openapi.Info | |
object WebApp extends ZIOAppDefault { | |
//type Name = String :| (Not[Empty] & Alphanumeric) // //DescribedAs "name should not be empty and only made of alphanumeric characters" | |
type Name = String :| (MinLength[3] & MaxLength[64]) | |
type Age = Int :| Positive // DescribedAs "Age should be positive" | |
type NickName = String :| (MinLength[3] & MaxLength[6]) | |
//type NickNames = List[NickName] :| MinLength[1] | |
type NickNames = List[NickName] :| Not[Empty] | |
enum Gender derives ConfiguredJsonValueCodec { | |
case Female, Male, Other | |
} | |
case class Salute( | |
name: Name, | |
age: Int :| Positive, /*DescribedAs "Age should be positive"*/ | |
gender: Option[Gender], | |
nicknames: NickNames | |
) derives ConfiguredJsonValueCodec | |
case class Greeting(message: String) derives ConfiguredJsonValueCodec | |
// -------------------------------------------------- | |
def helloLogic(salute: Salute): UIO[Greeting] = ZIO.succeed(Greeting("hello")) | |
val helloEndPoint = | |
endpoint | |
.tag("Greetings") | |
.name("hello") | |
.description("Returns greeting") | |
.post | |
.in("hello") | |
.in(jsonBody[Salute]) | |
.out(jsonBody[Greeting]) | |
val helloRoute = helloEndPoint.zServerLogic[Any](helloLogic) | |
// -------------------------------------------------- | |
val apiDocRoute = | |
SwaggerInterpreter() | |
.fromServerEndpoints( | |
List(helloRoute), | |
Info(title = "Greeting API", version = "1.0", description = Some("Everything required to be polite")) | |
) | |
// -------------------------------------------------- | |
val routes = ZioHttpInterpreter().toHttp(List(helloRoute) ++ apiDocRoute) | |
val server = for { | |
_ <- ZIO.log("API documentation : http://127.0.0.1:8080/docs") | |
_ <- Server.serve(routes) | |
} yield () | |
override def run = server.provide(Server.default) | |
} | |
WebApp.main(Array.empty) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment