2

我需要开发 REST API 来将 CRUD 操作暴露给 DB 和一些业务逻辑。我更喜欢这个模块是独立的、快速的、可扩展的和灵活的(没有提供我不需要的功能的不必要的模块,以降低维护成本)。

开发偏好:
- 进行类型检查的框架/语言
- 具有良好的 ORM 映射
- 具有良好的 TDD/BDD 支持
- 函数式语言

我想知道像 squeryl 和 blue eyes 或 squeryl 和 spary 这样的 scala 模块的组合是否可以解决问题,但它不一定是 scala。有任何想法吗?

4

3 回答 3

1

对于 Web 前端,Play Framework最近已成为默认选择。

对于 ORM,我推荐SORM 框架

以下是它可以做什么的完整示例。不需要额外的代码。

// 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() 
于 2013-04-11T13:00:04.183 回答
1

你所描述的当然是可能的。我没有任何使用 Spray 或 BlueEyes 的经验,但我肯定使用过 Squeryl + Play,它可以做你想做的事。它可能提供了您不需要的模块,但如果您不使用它们,它们不应该增加维护成本。

一个大问题是大多数(如果不是全部)Scala 框架都是围绕异步编程模型设计的(事实上,大多数其他高可扩展性框架也是如此,例如 Node.js)。另一方面,ORM 通常是围绕同步编程模型构建的。但是,您可以通过一些胶水代码、一些防御性编码和一些仔细的调整(这就是我们所做的)来解决这种不匹配问题。

一个更激进的替代方法是将 ORM 替换为 MongoDB 或 CouchDB 等文档数据库(文档数据库通常具有合理的异步驱动程序)。

于 2013-04-10T14:08:31.053 回答
0

我认为Lift web 框架很可能是一个候选者,原因如下:

道具

  1. 高度模块化。

    尽管 Lift 是一个完整的 Web 应用程序框架,但它是高度模块化的。它有自己的 ORM 库,但如果你不喜欢它,就不要将它包含在你的库依赖项中,而是使用 Squeryl 等其他库。类似地,它具有类型安全的 JSON 库,但它也是可选的。

  2. 它只是一个普通的 Java Web Container 过滤器。

    这意味着您可以将它与运行在 Java Web Container 上的其他框架一起使用,并指定只有特定的 URL 将转到 Lift,而其他 URL 将仅用于您的旧框架或只是一个纯 JSP。

  3. 它是类型安全的和功能性的。

    Lift 中的大多数操作都是强类型安全的,例如,您可以将会话变量存储在 SessionVar 中而不会丢失其类型信息。

    Lift 还利用了许多函数式编程技术,例如部分函数、模式匹配和基于转换的纯 xHTML/HTML5 模板系统,而​​不是在模板中嵌入 scala 代码来生成动态内容。

  4. 对有状态和无状态的超级简单的 REST 支持。

    在 Lift 中创建一个REST API 非常简单,它有一个非常好的和简单的 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 所需的全部内容。它将 URLGET /api/blog/1.xml与 XML 响应匹配,并GET /api/blog/1.json返回 JSON 响应。

缺点

Lift 最大的缺点是文档比其他框架少,而且您可以在网络上找到的一些信息已经过时。

而且由于Lift使用了很多高级的Scala特性和一些函数式编程风格,所以如果你不熟悉Scala和函数式编程特性,有时候学习起来并不容易。

于 2013-04-11T02:58:30.203 回答