Initial commit

This commit is contained in:
Paul-Henri Froidmont 2025-02-27 18:45:46 +01:00
commit 1919e4b72c
Signed by: phfroidmont
GPG key ID: BE948AFD7E7873BE
14 changed files with 640 additions and 0 deletions

View file

@ -0,0 +1,71 @@
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)