In the last post we talked about setting up a tiny application that shares Scala code across the Server and Client. However no real application is complete without persistence or a database. I’d like to share some quick code snippets to enhance the small proof-of-concept from last time.

As a database I’ve chosen MongoDB, because it fits our needs well and it’s really simple to set up! We could also use any other database be it relational or another style of NoSQL DB, not trying to start any discussions on BASE vs ACID or the like.

If you’re not familiar with MongoDB, it’s a document-oriented database, that saves JSON-like (BSON - Binary JSON) documents. You can try it out real quick in the Mongo shell, which is also a full-on Javascript interpreter. If you want to go into detail I can also recommend this book.

We’ll start out by adding Casbah to our sbt dependencies. Casbah is a small toolkit for working with Mongo in Scala. Now we can start using Mongo by connecting inside our ScalatraBootstrap.

import com.ltj.server._
import org.scalatra._
import javax.servlet.ServletContext
import com.mongodb.casbah.Imports._

class ScalatraBootstrap extends LifeCycle {
  override def init(context: ServletContext) {
    val mongoClient =  MongoClient()
    val mongo = mongoClient("pizza")
    context.mount(new PizzaServlet(mongo), "/*")
  }
}

With casbah we can create a client with default settings (port 27017 and localhost). We can then connent to a database by calling the client.

In our case we’ll connect to the database “pizza”. Then we insert the database into the constructor of our servlet. In our servlet we’ll use this instance to persist our orders, query them and delete them. These 3 cases map very well to the HTTP methods and we’ll keep using only JSON to transfer our data.

class PizzaServlet(db: MongoDB) extends PizzaorderStack {

  post("/orders"){
    val json = request.body
    val order = read[Order](json)
    if (!order.isValidOrder()) halt(400)

    val orders = db("orders")
    orders += JSON.parse(json).asInstanceOf[DBObject]

  }

  get("/orders"){
    val orders = db("orders").find()
    JSON.serialize(orders.toList)
  }

  delete("/orders/:id"){
    val id = new ObjectId(params("id"))
    val orders = db("orders")
    orders.remove(MongoDBObject("_id" ->  id))
  }

}

As we can see, working with Mongo and JSON is pretty simple. We’re just pushing our JSON data straight to the database without normalization. Now I did a small test with our current client to see if the POST-Request to orders saves the order and voila! It works!

clientTest

The “find”-method returns a cursor which we can easily convert to a List or another Scala collection and then just serialize it to JSON.

Deleting is a little bit more tricky. Mongo has it’s own mechanic of keeping a unique id for each entry of the collection called the “ObjectId”.

If you’ve expiremented with the Mongo shell or worked with Mongo before you’ll familiar with it, but basically it’s a 12-byte BSON Object which Mongo will add to your document if you don’t specify your own unique identifier. It’s pretty clever and you can check out some of the details here.

So once we’ve converted our id-string to an ObjectId we can then easily remove the specified document. Now we can start expanding our client. We’ll start by making another HTML template where we want to list all of our orders.

<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Orders</title>
</head>
<body onload="com.ltj.pizza.Main().showOrders()">
	<h1>All Orders:</h1>
	<ul id="orders">
	
	</ul>
	<script src="lib/jquery-1.9.1.min.js"></script>
	<script src="js/scala-2.11/pizza-order-fastopt.js"></script>
</body>
</html>

Pretty simple so far, now let’s create some code, that retrieves all the orders via GET-Request and then appends it into our “orders” list.

@JSExport
def showOrders(): Unit = {
  jQuery.get(url = "/orders",  success = (data: String) => {
    val orders = read[Seq[Order]](data)
    orders.foreach(order => {
	  val list = jQuery("<ul>")
	  order.pizzas.foreach { pizza => list.append(jQuery("<li>").text(pizza.toString())) }
	  jQuery("#orders").append(jQuery("<li>").append(list))
    })
  })
}
  

We just parse the json back to a Seq of Orders and use it to create new ul and li elements. This is also real simple and probably not the best example for creating a good overview for our orders, but we also don’t want to do a lot of DOM-Manipulation.

Maybe in another part of this series, we could recreate this with more functionality using Angular or React. However let’s take a look at the result!

It works!

Yay! A litte bit shabby but now we have a very easy-to-work-with setup from which we could expand on. We’ve already talked about what our next step could look like, so I’d like to end this post with a little video I found on the topic of Scala.js Have fun!

You can find all the code showed here and lots more in the github repo.

There’s been a lot of talks recently about the “holy grail of web development” of sharing code between the Server and the Client. I think this is a great idea as writing the same code twice can be expensive as the complexity of your project grows. I’ve never been a huge fan of Javascript, but recently a lot of transpilers and extensions to Javascript have emerged, to overcome some of the common pitfalls of Javascript. I’ve been doing a lot of TypeScript with Angular and Express.js recently and have come to appreciate the working with MEAN, I realized, that since I’m already transpiling to Javascript and I’d heard that Scala.js is no longer experimental, that transpiling from Scala might be a good idea. With Web Assembly becoming a thing transpiling from different languages might just become more and more popular, so I decided to write up a short proof of concept using Scalatra, jQuery and µPickle.

First I thought of a small scenario to model my application after. Imagine you sell Pizzas and want people to order them online. Now forgetting about security and all that blah, I implemented something small that checks if you order matches the minimum order value. Take a look.

package com.ltj.models

