The Read Write Web application

by: Alexandre Bertails, W3C

for: Boston Scala

available at http://www.w3.org/Talks/2011/09/22-scala-meetup-ab/

/me

Today

Read Write Web - articles

Read Write Web - overview

The Linked Data article gave simple rules for putting data on the web so that it is linked. This article follows on from that to discuss allowing applications to write as well as read data. – Read-Write Linked Data

General

GET HTML

GET RDF

MS-Author-Via: SPARQL

PUT RDF

POST

Unfiltered

(extracts from the tutorial)

Unfiltered is a toolkit for servicing HTTP requests in Scala. It provides a consistent vocabulary for handing requests on various server backends, but does not interfere with direct access to their native interfaces.

type Intent [-A, -B] = PartialFunction[HttpRequest[A], ResponseFunction[B]] 

Unfiltered - ResponseFunction[-A]

def ~> [B <: A] (that: ResponseFunction[B]) : ResponseFunction[B] 
Ok ~> ViaSPARQL ~> ContentType(encoding.toContentType) ~> ResponseModel(model, baseURI, encoding)

Unfiltered - Intent

case req @ Path(path) if path startsWith rm.basePath => { ... }
case GET(_) | HEAD(_) => { ... }
case GET(_) & Accept(accepts) if isHTML(accepts) => { ... }

Java methods have a finite size, and the Scala compiler generates very large methods for complex pattern matching.

Scalaz’ Validation

UPDATED: during my presentation, I talked about the Validation monad, which is not, even if you can flatMap this s***! I plan to speak about that during my next talk at Boston Scala.

sealed trait Validation[+E, +A] { ... }
final case class Success[E, A](a: A) extends Validation[E, A]
final case class Failure[E, A](e: E) extends Validation[E, A]
trait Resource {
  def get():Validation[Throwable, Model]
  def save(model:Model):Validation[Throwable, Unit]
}
def flatMap[EE >: E, B](f: A => Validation[EE, B]): Validation[EE, B] = this match {
  case Success(a) => f(a)
  case Failure(e) => Failure(e)
}
for {
  model <- r.get() failMap { t => NotFound }
  // TODO: we should handle an error here
  _ = UpdateAction.execute(update, model)
  _ <- r.save(model) failMap { t =>  InternalServerError ~> ResponseString(t.getStackTraceString)}
} yield Ok

Mapping Failure

How to go from Validation[F, S] to Validation[F’, S]?

trait ValidationW[E, S] {
  val validation:Validation[E, S]
  def failMap[EE](f:E => EE):Validation[EE, S] = validation.fail map f validation
}
implicit def wrapValidation[E, S](v:Validation[E,S]):ValidationW[E, S] =
  new ValidationW[E, S] { val validation = v }
def fold[X](failure: E => X = identity[E] _, success: A => X = identity[A] _): X = this match {
  case Success(x) => success(x)
  case Failure(x) => failure(x)
}
implicit def unwrap[E, F <: E, S <: E](v:Validation[F,S]):E =
  v.fold(e => e, s => s)

Back to the code

Also