我需要开发REST API以向数据库和一些业务逻辑公开CRUD操作。我更喜欢这个模块是独立的,快速的,可扩展的和灵活的(没有不必要的模块提供我不需要的功能,以降低维护成本)。
发展偏好:
- 进行类型检查的框架/语言
- 具有良好的ORM映射
- 具有良好的TDD / BDD支持
- 功能语言
我想知道是否有像squeryl和blue eyes或squeryl和spary这样的scala模块的组合可以解决问题,但它不一定是scala。有什么想法吗?
答案 0 :(得分:1)
你所描述的当然是可能的。我对Spray或BlueEyes没有任何经验,但我确实使用过Squeryl + Play,它可以做你想做的事。它可能提供了您不需要的模块,但如果您不使用它们,这些模块不应该导致维护成本。
一个重要的问题是,大多数(如果不是全部)Scala框架是围绕异步编程模型设计的(实际上是大多数其他高可伸缩性框架,如Node.js)。另一方面,ORM通常围绕同步编程模型构建。但是,您可以通过一些胶水代码,一些防御性编码和一些仔细调整(这就是我们所做的)来解决这种不匹配问题。
更激进的替代方案是将ORM交换为MongoDB或CouchDB等文档数据库(文档数据库通常具有合理的异步驱动程序)。
答案 1 :(得分:1)
对于网络前端Play Framework最近已成为默认选择。
对于ORM,我建议SORM Framework:
以下是它可以做的完整示例。无需额外代码。
// 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()
答案 2 :(得分:0)
我认为Lift web framework很可能是由于以下原因:
高度模块化。
虽然Lift是一个完整的Web应用程序框架,但它是高度模块化的。它有自己的ORM库,但是如果你不喜欢它,就不要将它包含在你的库依赖项中,而是使用像Squeryl这样的其他库。类似地,它具有类型安全的JSON库,但它也是可选的。
这只是Java Web容器的普通过滤器。
这意味着您可以将其与在Java Web容器上运行的其他框架一起使用,并指定只有某个URL将转到Lift,而其他URL将只对您的旧框架或仅仅是纯JSP。
它是类型安全且功能齐全的。
Lift中的大多数操作都是强类型类型安全的,例如,您可以在SessionVar中存储会话变量而不会丢失它的类型信息。
Lift还利用了许多函数式编程技术,如部分函数,模式匹配和基于转换的pure xHTML/HTML5 template system,而不是在模板中嵌入scala代码来生成动态内容。
对有状态和无状态的超级简单REST支持。
创建一个REST API in Lift is super easy,它有一个相当不错的简单DSL。并且它支持有状态和无状态,有时以有状态的方式做事更容易,而Lift会给你这个。有状态和无状态都使用相同的REST DSL,你只需要告诉Lift你想要什么样的风格,它将为你处理所有事情(初始化会话......等)。
例如,以下代码显示了如何创建支持XML和JSON以获取和发布博客文章的REST API。
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)
}
}
这几乎是您在Lift中制作REST API所需的全部内容。它会将网址GET /api/blog/1.xml
与XML响应匹配,GET /api/blog/1.json
将返回JSON响应。
Lift的最大缺点是文档比其他框架要少,而且你在网上找到的一些信息已经过时了。
因为Lift使用了许多高级Scala功能和一些函数式编程风格,所以如果你不熟悉Scala和函数式编程功能,有时候学习它并不容易。