72 lines
2.1 KiB
Scala
72 lines
2.1 KiB
Scala
|
|
package lu.foyer
|
||
|
|
|
||
|
|
import lu.foyer.clients.ClientState
|
||
|
|
|
||
|
|
import zio.*
|
||
|
|
import zio.Console.*
|
||
|
|
import zio.http.*
|
||
|
|
import zio.schema.*
|
||
|
|
import zio.http.endpoint.*
|
||
|
|
import zio.http.codec.*
|
||
|
|
import java.net.URI
|
||
|
|
import zio.http.endpoint.openapi.OpenAPIGen
|
||
|
|
import zio.http.endpoint.openapi.SwaggerUI
|
||
|
|
import zio.http.codec.PathCodec.path
|
||
|
|
|
||
|
|
case class JsonApiResponseSingle[T](
|
||
|
|
data: JsonApiResponseEntity[T],
|
||
|
|
links: JsonApiResponseLinks)
|
||
|
|
derives Schema
|
||
|
|
|
||
|
|
case class JsonApiResponseMultiple[T](
|
||
|
|
data: List[JsonApiResponseEntity[T]],
|
||
|
|
links: JsonApiResponseLinks,
|
||
|
|
meta: JsonApiResponseMeta)
|
||
|
|
derives Schema
|
||
|
|
|
||
|
|
case class JsonApiResponseLinks(
|
||
|
|
self: String,
|
||
|
|
first: Option[String] = None,
|
||
|
|
prev: Option[String] = None,
|
||
|
|
next: Option[String] = None,
|
||
|
|
last: Option[String] = None)
|
||
|
|
derives Schema
|
||
|
|
|
||
|
|
case class JsonApiResponseMeta(totalRecords: Int, totalPages: Int) derives Schema
|
||
|
|
|
||
|
|
final case class JsonApiResponseEntity[T](id: String, `type`: String, attributes: T) derives Schema
|
||
|
|
|
||
|
|
case class Page(number: Int, size: Int, totals: Boolean)
|
||
|
|
|
||
|
|
val pageParams =
|
||
|
|
(HttpCodec.query[Option[Int]]("page[number]")
|
||
|
|
& HttpCodec.query[Option[Int]]("page[size]")
|
||
|
|
& HttpCodec.query[Option[Boolean]]("page[totals]"))
|
||
|
|
.transform[Page]((number, size, totals) =>
|
||
|
|
Page(number.getOrElse(0), size.getOrElse(50), totals.getOrElse(false))
|
||
|
|
)(p => (Some(p._1), Some(p._2), Some(p._3)))
|
||
|
|
|
||
|
|
object ClientsController:
|
||
|
|
private val fetchMany =
|
||
|
|
Endpoint(Method.GET / "clients").query(pageParams).out[JsonApiResponseMultiple[ClientState]]
|
||
|
|
|
||
|
|
private val fetchManyRoute =
|
||
|
|
fetchMany.implement(page =>
|
||
|
|
ZIO.succeed(
|
||
|
|
JsonApiResponseMultiple[ClientState](
|
||
|
|
List.empty,
|
||
|
|
JsonApiResponseLinks("https://api.example.org"),
|
||
|
|
meta = JsonApiResponseMeta(0, 1)
|
||
|
|
)
|
||
|
|
)
|
||
|
|
)
|
||
|
|
|
||
|
|
val endpoints = List(fetchMany)
|
||
|
|
val routes = Routes(fetchManyRoute)
|
||
|
|
|
||
|
|
object App extends ZIOAppDefault:
|
||
|
|
val openAPI = OpenAPIGen.fromEndpoints(ClientsController.endpoints)
|
||
|
|
val routes = ClientsController.routes ++ SwaggerUI.routes("docs" / "openapi", openAPI)
|
||
|
|
|
||
|
|
override def run = Server.serve(routes).provide(Server.default)
|