by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 08:28
    codecov-commenter commented #1263
  • 08:21
    scala-steward opened #1263
  • Sep 18 18:55
    benjumanji closed #1262
  • Sep 16 17:30
    benjumanji commented #1262
  • Sep 16 11:08
    sergeykolbasov commented #1262
  • Sep 16 11:08
    sergeykolbasov commented #1262
  • Sep 15 23:56
    benjumanji edited #1262
  • Sep 15 23:39
    benjumanji edited #1262
  • Sep 15 23:38
    benjumanji edited #1262
  • Sep 15 23:38
    benjumanji opened #1262
  • Sep 15 14:02
    hderms commented #1254
  • Sep 07 20:28
    codecov-commenter commented #1261
  • Sep 07 20:21
    scala-steward opened #1261
  • Sep 03 15:22
    codecov-commenter commented #1260
  • Sep 03 15:15
    scala-steward opened #1260
  • Sep 02 07:06
    codecov-commenter commented #1259
  • Sep 02 06:59
    scala-steward opened #1259
  • Aug 31 02:26
    codecov-commenter commented #1258
  • Aug 31 02:19
    scala-steward opened #1258
  • Aug 26 22:33
    codecov-commenter commented #1257
Thomas Santana
@nebulorum

I've been building in finch for a couple of week and using the Cookbook and user guide as much as possible. I really liked the idea of composing Endpoints. So I attempted to build one with mapOutputAsync and twitter.util.Futures.

def checkToken: com.twitter.util.Future[TokenInfo]  = ???
val authenticated: Endpoint[IO, TokenInfo] = header(Fields.Authorization).mapOutputAsync {
     checkToken(header).map(Ok)
}

This does not work since of header unlike get there are not Mapper for the future. I found a way via twitter Future to scala Future (form the cookbook with IO.pure, and IO.fromFuture). But I wonder if there is a way to do this without this step. I also tried to use io.catbirds.util but could not find a good way. Ony one have a better solution?

Sergey Kolbasov
@sergeykolbasov
Shortly, you need a conversion to IO anyway, but there is indeed a way to skip intermediate hop through Scala Future
Thomas Santana
@nebulorum
Shouldn't this conversion be applied on the other EndpointModules?
Thomas Santana
@nebulorum
This worked for me: def toIO[A](f: TFuture[A]): IO[A] = ToAsync.twFutureToAsync[IO].apply(f). However I feeling this is not the correct use. Is there a cleaner way?
Sergey Kolbasov
@sergeykolbasov
Yep, make checkToken returning you IO :)
I'd suggest to fallback to Future (if it's really required) somewhere on the very edge of the application where the actual I/O happens
Thomas Santana
@nebulorum
Sergey I get your suggestion of limiting the use of Future. From the looks of all Cat Effect/IO discussions Future is not the correct abstraction. But since Finch run on top of Finagle, doesn't it make sense to leverage the capabilities? Is there a more Effect way of using Finagle?
Sergey Kolbasov
@sergeykolbasov

@nebulorum there is no simple answer here, especially on "correctness" of abstraction.

Personally I'd prefer to use F[_] inside the application instead of fixing on a specific monad, would it be Future, IO or Task.

Speaking of Twitter Future, the only "killer feature" comparing to cats.effect.IO is LocalContext that is somewhat similar to Java's ThreadLocal and might be quite handy to use. I.e. monix Task provides similar capabilities.

We use ReaderT[IO, RequestEnv, *] monad instead to have the same set of capabilities but also keep referential transparency.

If you keep Future outside of your application logic, there is no difference from your app perspective on what happens outside
Octav Zaharia
@octavz

it looks weird indeed
is type for helloWorld and combos set explicitly?

@sergeykolbasov i was missing addSbtPlugin("org.lyranthe.sbt" % "partial-unification" % "1.1.2")

