Skip to content
This repository has been archived by the owner on Jan 23, 2024. It is now read-only.

Commit

Permalink
refactor(http4s): simplify structure
Browse files Browse the repository at this point in the history
  • Loading branch information
JesusMtnez committed Sep 5, 2023
1 parent 3d1cbdb commit 56360b9
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 45 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A series of implemetations of [Todo-Backend][todo-backend] REST API in **Scala** using different libraries.

- [x] Using `http4s` with `cats-effect`
- [ ] Using `zio-http` with `zio`
- [x] Using `http4s` with `cats-effect`: see `todobackend-http4s` module
- [ ] Using `zio-http` with `zio`: see `todobackend-zio` module

[todo-backend]: https://www.todobackend.com/

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import org.typelevel.log4cats.slf4j.Slf4jFactory
import org.http4s.Method
import org.typelevel.ci.CIString

object TodoBackendServer {
object TodoBackendApp extends IOApp.Simple:
val run = startServer[IO]

def run[F[_]: Async: Network]: F[Unit] =
def startServer[F[_]: Async: Network]: F[Unit] =
implicit val loggerFactory: LoggerFactory[F] = Slf4jFactory.create[F]

val cors =
Expand All @@ -28,14 +29,11 @@ object TodoBackendServer {
)
)
.withAllowHeadersIn(Set(CIString("content-type")))

for {
repository <- TodoRepositoryImpl.inMemory[F]()
repository <- TodoRepository.inMemory[F]()
routes = TodoBackendRoutes.about[F]()
<+> TodoBackendRoutes.todo[F](repository)

httpApp <- cors(Logger.httpApp(true, true)(routes.orNotFound))
_ <- EmberServerBuilder.default[F].withHttpApp(httpApp).build.useForever
} yield ()

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,30 @@ import es.jesusmtnez.todobackend.domain.TodoItem

import java.util.UUID

object TodoRepositoryImpl {
trait TodoRepository[F[_]] {
def create(title: String, order: Option[Int]): F[Option[TodoItem]]
def delete(id: UUID): F[Unit]
def deleteAll(): F[Unit]
def getAll(): F[List[TodoItem]]
def getById(id: UUID): F[Option[TodoItem]]
def update(
id: UUID,
title: Option[String],
completed: Option[Boolean],
order: Option[Int]
): F[Option[TodoItem]]
}

object TodoRepository:

def inMemory[F[_]: Sync](): F[TodoRepository[F]] =
Ref[F]
.of(Map.empty[UUID, TodoItem])
.map(new InMemory[F](_))

private final case class InMemory[F[_]: Sync](
private val store: Ref[F, Map[UUID, TodoItem]]
) extends TodoRepository[F] {
) extends TodoRepository[F]:

override def create(
title: String,
Expand Down Expand Up @@ -62,12 +82,3 @@ object TodoRepositoryImpl {
.fold(items)(item => items.removed(id) + (id -> item))
}
.map(_.get(id))
}

def inMemory[F[_]: Sync](): F[TodoRepository[F]] =
Ref[F]
.of(Map.empty[UUID, TodoItem])
.map(
new InMemory[F](_)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import es.jesusmtnez.todobackend.domain.TodoItem

class InMemoryRepositorySuite extends CatsEffectSuite {

val repository = TodoRepositoryImpl.inMemory[IO]()
val repository = TodoRepository.inMemory[IO]()

test("getAll should return empty when there are no items"):
for {
Expand Down

0 comments on commit 56360b9

Please sign in to comment.