2

I need to develop REST APIs to expose CRUD operations to DB and some business logic. I prefer this module to be standalone, fast, scalable and nimble (no unnecessary modules that provide functionality that I don't need, to reduce maintenance cost).

Development preferences:
- a framework/language that does type checking
- has good ORM mapping
- has good TDD/BDD support
- functional language

I'm wondering if some combination of scala modules like squeryl and blue eyes or squeryl and spary does the trick, but it doesn't have to be scala. Any ideas?

Srini K
  • 3,315
  • 10
  • 37
  • 47

3 Answers3

1

What you describe is certainly possible. I don't have any experience with Spray or BlueEyes, but I've certainly used Squeryl + Play, and it can be made to do what you want. It probably provides modules that you don't need, but these shouldn't contribute to the maintenance cost if you don't use them.

The one big gotcha is that most (if not all) of the Scala frameworks are designed around an asynchronous programming model (as indeed are most other high scalability frameworks, like Node.js). ORMs, on the other hand, are generally built around a synchronous programming model. However, you can work around this mismatch with a little glue code, some defensive coding, and some careful tuning (which is what we did).

A more radical alternative is to swap the ORM for a document database like MongoDB or CouchDB (document databases usually have reasonable asynchronous drivers).

James_pic
  • 3,240
  • 19
  • 24
  • Thanks. The modules we don't use do contribute to performance and maintenance cost due to software updates and bug fixes. This is especially true for "Views" part of MVC, which tend to have most changes overtime. However, this is what I was going to do if there are no better options. – Srini K Apr 10 '13 at 15:35
  • One more thing...Though I said ORM, I actually meant DB entity (relational or not) to Object mapping. Thanks for pointing that out. Having said that I also believe that it is not SQL vs noSQL anymore. Polygot persistence will become the new normal, though we don't think we have enough tools to deal with it yet. – Srini K Apr 10 '13 at 15:45
1

For a web front-end Play Framework has become a default choice lately.

For an ORM I recommend SORM Framework:

Following is a complete example of what it can do. No extra code required.

// Declare a model:
case class Artist( name : String, genres : Set[Genre] )
case class Genre( name : String ) 

// Initialize SORM, automatically generating schema:
import sorm._
object Db extends Instance(
  entities = Set( Entity[Artist](), Entity[Genre]() ),
  url = "jdbc:h2:mem:test"
)

// Store values in the db:
val metal = Db.save( Genre("Metal") )
val rock = Db.save( Genre("Rock") )
Db.save( Artist("Metallica", Set(metal, rock) ) )
Db.save( Artist("Dire Straits", Set(rock) ) )

// Retrieve values from the db:
// Option[Artist with Persisted]:
val metallica = Db.query[Artist].whereEqual("name", "Metallica").fetchOne() 
// Stream[Artist with Persisted]:
val rockArtists = Db.query[Artist].whereEqual("genres.item.name", "Rock").fetch() 
Community
  • 1
  • 1
Nikita Volkov
  • 42,792
  • 11
  • 94
  • 169
  • Thanks. Can you please answer questions posted here? http://stackoverflow.com/questions/15958677/latest-scala-version-sorm-supports – Srini K Apr 11 '13 at 20:56
0

I think Lift web framework is quite a possible candidate for the following reason:

Props

  1. Highly modularized.

    Although Lift is a complete web application framework, but it's highly modularized. It has its own ORM library, but if you don't like it, just not include it in your library dependency and use other library like Squeryl instead. Similar, it has type-safe JSON library, but it's optional too.

  2. It's just a normal Filter of Java Web Container.

    It means you could use it with other framework that runs on Java Web Container, and specify that only certain URL will go to Lift, and other URL will just to your old framework or just simply a pure JSP.

  3. It's type-safe and functional.

    Most operation in Lift is strongly-type type safe, for example, you could store session variable in SessionVar without lose it's type information.

    Lift also leverage a lot of functional programming technique like partial function, pattern matching and a pure xHTML/HTML5 template system that based on transformation instead of embed scala code in your template to generate dynamic content.

  4. Super easy REST support for both stateful and stateless.

    Create a REST API in Lift is super easy, it has a pretty good and simple DSL for it. And it support both stateful and stateless, sometimes it's more easier to do something in stateful way, and Lift give you that. Both stateful and stateless use same REST DSL, you just need to tell Lift what style you want, and it will handle everything (initialize session...etc) for you.

    For example, the following code shows how you could create a REST API that support both XML and JSON to get and post a blog article.

    object BlogAPI extends RestHelper {
    
      def getPostXML(postID: String) = <article>{postID}</article>
      def getPostJSON(postID: String): JValue = ("postID" -> 1)
      def addPostJSON(jsonBody: JValue) = {
        // Extract from jsonBody and add post to DB 
        new OkResponse()
      }
    
      serve {
        // Read blog post API in XML and JSON
        case "api" :: "blog" :: "post" :: postID :: Nil XmlGet request => getPostXML(postID)
        case "api" :: "blog" :: "post" :: postID :: Nil JsonGet request => getPostJSON(postID)
    
        // Post blog post API in JSON
        case "api" :: "blog" :: "post" :: Nil JsonPost ((jsonBody, req)) => addPostJSON(jsonBody)
      }
    }
    

    That's pretty much all of it you need to craft a REST API in Lift. It will match the URL GET /api/blog/1.xml to a XML response, and GET /api/blog/1.json will return a JSON response.

Cons

The most downsides of Lift is that the documentation is less than some other framework, and some information you could find on web is outdated.

And because Lift using lots of advanced Scala feature and some functional programming style, so sometimes it's not easy to learning it if you are not familiar Scala and functional programming feature.

Brian Hsu
  • 8,781
  • 3
  • 47
  • 59