Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jan 15 19:29
    scala-steward closed #1300
  • Jan 15 19:29
    scala-steward commented #1300
  • Jan 15 19:29
    scala-steward opened #1315
  • Jan 11 17:25
    r2d2-94 commented #544
  • Jan 05 20:35
    codecov-io commented #1314
  • Jan 05 19:30
    scala-steward closed #1304
  • Jan 05 19:30
    scala-steward commented #1304
  • Jan 05 19:30
    scala-steward opened #1314
  • Dec 24 2020 10:14
    codecov-io commented #1313
  • Dec 24 2020 10:05
    scala-steward closed #1307
  • Dec 24 2020 10:05
    scala-steward opened #1313
  • Dec 23 2020 20:34
    mfirry commented #1278
  • Dec 23 2020 19:30
    scala-steward opened #1312
  • Dec 23 2020 17:32
    mfirry commented #1278
  • Dec 20 2020 15:41
    codecov-io commented #1311
  • Dec 20 2020 15:30
    scala-steward closed #1292
  • Dec 20 2020 15:30
    scala-steward opened #1311
  • Dec 19 2020 03:24
    codecov-io commented #1310
  • Dec 19 2020 03:15
    scala-steward closed #1295
  • Dec 19 2020 03:15
    scala-steward opened #1310
ComFreek
@ComFreek
Not even this works:
import io.finch._
import cats.effect.IO
import com.twitter.finagle.Http
import com.twitter.io.Buf
import com.twitter.util.Await

object Test extends App with Endpoint.Module[IO] {
  implicit val encodeException: Encode.Text[Exception] =
    Encode.text((_, cs) => Buf.ByteArray.Owned("ERR!".getBytes(cs.name)))

  val api: Endpoint[IO, String] = get("hello") {
    throw new Exception("test")
    Ok("Hello, World!")
  }
  Await.ready(Http.server.serve(":8080", api.toServiceAs[Text.Plain]))
}
http://127.0.0.1:8080/hello does not output ERR! in the browser
Sergey Kolbasov
@sergeykolbasov

Hello @ComFreek

It's a bit trickier. That default encoder covers only "exceptions" inside of Output, i.e. BadRequest(new Exception("test"))

If you would like to cover all the exceptions, you need to set up filter on top of finagle's Service[Request, Response] or use middleware filters like here:
https://github.com/finagle/finch/blob/master/examples/src/main/scala/io/finch/middleware/Main.scala
shortly speaking in Finch we prefer to avoid exceptions as a mechanism and rather deal with errors as values, as it's much cleaner and easier to reason about
import io.finch._
import cats.effect.IO
import com.twitter.finagle.Http
import com.twitter.io.Buf
import com.twitter.util.Await

object Test extends App with Endpoint.Module[IO] {
  implicit val encodeException: Encode.Text[Exception] =
    Encode.text((_, cs) => Buf.ByteArray.Owned("ERR!".getBytes(cs.name)))

  val api: Endpoint[IO, String] = get("hello") {
    if (Random.nextBoolean()) {
      Ok("Hello, World!")
    } else {
      BadRequest(new Exception("oh no"))
    }
  }
  Await.ready(Http.server.serve(":8080", api.toServiceAs[Text.Plain]))
}
This should work
ComFreek
@ComFreek
@sergeykolbasov I understand your philosophy on values over exceptions, but for debugging receiving just a 500 Internal Server Error is utterly lacking.
I need those stack traces
Let me see if I can get the filter approach working
Sergey Kolbasov
@sergeykolbasov

It's a method of IO.

Although, it works for any F[_] : Apply with import cats.syntax.all._

ComFreek
@ComFreek
Does that look idiomatic?
If so, any chance we can integrate this in the Finch docs somehow?
(not necessarily the full code, a simplified version might suffice)
Sergey Kolbasov
@sergeykolbasov
I have a plan to make a major update on the documentation, but probably after Black Friday, as now we're quite busy
ComFreek
@ComFreek
Okay, great. HTTP 500 errors without response body costed me more debugging hours than I am willing to admit.
ComFreek
@ComFreek
How can I serve two endpoints with different encodings? Say, the default of my app should be JSON, but one particular endpoint should be plain text.
I have something like:
override protected def getCompiledOverallEndpoint(state: ServerState): Endpoint.Compiled[IO] =
  Bootstrap.serve[Application.Json](getEndpointsForState(state)).compile :+: ???
but my trial of :+: doesn't work: that operator doesn't exist on compiled endpoints apparently
ComFreek
@ComFreek
got it
Bootstrap
      .serve[Application.Json](getJSONEndpointsForState(state))
      .serve[Text.Plain](getTextEndpointsForState(state))
      .compile
Ayoub
@I_am_ayoub_twitter

Hi,
I have strange error while trying to compile one of the examples:
https://github.com/finagle/finch/blob/master/examples/src/main/scala/io/finch/iteratee/Main.scala#L54
the error is could not find implicit value for parameter LR: io.finch.LiftReader[io.iteratee.Enumerator,cats.effect.IO]
I don't see what it is missing especially that I copied exactly the same imports
this is my build

          "com.github.finagle"   %% "finchx-core"     % 0.32.1",
          "com.github.finagle"   %% "finchx-circe"    % 0.32.1",
          "com.github.finagle"   %% "finchx-iteratee" % 0.32.1",