case class Topping (name: String, price: Float)

object Topping {
  def apply(name: String): Option[Topping] = name match {
    case "Onion" => Some(Topping(name, 1))
    case "Peppers" => Some(Topping(name, 1.5f))
    case "Ham" => Some(Topping(name, 2.5f))
    case "Pepperoni" => Some(Topping(name, 2))
    case "Olives" => Some(Topping(name, 1))
    case _ => None
  }
}


case class Pizza (toppings: List[Topping]){
	
  def addTopping(topping: Option[Topping]): Pizza = {
    if (topping.isEmpty) this
    else Pizza(toppings :+ topping.get)
  }
}

object Pizza {
  val BasePrice: Float = 3.5f
}


case class Order(pizzas: List[Pizza]) {
  
  val minimumOrderValue = 12.50
  
  def isValidOrder(): Boolean = {
    price() > minimumOrderValue
  }
  
  def price(): Float = {
    val toppingPrices = for {
      pizza <- pizzas
      topping <- pizza.toppings
    } yield topping.price
    toppingPrices.foldLeft(Pizza.BasePrice* pizzas.length)(_ + _)
  }
 
}

Now for writing the server-side code. If you’re not familiar with Scalatra, it’s a small Sinatra-like (obviously) framework, which allows you to quickly create RESTful services (similar to Express). Scala has built-in xml literals and we can take advantage of that and write pure HTML and map it to a GET-Request. XML values are a type safe in the sense that an error in the XML Markup would cause a compile time error. Now in a real world application we’d use a templating language like Jade or Scalate, but for this app we’re just gonna use this shortcut.

package com.ltj.server

import com.ltj.models.Order
import org.scalatra._
import upickle.default._

class PizzaServlet extends PizzaorderStack {

  get("/") {
    <html>
      <body>
        <h1>Order your Pizza!</h1>
        <form>
          <select id="topping">
            <option value="Margherita">Margherita</option>
            <option value="Onion">Onion</option>
            <option value="Olives">Olives</option>
            <option value="Peppers">Peppers</option>
            <option value="Ham">Ham</option>
            <option value="Pepperoni">Pepperoni</option>
          </select>
          <input type="button" onclick="com.ltj.pizza.Main().submitTopping()" value="Add Topping to Pizza"/><br/>
          <input type="button" onclick="com.ltj.pizza.Main().submitPizza()" value="Add Pizza to Order"/><br/><br/>
          Your current total: <span id="price">0.00</span>$<br/>
          Please select at least 12.50$ before sending your order.
          <input type="button" onclick="com.ltj.pizza.Main().submitOrder()" value="Send Order!"/>
        </form>
        <script src="lib/jquery-1.9.1.min.js"></script>
        <script src="js/scala-2.11/pizza-order-fastopt.js"></script>
      </body>
    </html>
  }

  post("/orders"){
    val order = read[Order](request.body)
    if (!order.isValidOrder()) halt(400)
  }

}

On a POST-Request to “/orders” we read the incoming JSON, parse it to a Scala Object (using uPickle) and check if it’s valid. If it isn’t we’ll just halt the request and send a 400 back to the client. Now as you can probably see, the code above already contains some calls to the client side logic. If you’re unfamiliar with how Scala.js works, check the links below for some great explanations. Anyway here’s the code that will check the order before sending a POST-Request to confirm the order.

object Main extends JSApp {
	
  var order = Order(List())
  var currentPizza = Pizza(List())
  
  @JSExport
  def submitTopping(): Unit = { 
	  val unvalidatedTopping = jQuery("#topping").`val`.toString()
	  val topping = Topping(unvalidatedTopping)
	  currentPizza = currentPizza.addTopping(topping) 
  }
  
  @JSExport
  def submitPizza(): Unit =  {  
	  order =  Order(order.pizzas :+ currentPizza); 
	  currentPizza = Pizza(List())
	  jQuery("#price").html(order.price().toString())
  }
  
  @JSExport
  def submitOrder(): Unit = { 
	  if (order.isValidOrder()){
	 	  
	 	   val jqxhr = jQuery.post("/orders", write(order),(data: Any) => {
    		 	window.alert("Your order has been processed and will be there shortly!")
    	 })
    	   
	  } else {
	 	  window.alert("Minimum value not reached!")
	  }
  }
  
  def main(): Unit = {
	  
		jQuery.ajaxSetup(js.Dynamic.literal(
			contentType = "application/json"
		))
  }
	

With the @JSExport annotation we can now call the methods using the onclick attribute.

So now that we have all this wired up we can start up the application.

My helpful screenshot

And see there, it works! So there we have it. Sharing Scala code between client and the server. In my opinion the name “holy grail” does do a lot of justice to this approach. However Scala.js hasn’t reached 1.0 yet, although bindings for React and Angular already exist today. If you’re a Scala developer and always wished you could extend your Backend knowledge to the client, you should give it a try. The sbt plugins work really well, and I hear integration into Angular and React work quite nicely and combined with the Play! framework it could be very very powerful. If you’re interested, I’ve prepared a few links.

You can find all the code showed here and lots more in the github repo.

The basics of Scala.js http://www.scala-js.org/tutorial/basic/

Using Scala.js with jQuery https://github.com/scala-js/scala-js-jquery

Using sbt to cross compile Scala to the JVM and JS http://lihaoyi.github.io/hands-on-scala-js/#IntegratingClient-Server