Http4s middleware - example with a resource being used by routes #947
Answered
by
armanbilge
adamjuhasz
asked this question in
Q&A
-
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.
Answered by
armanbilge
Jan 19, 2024
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.
5 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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], *]]
.