Am I missing some library or import ? Anyone have an idea ?

Ayoub
@I_am_ayoub_twitter
ah fixed the issue, it seems that import io.finch.iteratee._ was missing and it wasn't needed in the example because it was the same package
Beck Gaël
@beckgael
Hi, as a scala addict and pretty new to microservice world, i'm seriously thinking to do my next project using pure scala library to build my services, unfortunately i'm not sure about my options, i believe than Play will have to many unused functionalities for my use case, then here i am stuck between Finagle, Finch, and Finatra. Knowing that those two last are both built on top of Finagle. What reasoning should i have to make my choice between those three nice frameworks ?
Thank you
Sergey Kolbasov
@sergeykolbasov

Hey @beckgael

Finatra & Play provide you with opionated and out-of-the-box solutions, while Finch is minimalistic & highly-customizable, but requires more investments in setting up things manually.

Essentially, it depends on you. If you wish to have an absolute control over your application, it's easier to obtain it with Finch. If you're looking for something to quickly start with, but willing to give up some of the control to the framework: roll with Play or Finatra

i.e. in Finch you decide what effect type you're going to use: IO, Task, ZIO, Kleisli or whatever

in Play & Finatra you're stuck with Scala or Twitter Future respectively. So there is that.

With Finch you can pick out of many JSON libraries to encode & decode data in your API, in Finatra I believe you have to deal with Jackson.

etc etc

I have plans to set up some kind of Finch-baked opionated bootstrap, so people would have easier time to start with it, but atm I'm quite busy with work
tpetillot
@tpetillot

endpoint.toServiceAs[Text.Html] require Endpoint returned type to be com.twitter.finagle.http.Response.
But status of the given response will be ignored, in favor of the io.finch.Outputs status.

So is there a way to not specify the status on com.twitter.finagle.http.Response ?

tpetillot
@tpetillot
Also, is it possible to serve multiple services ? As I need to serve assets which are not Text.Html, but Text.Css.
Ryan Plessner
@rpless
@tpetillot If your html and css are located at different paths you can use the Bootstrap to serve them with different return types. https://github.com/finagle/finch/blob/f1e7ed1c9b43d83138bc1edae4737785d676209b/core/src/main/scala/io/finch/Bootstrap.scala#L12-L16
tpetillot
@tpetillot
Exactly what I was looking for @rpless , thanks a lot !
Have you any idea about the previous interogation ?
Ryan Plessner
@rpless
ah yes sorry, missed that. the toServiceAs[Text.Html] does not necessarily require Response, but if you use another type you'll most likely need to provide your own Encode.Aux[A, Text.Html]. to your question about the Response's status getting overridden by the Output's status, I would expect that. The why around it is to return the Response directly without the output wrapping it. Finch is able to serve both raw Response and things wrapped in Output
tpetillot
@tpetillot
Make perfect sense, thank you for your clarifications!
Christopher London
@Sicarius154

Hi all, I'm having some issues with CORS, it's my first time using Scala on an edge-service that communicates with a React client. Am I correct in thinking that using:

new Cors.HttpFilter(Cors.UnsafePermissivePolicy).andThen( (Bootstrap .serve[Application.Json]( ... .toService)

Will essentially disable CORS on the backend?

Marwan Rabbâa
@waghanza
Hi,
We try to add finch in the-benchmarker/web-frameworks#3675. This a benchmarking project. We care about having consent (or at least non-opposition) before doing such a thing. Do core dev / maintainers are not opposed of add finch in this list ?
Sergey Kolbasov
@sergeykolbasov
sure
Marwan Rabbâa
@waghanza
:heart:
Sergey Kolbasov
@sergeykolbasov
although, code looks a bit weird as to me
Marwan Rabbâa
@waghanza
honestly, I'm not a scala guy :stuck_out_tongue:, but feel free to review (that also a reason of asking for consent / approval)
Sergey Kolbasov
@sergeykolbasov

instead of

Bootstrap
      .serve[Text.Plain](root)
      .serve[Text.Plain](postUser)
      .serve[Text.Plain](getUserName)
      .toService

should be

Bootstrap
      .serve[Text.Plain](postUser :+: getUserName :+: root)
      .toService
I'll drop the comment in PR
Marwan Rabbâa
@waghanza
thanks
tpetillot
@tpetillot

Hi all!

Using Bootstrap.serve[Text.Html] on a endpoint containing finagle Response, content-type isn't added.
When added on response, it's alright, but then nothing should be specified on Bootstrap.serve which isn't possible.

From my understanding, serve[CT](A :: B :: CNil) compiled will look for io.finch.Encode types Aux[A, CT] and Aux[B, CT] if type isn't com.twitter.finagle.http.Response.

As it is a com.twitter.finagle.http.Response, CT should not be mandatory ?

What would be the right way ? I'm using scalatags, should I create an encoder for something like (Status, Option[TypedTag]) ?
How to serve Response without specifying content type as it's not use from Bootstrap ?

Sergey Kolbasov
@sergeykolbasov
hmm, it's a tricky one

from one hand, I understand your point on the lack of consistency

from the other hand, we don't want to mangle with user created Response as we assume they know what they're doing going with the low-level abstraction

so I'd say if you deal with responses directly, have it added there
although, in theory it's possible to check Content-Type header and update it if missing
tpetillot
@tpetillot
Thanks @sergeykolbasov , that's what I assume!