All Downloads are FREE. Search and download functionalities are using the official Maven repository.

skinny.micro.routing.AsyncRoutingDsl.scala Maven / Gradle / Ivy

The newest version!
package skinny.micro.routing

import javax.servlet.http.HttpServletRequest

import skinny.micro._
import skinny.micro.constant._
import skinny.micro.context.SkinnyContext

/**
 * The core SkinnyMicro DSL.
 *
 * The SkinnyMicro DSL core methods take a list of [[skinny.micro.routing.RouteMatcher]] and a block as the action body.
 * The return value of the block is rendered through the pipeline and sent to the client as the response body.
 */
trait AsyncRoutingDsl extends RoutingDslBase {

  def get(transformers: RouteTransformer*)(action: (Context) => Any): Route = addRoute(Get, transformers, action)

  def post(transformers: RouteTransformer*)(action: (Context) => Any): Route = addRoute(Post, transformers, action)

  def put(transformers: RouteTransformer*)(action: (Context) => Any): Route = addRoute(Put, transformers, action)

  def delete(transformers: RouteTransformer*)(action: (Context) => Any): Route = addRoute(Delete, transformers, action)

  def options(transformers: RouteTransformer*)(action: (Context) => Any): Route = addRoute(Options, transformers, action)

  def head(transformers: RouteTransformer*)(action: (Context) => Any): Route = addRoute(Head, transformers, action)

  def patch(transformers: RouteTransformer*)(action: (Context) => Any): Route = addRoute(Patch, transformers, action)

  /**
   * Prepends a new route for the given HTTP method.
   *
   * Can be overridden so that subtraits can use their own logic.
   * Possible examples:
   * $ - restricting protocols
   * $ - namespace routes based on class name
   * $ - raising errors on overlapping entries.
   *
   * This is the method invoked by get(), post() etc.
   *
   * @see skinny.micro.SkinnyMicroKernel#removeRoute
   */
  protected def addRoute(method: HttpMethod, transformers: Seq[RouteTransformer], action: (Context) => Any): Route = {
    val route: Route = {
      val r = Route(transformers, () => action.apply(context), (req: HttpServletRequest) => routeBasePath(
        SkinnyContext.buildWithoutResponse(req, servletContext,
          UnstableAccessValidation(unstableAccessValidationEnabled, useMostlyStableHttpSession))))
      r.copy(metadata = r.metadata.updated(Handler.RouteMetadataHttpMethodCacheKey, method))
    }
    routes.prependRoute(method, route)
    route
  }

  private[this] def addStatusRoute(codes: Range, action: (Context) => Any): Unit = {
    val route = Route(Seq.empty, () => action, (req: HttpServletRequest) => routeBasePath(skinnyContext(servletContext)))
    routes.addStatusRoute(codes, route)
  }

  /**
   * Error handler for HTTP response status code range. You can intercept every response code previously
   * specified with #status or even generic 404 error.
   * {{{
   *   trap(403) { implicit ctx =>
   *    "You are not authorized"
   *   }
   * }* }}}
   * }}
   */
  def trap(codes: Range)(block: (Context) => Any): Unit = {
    addStatusRoute(codes, block)
  }

  /**
   * @see error
   */
  def trap(code: Int)(block: (Context) => Any): Unit = {
    trap(Range(code, code + 1))(block)
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy