by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 12:23
    scala-steward opened #1269
  • 08:28

    sergeykolbasov on master

    modified the document of sample… (compare)

  • 08:28
    sergeykolbasov closed #1250
  • 08:28
    sergeykolbasov commented #1250
  • 08:27

    sergeykolbasov on master

    docs/user-guide.md: add a few e… (compare)

  • 08:27
    sergeykolbasov closed #1268
  • Sep 25 13:40

    sergeykolbasov on update-docs

    Replace time example with the g… (compare)

  • Sep 25 13:16
    codecov-commenter commented #1268
  • Sep 25 13:09
    sergeykolbasov closed #1191
  • Sep 25 13:09
    sergeykolbasov closed #1264
  • Sep 25 13:09
    sergeykolbasov closed #1263
  • Sep 25 13:09
    sergeykolbasov closed #1261
  • Sep 25 13:09
    sergeykolbasov closed #1260
  • Sep 25 13:09
    sergeykolbasov closed #1259
  • Sep 25 13:09
    sergeykolbasov closed #1258
  • Sep 25 13:09
    sergeykolbasov closed #1257
  • Sep 25 13:09
    sergeykolbasov closed #1256
  • Sep 25 13:09
    sergeykolbasov closed #1255
  • Sep 25 13:09
    sergeykolbasov closed #1253
  • Sep 25 13:09
    sergeykolbasov closed #1252
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?
Maksym
@ratoshniuk

Hi there!

I am currently trying to use finch but got some issues with understanding of it's abstractions

I have multiple services and want to combine them while bootrstrapping

its it possible to do?

for example


val svc1: Service[Request, Response] = ???
val svc2:  Service[Request, Response] = ???

Http.server.serve(":8080", svc1 :+: svc2)
thanks for any help!
Sergey Kolbasov
@sergeykolbasov

Hi @ratoshniuk

Could you elaborate how did you end up with two Finagle services?

Usually, in finch you would combine Endpoints first using :+: operator, and only after that convert it to Finagle service, so routing would be handled for you.

If it's crucial to have multiple services, take a look at twitter-server HttpMuxer:
https://github.com/twitter/twitter-server/blob/master/server/src/test/scala/com/twitter/server/util/HttpUtilsTest.scala

Though you would need to handle routing there manually

Dermot Haughey
@hderms
@sergeykolbasov if you want finagle filters to only be applied to certain endpoints, but not others, wouldn't that imply you need separate finagle services?
we had an issue like that in the past which we resolved by having multiple finagle services (which we got rid of by writing a more finch-centric way of doing authorization/authentication)
Larry Bordowitz
@lbordowitz
Is there a way to make a list of endpoints, to use in a foreach and then also to "fold" (or something) into a coproduct?
Larry Bordowitz
@lbordowitz
Nevermind
Frederick Cai
@zhenwenc
@lbordowitz I had the same wonder earlier hah! Have you managed to find the solution?
Sergey Kolbasov
@sergeykolbasov
It's possible only under the condition of endpoints sharing the same type
Then you can use Endpoint.coproduct method
Otherwise welcome to the beautiful world of shapeless, type level programming and all the rest of things we love
Georgi Krastev
@joroKr21
Hmm, it would be nice to have Endpoint.coproduct[A](endpoints: Endpoint[A]*)
I checked now and we have only endpointA coproduct endpointB
Larry Bordowitz
@lbordowitz
@zhenwenc I'm working on adding metadata to finch for auto-generation of REST API specification documents. So, instead of working with the coproduct directly, I just created a recursive list-like datastructure in my metadata and shoved the two parts of the coproduct into there.
Dermot Haughey
@hderms
@lbordowitz interested to see how this turns out. The big weakness with all the auto-documenting stuff I've seen so far is what happens when you have a JSON body or JSON response. I'm not sure that's doable in a general sense with something like circe given that custom encoders/decoders are relied upon relatively frequently in practice and I'm not sure if there is an ideal solution for documenting them automatically given they can execute arbitrary code. Also I don't think you can tell a derived codec from a manually implemented one so I'm not confident that libraries could handle it properly. Let me know if you have any ideas because that ended up being one of the big roadblocks I identified
Georgi Krastev
@joroKr21
Well you can't use Circe or other JSON-only codecs. You would need another typeclass perhaps for schemas but the problem is keeping it in sync with the codecs. Btw that's one reason why I prefer (semi) auto generated codecs. I don't understand why people shy away from that. As long as you have separate data types to keep your API layer isolated from your internal logic, it's all fine.
Larry Bordowitz
@lbordowitz
@hderms the goal isn't automatic derivation of everything, just low touch. So, you get the type when you make a jsonBody, and it's decodable; can we get enough metadata to derive a json object schema? What if it's just for standard case classes? And, yeah, definitely more than a little stuck on body encoding right now. Regarding responses, I had an idea of a sort of "test harness" like runner, which could generate documented examples and maybe even output types. It's a bit pie-in-the-sky, tho, cuz I don't know a lot of the reflection and fancy tricks these serialization libraries (like Circe) use to do what they do.
Dermot Haughey
@hderms
yeah i'm not confident anything like that could work with circe without breaking as soon as you introduce your own custom encoder/decoder