I am trying to run my webapp that is based on http4s on jetty. The http4s library provides AsyncHttp4sServlet[IO] class to extend and I use as follows:
class UserSvcServlet
extends AsyncHttp4sServlet[IO](
service = UserSvcServer.start,
servletIo = BlockingServletIo(4096, Blocker.liftExecutorService(Executors.newCachedThreadPool())),
serviceErrorHandler = DefaultServiceErrorHandler
)
As you can see on the service
property, I provide my http service that has the following implementation:
def start[F[_]: ConcurrentEffect: ContextShift: Sync: Timer]: HttpApp[F] =
for {
a <- EnvironmentLoader.db.load[F].map(create_transactor)
b <- EnvironmentLoader.cors.load[F].map(origin)
http = Logger.httpApp(true, true)(CORS(UserRoutes(UserProgram(LiveUserQuery.make(a))).routes, b).orNotFound)
} yield http
The start
method should return HttpApp[F]
but unfortunately the for
block returns F[Http[F]]
. However at the end the F
will be an IO
type.
Here is the definition of HttpApp[F]
:
type Http[F[_], G[_]] = Kleisli[F, Request[G], Response[G]]
The both EnvironmentLoader.db.load[F].map(create_transactor)
and EnvironmentLoader.cors.load[F].map(origin)
is in the context of F
and they load environment variables. For loading environment variables, I use the library https://cir.is/.
I know, it is not possible to get Http[F]
out of the context F
. Do I have here to restructure the code to make it work?
Update
One possible workaround would be:
class UserSvcServlet
extends AsyncHttp4sServlet[IO](
service = UserSvcServer.start[IO].unsafeRunSync(),
servletIo = BlockingServletIo(4096, Blocker.liftExecutorService(Executors.newCachedThreadPool())),
serviceErrorHandler = DefaultServiceErrorHandler
)
It is ugly but it works.