Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 12:40
    lukoyanov commented #3955
  • 12:39
    lukoyanov commented #3956
  • 12:39

    rossabaker on gh-pages

    updated site (compare)

  • 12:35
    lukoyanov commented #3956
  • 12:02

    cquiroz on main

    Port many tests using legacy ma… Merge pull request #3970 from c… (compare)

  • 12:02
    cquiroz closed #3970
  • 12:02
    cquiroz commented #3970
  • 08:48
    amiguez commented #3964
  • 08:38
    amiguez ready_for_review #3964
  • 08:35
    roomanidzee starred http4s/http4s
  • 06:58
    yanns commented #3894
  • 06:45
    yanns ready_for_review #3894
  • 06:45
    yanns edited #3894
  • 06:40
    rossabaker commented #3894
  • 06:28
    rossabaker commented #3969
  • 06:22
    rossabaker commented #3964
  • 03:05
    cquiroz commented #3970
  • 02:58
    rossabaker commented #3970
  • Nov 29 23:54
    SystemFw commented #3894
Simon Shine
@sshine
Thanks!
Yeah, I actually expected more of the type inference. Not sure why that didn't work.
Anton Sviridov
@keynmol
There's probably a terribly simple reason why it doesn't, but I'm failing to spot it right now..
Simon Shine
@sshine
That's beyond my learning goal for tonight. :-D
Anton Sviridov
@keynmol
for sure, there be dragons :) good luck with the rest
Simon Shine
@sshine
Thanks!
Ross A. Baker
@rossabaker
I'm starting some tickets for the LSUG event on Saturday. We always love help, but please leave those for the event. If you're looking for work, please join the http4s-dev Gitter. :smile:
Carlos Quiroz
@cquiroz
What is LSUG?
Ross A. Baker
@rossabaker
London Scala Users Group. Zainab Ali is organizing an open source contribution day for new contributors while maintainers are around to help.
the trick is that F[Option[A]] == OptionT[F, A]
David Gutsch
@gutscdav000

Hello, struggling with an interesting type error while converting blaze server to jetty. Was wondering if you all have seen this before?

required: org.http4s.HttpRoutes[IO]
found: org.http4s.HttpRoutes[cats.effect.IO]

I know I've had a similar error when I first setup my authentication middleware, but can't figure out what I did to solve it. Abbreviated source code below:

object Main extends IOApp with AuthenticationMiddleware with StrictLogging {
  def httpRoutes(transactor: doobie.Transactor[IO], blocker: Blocker): HttpRoutes[IO] = HttpRoutes.of[IO] {
    case req@POST -> Root / "login" =>
      req.as[UserInfo] flatMap (user => {
        logger.info(f"authenticating user: ${user}")
        AuthService.login(user, userModel)
      })
    case req@GET -> Root / "health" => Ok() // TODO: make this a real helathcheck
  }

  override def run(args: List[String]): IO[ExitCode] =
    JettyExampleApp.resource.use(_ => IO.never).as(ExitCode.Success)

  object JettyExampleApp {
    def builder[IO[_]: ConcurrentEffect: ContextShift: Timer](blocker: Blocker): JettyBuilder[IO] = {

      JettyBuilder[IO]
        .bindHttp(8080, "0.0.0.0")
        .mountService(httpRoutes(transactor, blocker), "") // Type Error Here
    }

