How to apply filter on finch endpoint without using finagle filters?

342 Views Asked by At

I have more than one endpoints.I am able to apply common filters on endpoints using finagle filter.But now I want to apply a filter on a specific endpoint. How can I achieve this?

2

There are 2 best solutions below

0
Shastick On

I had a similar question (for basic authentication filtering) that popped up while playing with redbubble's finch template which I partially solved in the following way:

class AuthenticatedEndpoint[A](e: Endpoint[A]) extends Endpoint[A] { self =>

final def apply(mapper: Mapper[A]): Endpoint[mapper.Out] = mapper(self)

final def apply(input: Input): Endpoint.Result[A] =
  if (checkSession(input.request)) {
    e(input)
  } else {
    // TODO return something meaningful to the caller (if possible?)
    EndpointResult.Skipped
  }
}

object AuthenticatedEndpoint {

  def validSession[A](e: Endpoint[A]): Endpoint[A] = new AuthenticatedEndpoint(e)

}

(with checkSession returning true if all is well with the request). Then my api is defined as:

val api = "v1" :: loginApi :+: validSession(peopleApi :+: healthApi :+: adminApi)

This works well in the sense that requests without a session won't have access to the endpoints passed to validSession, but I have yet to find an easy way to return an error message to the caller, and I'd be curious to know if I chose the right path here.

0
Chandan Rajah On

This is how I got around it. It's probably not ideal but works.

class AuthenticatedEndpoint[A](e: Endpoint[A])(implicit auth: Request => Boolean) extends Endpoint[A] { self =>

  final def apply(mapper: Mapper[A]): Endpoint[mapper.Out] = mapper(self)

  final def apply(input: Input): Endpoint.Result[A] =
    if (auth(input.request)) {
      e(input)
    } else {
      EndpointResult.Matched[Nothing](input, Rerunnable( Unauthorized(new Exception(s"Authentication Failed."))) )
    }
}

object AuthenticatedEndpoint {

  def validSession[A](e: Endpoint[A]): Endpoint[A] = new AuthenticatedEndpoint(e)

}