Reuse Skinny components in Spray apps

Skinny Framework itself depends on Skinny Micro and its Servlet integration. But skinny-validator, skinny-json4s and other components are independent from Servlet environment.

skinny-splash aims to provides handy APIs for Spray applciations by seamlessly integrating Skinny components.

https://github.com/skinny-framework/skinny-splash


Getting Started


After creating the following files, you can boot your first HTTP server built with skinny-splash. Pretty easy!

sbt run
# access `localhost:8080` or `localhost:8080/?name=World` form curl or web browser

Using sbt-resolver makes your Spray application development smoother. While running your Spray application by using the following command, sbt will detect your file changes and restart application automatically.

sbt ~reStart

If you’d like to create a portable jar file which can be invoked anywhere, use sbt-assembly to generate it.

sbt assembly
java -jar target/scala-2.11/my-blazing-app-assembly-0.1-SNAPSHOT.jar

build.sbt

lazy val sample = (project in file(".")).settings(
  scalaVersion := "2.13.8",
  name := "my-blazing-app",
  libraryDependencies ++= Seq(
    "com.typesafe.akka"    %% "akka-actor"    % "2.4.0",
    "io.spray"             %% "spray-can"     % "1.3.3",
    "io.spray"             %% "spray-routing" % "1.3.3",
    "io.spray"             %% "spray-json"    % "1.3.1",
    "org.skinny-framework" %% "skinny-splash" % "1.0.+"
  )
).settings(Revolver.settings: _*)

project/build.properties

sbt.version=0.13.8

project/plugins.sbt

addSbtPlugin("io.spray"     % "sbt-revolver" % "0.7.2")
// for standalone jar creation
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.13.0")

src/main/scala/app.scala

import skinny.splash._
import skinny.validator._

class MyController extends SprayController {
  def form(req: SprayRequest) = validation(req,
    paramKey("name") is required & maxLength(10)
  )
  def index(implicit req: SprayRequest): SprayResponse = {
    if (form(req).validate()) {
      val body = toJSONString(Map("message" -> s"Hello, ${params.getOrElse("name", "Anonymous")}"))
      respondAs(body)
    } else {
      respondAs(status = 400, body = toJSONString(keyAndErrorMessages))
    }
  }
}

trait MyDispatcher extends SprayDispatcher {
  val myController = new MyController
  def routes = Seq(
    getRoute("")(implicit req => myController.index),
    postRoute("post")(implicit req => myController.index)
  )
}

class MyDispatcherActor
  extends SprayDispatcherActor
  with MyDispatcher

object MyApp extends SprayApplication {
  def dispatcherActorProps = toProps(classOf[MyDispatcherActor])
}

src/main/resources/messages.conf

error {
  required="{0} is required"
  notNull="{0} is required"
  notEmpty="{0} is required"
  length="{0} length must be {1}"
  minLength="{0} length must be greater than or equal to {1}"
  maxLength="{0} length must be less than or equal to {1}"
  minMaxLength="{0} length must be greater than or equal to {1} or be less than or equal to {2}"
  numeric="{0} must be numeric"
  intValue="{0} is less or greater than expected range"
  longValue="{0} is less or greater than expected range"
  intMinValue="{0} must be greater than or equal to {1}"
  intMaxValue="{0} must be less than or equal to {1}"
  intMinMaxValue="{0} must be greater than or equal to {1} or be less than or equal to {2}"
  longMinValue="{0} must be greater than or equal to {1}"
  longMaxValue="{0} must be less than or equal to {1}"
  longMinMaxValue="{0} must be greater than or equal to {1} or be less than or equal to {2}"
  dateTimeFormat="{0} must be a datetime value"
  dateFormat="{0} must be a date value"
  timeFormat="{0} must be a time value"
  same="{0} must be the same with {1}"
  email="{0} must be an e-mail"
  past="{0} must be in the past"
}

Give us your feedback!

skinny-splash is a very young library. We’d like to improve step by step with users. If you’re interested in using it and hope more features, please let us know here:

https://github.com/skinny-framework/skinny-splash/issues


If you find a typo or mistake in this page, please report or fix it. How?