    def resource[IO[_]: ConcurrentEffect: ContextShift: Timer]: Resource[IO, Server] =
      for {
        blocker <- Blocker[IO]
        server <- builder[IO](blocker).resource
      } yield server
  }
}
nigredo-tori
@nigredo-tori
@gutscdav000, here are your culprits: def builder[IO[_]... and def resource[IO[_].... You have a type parameter named IO, which is easily confused with the cats.effect.IO type.
David Gutsch
@gutscdav000
Thank you! out of curiosity where does the type IO come from? I'm familiar with cats IO.
nigredo-tori
@nigredo-tori
@gutscdav000, could you rephrase that? I'm not sure what you're asking.
David Gutsch
@gutscdav000

I wondered if IO was some kind of implicit type to scala or from http4s. To avoid ambiguity I converted the IO's to F and get the same error:

required: org.http4s.HttpRoutes[F]
found: org.http4s.HttpRoutes[cats.effect.IO]

I'm wondering if that narrows things down to something else.

  override def run(args: List[String]): cats.effect.IO[ExitCode] =
    JettyExampleApp.resource.use(_ => cats.effect.IO.never).as(ExitCode.Success)

  object JettyExampleApp {
    def builder[F[_]: ConcurrentEffect: ContextShift: Timer](blocker: Blocker): JettyBuilder[F] = {

      JettyBuilder[F]
        .bindHttp(8080, "0.0.0.0")
        .mountService(httpRoutes(transactor, blocker), "")
    }

    def resource[F[_]: ConcurrentEffect: ContextShift: Timer]: Resource[F, Server] =
      for {
        blocker <- Blocker[F]
        server <- builder[F](blocker).resource
      } yield server
Fabio Labella
@SystemFw
@gutscdav000 you might be importing the io._ syntax from http4s
nigredo-tori
@nigredo-tori

I wondered if IO was some kind of implicit type to scala or from http4s.

It's just cats.effect.IO.

To avoid ambiguity I converted the IO's to F and get the same error:

Hopefully it's a bit more clear now. The error message should point to the line where you have the issue. I think it's this one:

.mountService(httpRoutes(transactor, blocker), "")

mountService expects an HttpRoutes[F], but httpRoutes(transactor, blocker) returns an HttpRoutes[IO], so those two don't fit together. You'll have to do one of the following:

  1. Parameterize httpRoutes with an effect type (F) as you've done with the other functions.
  2. Remove parametrization from builder and, consequently, from resource.
  3. Restructure your program so that HttpRoutes are created outside builder, and passed as a parameter (so that the calling code will have to prove that F is IO).
David Gutsch
@gutscdav000

I think I understand so I remove the type signatures from builder and resource:

def resource: Resource[IO, Server] = ...
def builder(blocker: Blocker): JettyBuilder[IO] = ...

and parameterize httpRoutes:

def httpRoutes[F](transactor: doobie.Transactor[F], blocker: Blocker, userModel: UserModel): HttpRoutes[F] = HttpRoutes.of[F] { ... }

Thank you for your time btw

Mouna.
@muunaar
Hello everyone, Im dealing with pagination,. so to explain the context, the header returned in the response follows has a Link field having as a value : <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=15>; rel="next", <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=34>; rel="last", <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=1>; rel="first", <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=13>; rel="prev" Im thinking of extracting the last page number and iterate over it !! I want to do it in a way that it doesn't deal with string interpolation as it may present some issues in the future if the format of the link changes. Also I have read about OptionalQueryParamDecoderMatcher in http4s but I didn't know how to make use of it . Can anyone help please !! Im open to your ideas !!
David Gutsch
@gutscdav000
Perhaps something like this could work for you:
    object offsetMatcher extends OptionalQueryParamDecoderMatcher[Int]("offSet")
    object pageMatcher extends OptionalQueryParamDecoderMatcher[Int]("page")

   case req @ GET -> Root / "service" :? offsetMatcher(offset) +& pageMatcher(page)  => ...
Mouna.
@muunaar
Yetah I have seen this but I'm looking for the last page , and the link had two pages might be identified the next and the last and sometimes the previous too
macakmujo
@macakmujo
why I cant connect
httpAppMiddleware : http4s.HttpApp[F] =
Logger.httpApp(true, true)(routes)
  exitCode <- BlazeServerBuilder[F](global)
    .bindHttp(8080, "0.0.0.0")
    .withHttpApp(httpAppMiddleware)
    .withSslContext(SSLContext.getDefault)
    .resource
} yield exitCode
curl https://localhost:8080 --insecure
curl: (35) Server aborted the SSL handshake
macakmujo
@macakmujo
now only HTTPS is working
how to have HTTP AND HTTPS ?? THX :)
Yilin Wei
@yilinwei
@macakmujo Take a look at the snippet here. You can also have a proxy depending on your setup as well.
In particular the redirect from HTTP to HTTPS.
nigredo-tori
@nigredo-tori
@macakmujo, all the standard Server builders in the library bind to a single port. So if you have to bind to two ports, you'll have to build two servers. Note that this restriction arises from the chosen API rather then from the server libraries themselves - for example, JettyServerBuilder in jetty4s supports binding to two ports at the same time. And you can always avoid existing builders, and directly set up your server of choice in any way you see fit.
Ross A. Baker
@rossabaker
I think multiple connectors is something we ought to support in all backends. Blaze and Ember could do it with a little work, and as @nigredo-tori has demonstrated, it's quite natural for the servlet containers.
Keir Lawson
@keirlawson
what are the default/recommended/most mature client/server backends for http4s these days? Still Blaze for both?
Keir Lawson
@keirlawson
or perhaps more specifically, how mature/ready for production use is ember?
Ross A. Baker
@rossabaker
That's a difficult one to answer, because different people have had different experiences.
Blaze still dominates usage. It has the most known issues, but perhaps the fewest unrevealed issues.
Ember is easily the most maintainable, but still has a bit higher velocity of fixes.
The servlet backends have been quietly reliable for a few people, but again, for a few people.
On the client side, AHC seems to be a consensus favorite, but I've had a lot of problems with it. I like the jdk-http-client a lot, but that requires JDK11.
I hesitate to issue a blanket recommendation, but those are at least some pros and cons.
Keir Lawson
@keirlawson
Thanks for that detailed response :-)
Reason I ask is wanting to escape from ConcurrentEffect with Blaze/JDK, from what you say sounds like running ember in production at least isn't completely crazy :-)
Ross A. Baker
@rossabaker
Ember is your only escape hatch now. In Cats-Effect 3, most (all?) of them will be satisfied with Concurrent.
Keir Lawson
@keirlawson
:+1:
Ross A. Baker
@rossabaker
I think using the Kleisli tools, particularly Natchez, is driving Ember adoption.
Keir Lawson
@keirlawson
Yep, Natchez is what's pushing me there
Ross A. Baker
@rossabaker
You'd be an early adopter, but @ChristopherDavenport is pretty smart, and we'd all love to have more eyes on it.
Even though I don't think one will ever be best for all cirumstances, there's always going to be a natural default, and I would be happy if that shifted from Blaze to Ember. From a maintainer's perspective, it at least looks more like the rest of the code.
rnd4222
@rnd4222_gitlab
What is the practical reasons to avoid ConcurrentEffect?
Are you guys running your servers in a ReaderT-based stack, instead of using effect-translating-middleware?
Chris Jansen
@janstenpickle

@keirlawson bit of shameless self promotion, but Trace4Cats has syntax for lifting any http4s client or server into a trace context https://github.com/janstenpickle/trace4cats/blob/master/modules/example/src/main/scala/io/janstenpickle/trace4cats/example/Http4sExample.scala. This means you can construct a client or server that requires a ConcurrentEffect, then lift the client into a Kleisli.

It also can interoperate with Natchez https://github.com/janstenpickle/trace4cats/blob/master/modules/example/src/main/scala/io/janstenpickle/trace4cats/example/NatchezExample.scala

Mouna.
@muunaar

Perhaps something like this could work for you:

    object offsetMatcher extends OptionalQueryParamDecoderMatcher[Int]("offSet")
    object pageMatcher extends OptionalQueryParamDecoderMatcher[Int]("page")

   case req @ GET -> Root / "service" :? offsetMatcher(offset) +& pageMatcher(page)  => ...

Yeah I have seen this but I'm looking for the last page , and the link had two pages might be identified the next and the last and sometimes the previous too