Thijs
@ThijsBroersen
When an exception is throw within one of the encoders the service returns a 500 and no error is logged. Is there any way I can add a specific exception handler to a service or part of a service, e.g. .serve[Application.Json](api).onErrorHandleWith(myhandler) ?
Ryan Plessner
@rpless
@ThijsBroersen you can use api.handle() in that case. Although I thought encoding errors also go through the Encoder for Exception which is usually what I've used for handling that
Dermot Haughey
@hderms
we were figuring we'd be able to do something lke
withAuth :: someOtherEndpoint
withAuth being like Endpoint[User
but predictably there is no JSON encoder for User so this doesn't work
Dermot Haughey
@hderms
it seems like this form of composition just won't work for us which makes it hard for us to understand how we could blanketly add auth to a collection of endpoiints
from one perspective we could make sure User has a JSON codec and then perhaps it would work but it seems kind of hacky
Dermot Haughey
@hderms
I got it to work with an Endpoint[HNil] which isn't ideal but will more or less work for us
definitely was a bit confusing
Stefan Dietiker
@d-s-d
@hderms Why would you need an Encoder for User?
Dermot Haughey
@hderms
Alfredo Torre
@sentenza
Hey guys. I need some help here. I've just started using Finch and I was looking for a tutorial or some docs/examples on how to create a sort of "route decorator". I want to create a set of authenticated routes verifying JWT tokens produced by Auth0, but in order to do that I should execute a monadic flow (within cats.IO I guess) and check whether return a 401 or not at the end of the world.
Alfredo Torre
@sentenza
for instance in Play you can use the action composition to execute a check before executing the actual action like a sort of action decorator https://www.playframework.com/documentation/2.7.x/ScalaActionsComposition#Custom-action-builders
Ryan Plessner
@rpless
@sentenza are you using the old finch artifacts or the new finchx artifacts that make use cats effect? If you are using the ones with cats effect you can do something like this https://github.com/finagle/finch/blob/master/examples/src/main/scala/io/finch/middleware/Main.scala#L32
and only apply it to a subset of your endpoints
Frederick Cai
@zhenwenc
Hello, is there any good docs around for finchx? It's kinda confusing while reading the finch docs but using finchx :joy_cat:
Alfredo Torre
@sentenza

@sentenza are you using the old finch artifacts or the new finchx artifacts that make use cats effect? If you are using the ones with cats effect you can do something like this https://github.com/finagle/finch/blob/master/examples/src/main/scala/io/finch/middleware/Main.scala#L32

I'm using the new ones (finchx) so I guess that will solve my problem, but now I'm wondering how exactly I should take advantage of that middleware in my endpoints.

val auth: Endpoint.Compiled[IO] => Endpoint.Compiled[IO]  // where should I put the auth middleware?

val authFilter = Function.chain(Seq(auth))
val compiled = filters(Bootstrap.serve[Text.Plain](myEndpoint).compile)
// Endpoint.toService(compiled) ??

Is there any way to directly apply the authFilter on my endpoints?

Sergey Kolbasov
@sergeykolbasov
authFilter is just a function from Endpoint.Compiled to Endpoint.Compiled
so any compiled endpoint (in the example is myEndpoint) will be the subject of filtering once it's passed to the function
Sergey Kolbasov
@sergeykolbasov
However, Ryan mentioned that you can apply it only to subset of Endpoints. While in theory you can, you will end up with two compiled endpoints (that are just Kleisli) and combination of them is tricky, lawful one is even impossible, i.e. you can't distinguish 404 from endpoint not found and 404 from one of the endpoints as the resulting value. Therefore, you have to apply it to all the endpoints and check some preconditions in the middleware like path, method and whatever

If you don't like the case I mentioned and don't care about applicative nature of :: composition and the fact, that all the endpoints in this composition are evaluated to accumulate the errors, you can implement your own endpoint:

val auth: Endpoint[IO, HNil] = new Endpoint { .. } //or just header.mapOutputAsync depending on how you handle auth

And then compose it with those you need to protect:

get("foo" :: "bar" :: auth) { Ok("protected") }
Sergey Kolbasov
@sergeykolbasov
But beware that in :: composition all the endpoints evaluated unless one of them returns NotMatched. Since authentication for you is effectful, meaning it returns IO, you can't return NotMatched outside of IO. Therefore, you will have to return Matched result with failed output IO[Output] in case of authentication failure. In that case the rest of :: endpoints in the same composition scope are still evaluated for the sake of error accumulation. Say, you have JSON body to parse, then it'll be checked instead of failing fast. Nevertheless, Ok("protected") is never evaluated & returned if at least one of the endpoints in the corresponding composition fails with error, so in that context it's safe
Frederick Cai
@zhenwenc
Hi friends! I am wondering is there any tool available to document Finch endpoints, like swagger? Ideally auto(or semi-auto)-generated.
Sergey Kolbasov
@sergeykolbasov

Hi

No, sadly there is no tool to derive swagger from Finch endpoints

Frederick Cai
@zhenwenc
I found this lib (https://github.com/softwaremill/tapir) seems can be a good candidate. May require documenting each endpoints manually, but their syntax looks very similar to Finch(x).
Georgi Krastev
@joroKr21
Would be nice for someone to add a Finch interpreter to tapir :D
Sergey Kolbasov
@sergeykolbasov
I would say, straight to Finagle service then
Frederick Cai
@zhenwenc
Hmm...
Ryan Plessner
@rpless
yeah I'd say Tapir directly to Finagle is the way to go if you want to leverage Tapir. it also seems like they have a Finatra interpreter
Larry Bordowitz
@lbordowitz
What's the point of item in Endpoint?
Vladimir Kostyukov
@vkostyukov
It’s used for generating a more useful Error instance
Larry Bordowitz
@lbordowitz
Anything else?
Vladimir Kostyukov
@vkostyukov
I don’t think so. I personally wanted to remove them for a long time but haven’t figured a better way to propagate this meta information down to an Error instance.
Larry Bordowitz
@lbordowitz
I was thinking of implementing an item-like Monad to collect information for specification documents like OpenAPI
Sorta expanding the scope of item instead of removing it, sorry :P
Vladimir Kostyukov
@vkostyukov
Yeah, I think Sergey was experimenting with this as well. finagle/finch#880
Larry Bordowitz
@lbordowitz
That's a really nice pointer, thank you for that! Should it be a separate field like meta, or expand item?