Http4s middleware - example with a resource being used by routes #947
-
Hey all! I'm trying to understand how to use natchez and natchez-http4s when the route requires a resource (such as database calls). Is there an example of this? When trying to send the database object to the routes I get the following type error around the resource I'm trying to use in the http routes.
object Application extends IOApp.Simple {
given logger: Logger[IO] = Slf4jLogger.getLogger[IO]
val epInIO: EntryPoint[IO] = Log.entryPoint[IO]("app")
def server(
xa: HikariTransactor[IO],
httpConf: HttpConfig
): Resource[IO, Server] =
for
ep: EntryPoint[IO] <- Resource.pure(epInIO)
db: Database[IO] = Database(xa)
ap = ep.liftT(NatchezMiddleware.server(rootRoutes(db))).orNotFound
server: Server <- EmberServerBuilder
.default[IO]
.withHost(httpConf.host)
.withPort(httpConf.port)
.withHttpApp(ap)
.build
yield server
override def run: IO[Unit] =
for
dbConf: DatabaseConfig <- DatabaseConfig.getConfig[IO]
httpConf <- HttpConfig.getConfig[IO]
program: Resource[IO, Unit] = for
xa: HikariTransactor[IO] <- Database.makePostgresResource[IO](dbConf)
_x: Server <- server(xa, httpConf)
yield ()
_ <- program.use(_ => IO.never)
yield ExitCode.Success
} def rootRoutes[F[_]: Trace: Concurrent: Logger](database: Database[F])(implicit
ev: MonadError[F, Throwable]
): HttpRoutes[F] = Router(
"/" -> (HealthRoutes[F].routes),
"/v1/security" -> (SecuritiesRoutes[F](database).routes)
)
object Database:
def apply[F[_]: Async: Logger](
xa: Transactor[F]
): Database[F] = new Database[F](
securities = SecuritiesRepository[F](xa),
identifiers = IdentifierRepository[F](xa),
securityTree = SecurityTreeRepository[F](xa),
events = EventRepository[F](xa)
)
def makePostgresResource[F[_]: Async: Logger](
config: DatabaseConfig
): Resource[F, HikariTransactor[F]] = for
ec <- ExecutionContexts.fixedThreadPool(config.nThreads)
xa <- HikariTransactor.newHikariTransactor[F](
driverClassName = "org.postgresql.Driver",
url = s"jdbc:${config.url}",
user = config.user,
pass = config.pass,
connectEC = ec,
logHandler = Some(mkLogger[F])
)
yield xa |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
The problem is that you have a If your Otherwise, you can manually implement a |
Beta Was this translation helpful? Give feedback.
Hmm, ok, let's try something different. Try initializing your database like this:
Then you will need to change
xa
to be aHikariTransactor[Kleisli[IO, Span[IO], *]]
.