http4s-steward[bot] on http4s-scala-xml-0.23.11
http4s-steward[bot] on http4s-scala-xml-0.23.12
Update http4s-scala-xml to 0.23… (compare)
http4s-steward[bot] on http4s-server-0.23.13
Update http4s-circe, http4s-dsl… (compare)
http4s-steward[bot] on scala-library-2.12.15
http4s-steward[bot] on scala-library-2.12.16
Update scala-library, scala-ref… (compare)
http4s-steward[bot] on silencer-lib-1.7.8
http4s-steward[bot] on silencer-lib-1.7.9
Update silencer-lib, silencer-p… (compare)
typelevel-steward[bot] on swagger-ui-4.11.1
Update swagger-ui to 4.11.1 (compare)
class Routes[F[+_]: Sync](service: FooService[F]) extends RhoRoutes[F] {
private def handleError(t: Throwable): F[BaseResult[F]] = t match {
case e: CustomError =>
BadGateway(e)
case _ =>
InternalServerError(UnexpectedError)
}
GET / "api" +? param[Int]("id") |>> { id: Int =>
service
.getFoo(id)
.flatMap { foo =>
Ok(foo).widen[BaseResult[F]]
}
.handleErrorWith(handleError)
}
}
widen
InternalServerError(someEmptyFooInstance)
but it wouldn't compile either
val authUser: Kleisli[IO, Request[IO], Either[String, User]] = Kleisli { req =>
IO(Right(User("Bob", UUID.randomUUID())))
}
val onFailure: AuthedRoutes[String, IO] = Kleisli(req => OptionT.liftF(Forbidden(req.authInfo)))
val middleware = AuthMiddleware(authUser, onFailure)
object Auth extends AuthedContext[IO, User]
object BobRoutes extends RhoRoutes[IO] {
GET +? param("foo", "bar") >>> Auth.auth |>> { (foo: String, user: User) =>
Ok(s"Bob with id ${user.id}, foo $foo")
}
}
val service = middleware.apply(Auth.toService(BobRoutes.toRoutes()))
This code is copied from AuthedContext.scala
. But the Forbidden
part is still "not found" after import bulk of things to make other part of code works... By the way, how to make service
available for BlazeServerBuilder
, or convert to HttpApp
...?
Many thx!
val jwtStatelessAuthenticator =
JWTAuthenticator.pstateless.inHeader[F, User, HMACSHA256](
signingKey = signingKey,
settings = TSecJWTSettings(JWT_AUTH_HEADER, FiniteDuration(24L * 3600L, TimeUnit.SECONDS), None)
)
val authUser: Kleisli[OptionT[F, ?], Request[F], User] = Kleisli({ req =>
if (userAuthentication) {
jwtStatelessAuthenticator
.extractAndValidate(req)
.map(_.identity)
} else {
OptionT.pure[F](User.dummy)
}
})
private[auth] val defaultNotAuthenticated: AuthedRequest[F, String] => OptionT[F, Response[F]] =
req => OptionT.liftF(Forbidden(req.authInfo))
val onAuthFailure: AuthedRoutes[String, F] = Kleisli(defaultNotAuthenticated)
val authenticated: AuthMiddleware[F, User] =
AuthMiddleware.withFallThrough(authUser)
F[_]
instead of IO
. Is RhoRoutes suitable for that? I guess it is, although all the example code / documentation uses IO
. The reason I'm asking for is I have a route that returns different status codes based on some intermediate results and it works fine with IO
but I can't get it to be of the required F[Result[...]]
type with F[_]:ConcurrentEffect
, instead it just defaults to Any
As far as Intellij's shw implicits feature goes I can't see any difference. My ConcurrentEffect
is being picked up instead of ioEffect
which seems to be fine.
Hello there. Is it possible to get this feature backported to the 0.19.x releases series? We are stuck using the 0.20.x Http4s series right now, and we're trying to build some functionality that depends on the content-type headers:
Happy to open a PR against a branch if one is opened for me.
@zarthross is this something you can help me out with? We're using Rho internally but this is kind of a roadblock for us. We want to have a route support multiple content-types (e.g. json and proto), and we want to use the content-type header to control that. The Swagger document will unfortunately not work properly for this use case without that backport.
We are using 0.19.x because our team is still supporting Scala 2.11 at this time (and that cannot be changed until other vendor changes are completed).
Hello, I updated ther dependencies in my project,
cats-core = 2.1.1
cats-effect = 2.1.2
rho-swagger = 0.20.0
http4s-blaze-server = 0.21.0
now, I have a problem in start the project, the error is
Could not find an instance of Applicative for [x]F[x]
[error] server <- BlazeServerBuilder[F]
[error] ^
Any suggestions to solve this error?, The code is this
import cats.effect.{ConcurrentEffect, ContextShift, ExitCode, IO, IOApp, Resource, Timer}
import co.yyyy.xxxxAPI
import org.http4s.server.Server
import org.http4s.server.blaze.BlazeServerBuilder
object Main extends IOApp {
def run(args: List[String]): IO[ExitCode] =
AppServer.create.use(_ => IO.never).as(ExitCode.Success)
}
object AppServerSwagger {
def create[F[+_]: ConcurrentEffect: ContextShift: Timer]: Resource[F, Server[F]] =
for {
server <- BlazeServerBuilder[F]
.withHttpApp(xxxxAPI[F].httpApi)
.bindLocal(8085)
.resource
} yield server
}
Any error message
[error] found : cats.effect.Resource[[x]F[x],Nothing]
[error] required: cats.effect.Resource[F,org.http4s.server.Server[F]]
[error] config <- Resource.liftF(parser.decodePathF[F, DefaultConfig]("app"))
[error] ^
pathVar
s not supported like query param
s in terms of Enums? See above. Both use a StringParser based on an Enumeratum enum, but the path param comes through odd
implicit def producerTypeStringParser[F[_]]: StringParser[F, ProducerType] =
new StringParser[F, ProducerType] {
override def parse(
s: String
)(implicit F: Monad[F]
): ResultResponse[F, ProducerType] =
try SuccessResponse(ProducerType.withName(s))
catch {
case _: NoSuchElementException =>
FailureResponse.pure[F] {
BadRequest.pure(s"Invalid ProducerType format: '$s'")
}
}
override val typeTag: Option[TypeTag[ProducerType]] = Some(
implicitly[TypeTag[ProducerType]]
)
}
This is my StringParser FWIW
val myIdsList = paramD[List[Long]]("myIds", "Some ids")
which works as expected: it parses ?myIds=1&myIds=2
to a List[Long]
. However, how can I use my own StringParser[IO, List[Long]]
instead of QueryParsers.multipleParse
? I'd like to manually parse ?myIds=1,2
to List[Long]
.
The above came up during an upgrade from v0.19.0
to v0.20.0
where I noticed that suddenly, our custom StringParser[IO, List[Long]]
wasn't picked up and instead, QueryParsers.multipleParse
was being used.
What I see is that v0.19.0
's multiParse()
is defined for Seq[_]
while v0.20.0
's multiParse()
is defined for generic B[_]
.
I also see that QueryParsers.standardCollector
and QueryParsers.multiParse
are defined in the same scope. Would it help here if standardCollector
had higher priority than multiParse()
?
multiParse
by defining the following: implicit def http4sMultipleParseOverride[A](
implicit F: Monad[IO],
p: StringParser[IO, List[A]],
cbf: Factory[A, List[A]]
): QueryParser[IO, List[A]] =
standardCollector[List[A]](F, p)