Implement clients API
This commit is contained in:
parent
91584c18d5
commit
31014d1a0c
14 changed files with 474 additions and 228 deletions
|
|
@ -13,162 +13,12 @@ import java.net.URI
|
|||
import java.time.LocalDate
|
||||
import java.util.UUID
|
||||
|
||||
object JsonApiResponse:
|
||||
|
||||
case class One[T](
|
||||
data: Entity[T],
|
||||
links: Links)
|
||||
derives Schema
|
||||
|
||||
case class Many[T](
|
||||
data: List[Entity[T]],
|
||||
links: Links,
|
||||
meta: Meta)
|
||||
derives Schema
|
||||
|
||||
case class Links(
|
||||
self: String,
|
||||
first: Option[String] = None,
|
||||
prev: Option[String] = None,
|
||||
next: Option[String] = None,
|
||||
last: Option[String] = None)
|
||||
derives Schema
|
||||
|
||||
case class Meta(totalRecords: Option[Long], totalPages: Option[Long]) derives Schema
|
||||
|
||||
case class Entity[T](id: String, `type`: String, attributes: T) derives Schema
|
||||
|
||||
case class Error(message: String) derives Schema // TODO
|
||||
|
||||
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)))
|
||||
|
||||
trait CommandEngineController[Command: Schema, Event: Schema, State: Schema](
|
||||
entityName: String,
|
||||
commands: List[Command],
|
||||
commandEngine: CommandEngine[Command, Event, State]):
|
||||
|
||||
private val fetchMany =
|
||||
Endpoint(Method.GET / entityName)
|
||||
.query(pageParams)
|
||||
.out[JsonApiResponse.Many[State]]
|
||||
.outError[JsonApiResponse.Error](Status.InternalServerError)
|
||||
|
||||
private val fetchOne =
|
||||
Endpoint(Method.GET / entityName / string("entityId"))
|
||||
.out[JsonApiResponse.One[State]]
|
||||
|
||||
private val fetchEventsMany =
|
||||
Endpoint(Method.GET / entityName / string("entityId") / "events")
|
||||
.query(pageParams)
|
||||
.out[JsonApiResponse.Many[Event]]
|
||||
|
||||
private val fetchEventsOne =
|
||||
Endpoint(Method.GET / entityName / string("entityId") / "events" / string("eventId"))
|
||||
.out[JsonApiResponse.One[Event]]
|
||||
|
||||
private val commandsEndpoints = commands.map(command =>
|
||||
Endpoint(Method.POST / "clients" / "commands" / command.toString.toLowerCase)
|
||||
.in[Command]
|
||||
.out[JsonApiResponse.One[Event]]
|
||||
)
|
||||
|
||||
private val fetchManyRoute =
|
||||
fetchMany.implement(page =>
|
||||
commandEngine.stateRepo
|
||||
.fetchMany(page)
|
||||
.map(paged =>
|
||||
JsonApiResponse.Many(
|
||||
paged.items.map(entity =>
|
||||
JsonApiResponse.Entity(entity.entityId.toString, "todo", entity.data)
|
||||
),
|
||||
JsonApiResponse.Links("https://api.example.org"),
|
||||
meta = JsonApiResponse.Meta(paged.totals, None) // TODO
|
||||
)
|
||||
).mapError(e => JsonApiResponse.Error(e.getMessage))
|
||||
class ClientController(
|
||||
override val commandEngine: CommandEngine[ClientCommand, ClientEvent, ClientState])
|
||||
extends CommandEngineController[ClientCommand, ClientEvent, ClientState](
|
||||
"api:example:insurance",
|
||||
"client"
|
||||
)
|
||||
end CommandEngineController
|
||||
|
||||
object ClientController:
|
||||
private val fetchMany =
|
||||
Endpoint(Method.GET / "clients")
|
||||
.query(pageParams)
|
||||
.out[JsonApiResponse.Many[ClientState]]
|
||||
|
||||
private val fetchOne =
|
||||
Endpoint(Method.GET / "clients" / string("entityId"))
|
||||
.out[JsonApiResponse.One[ClientState]]
|
||||
|
||||
private val createCommand =
|
||||
Endpoint(Method.POST / "clients" / "commands" / "create")
|
||||
.in[ClientCommand.Create]
|
||||
.out[JsonApiResponse.One[ClientEvent]]
|
||||
|
||||
private val updateCommand =
|
||||
Endpoint(Method.PUT / "clients" / string("entityId") / "commands" / "udpate")
|
||||
.in[ClientCommand.Update]
|
||||
.out[JsonApiResponse.One[ClientEvent]]
|
||||
|
||||
private val disableCommand =
|
||||
Endpoint(Method.PUT / "clients" / string("entityId") / "commands" / "disable")
|
||||
.in[ClientCommand.Disable]
|
||||
.out[JsonApiResponse.One[ClientEvent]]
|
||||
|
||||
private val fetchEventsMany =
|
||||
Endpoint(Method.GET / "clients" / string("entityId") / "events")
|
||||
.query(pageParams)
|
||||
.out[JsonApiResponse.Many[ClientEvent]]
|
||||
|
||||
private val fetchEventsOne =
|
||||
Endpoint(Method.GET / "clients" / string("entityId") / "events" / string("eventId"))
|
||||
.out[JsonApiResponse.One[ClientEvent]]
|
||||
|
||||
private val fetchManyRoute =
|
||||
fetchMany.implement(page =>
|
||||
ZIO.succeed(
|
||||
JsonApiResponse.Many[ClientState](
|
||||
List.empty,
|
||||
JsonApiResponse.Links("https://api.example.org"),
|
||||
meta = JsonApiResponse.Meta(None, None)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
private val createCommandRoute =
|
||||
createCommand.implement(command =>
|
||||
ZIO.succeed(
|
||||
JsonApiResponse.One[ClientEvent](
|
||||
JsonApiResponse.Entity(
|
||||
id = "todo",
|
||||
`type` = "todo",
|
||||
ClientEvent.Created(
|
||||
lastName = command.lastName,
|
||||
firstName = command.firstName,
|
||||
birthDate = command.birthDate,
|
||||
drivingLicenseDate = command.drivingLicenseDate,
|
||||
phoneNumber = command.phoneNumber,
|
||||
email = command.email,
|
||||
address = command.address
|
||||
)
|
||||
),
|
||||
JsonApiResponse.Links("https://api.example.org")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val endpoints = List(
|
||||
fetchMany,
|
||||
fetchOne,
|
||||
createCommand,
|
||||
updateCommand,
|
||||
disableCommand,
|
||||
fetchEventsMany,
|
||||
fetchEventsOne
|
||||
)
|
||||
val routes = Routes(fetchManyRoute)
|
||||
end ClientController
|
||||
val layer = ZLayer.fromFunction(ClientController.apply)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue