27

我想知道让 Grails 应用程序提供可供 Web 服务使用的RESTful API (主要是一些 CRUD 操作)的最佳方法是什么,例如,当您想为基于浏览器的应用程序构建相应的iOS应用程序时,或者还要别的吗。

我想在我的 Grails 应用程序中构建一个单独的部分来接受调用,www.mywebapp.com/api/someAction以便我可以重用服务层。那么我将如何进行 URL 映射呢?只有一个大ApiController的听起来不是很时髦。

或者有什么我不知道的更好的方法吗?这种方法必须支持OAuth之类的东西来对调用 Web 服务的用户进行身份验证。

4

4 回答 4

58

Grails绝对可以提供 REST api,但是这样做的难度取决于您希望 API 的成熟程度(也就是 RESTful)。

基本 REST

获得基本的 RESTfullness 水平,使用完整的 HTTP 动词并利用 HTTP 响应代码来操作资源的 json 或 xml 表示,非常容易。有3个主要部分来实现它:

  1. 网址映射

    这是我如何在最近的项目中编写 URL 映射以允许更多 RESTful URL 的示例:

    // RESTful list mapping
    name restEntityList: "/$controller"(parseRequest: true) {
        action = [GET: "list", POST: "save"]
    }
    
    // RESTful entity mapping
    name restEntity: "/$controller/$id"(parseRequest: true) {
        action = [GET: "show", PUT: "update", POST: "update", DELETE: "delete"]
        constraints {
            id matches: /\d+/
        }
    }
    
  2. 内容协商

    Grails 可以处理内容协商的 3 种不同方式使框架非常灵活,允许您支持更广泛的客户端,这些客户端可能无法设置诸如 Accept HTTP 标头之类的内容。

    您可以使用内容协商来响应不同的请求,withFormat根据客户端指示的内容,使用块以不同的方式响应他们想要的内容。这种强大的能力也可以用来对你的 API 进行版本控制,就像Github 所做的那样。

  3. 响应状态

    HTTP 已经内置了一个很好的响应机制,它允许您利用架构中的先天能力,例如可缓存性和独立操作。虽然某些 Web 浏览器不能非常优雅地处理某些响应代码,但使用您的 API 的客户端应用程序可以使用它们来大大简化其内部代码。

干休息

使您的应用程序 RESTful 并同时保持其 DRY 的最佳方法之一是尽可能利用控制器脚手架,因为 CRUD 对于所有域对象基本上都是相同的。这篇关于使默认控制器更加 RESTful 的文章和这篇关于简化默认控制器的文章都是从脚手架获得更多功能的好资源。

高级 REST

一旦你达到了这一点,你就有了一个非常实用的 REST API 用于你的 grails 应用程序。您可以执行所有基本的 CRUD 操作,并且资源相当容易使用。

然而,真正的 RESTful 超媒体 API 阶梯的下一个层次要实现起来要困难得多。解决这个问题是 Grails 的路线图,但目前它相当痛苦。这些部分是:

  1. 超媒体资源
  2. 内容类型
  3. 版本控制

值得庆幸的是,有一个插件可以很容易地定义自定义编组器,这使我们能够相当容易地涵盖剩下的三个 REST 难题。

最后,还有保护整个事物的方面。一般来说,就保护用户对您的 api 的访问而言, Spring Security将为您提供良好的支持。由于大多数 API 访问来自应用程序,并且用户不可见,因此基本或摘要式身份验证通常是最简单的方法。有一个基于 Spring SecurityOAuth 插件。我没有亲自使用过它,所以我不能保证它的稳定性,但它对我来说看起来还不错。

总的来说,Grails 足够灵活和强大,可以非常非常好地执行 REST,但尚未完成使其开箱即用地执行 REST 的工作。

于 2012-05-02T18:51:45.413 回答
6

grails 文档在设置 RESTfull api 方面做得很好

http://grails.org/doc/latest/guide/webServices.html#13.1

于 2012-03-30T14:02:02.727 回答
1

无论如何,您都可以映射它,使用任何 url 结构。Grails UrlMapping 非常灵活,它只是映射到的默认行为/$controller/$action,但您可以使用自己的映射,您可以手动事件映射每个 url,等等。

请参阅 UrlMapping 文档 - http://grails.org/doc/latest/guide/theWebLayer.html#urlmappings

于 2012-03-29T21:18:54.033 回答
1
  • 网址映射:

    "/api/element/$version/$master" { 控制器 = "element" 动作 = [GET:"show"] }

这会将 http get 映射到控制器元素的 show 方法。

  • 即显示方法:

DRY:api 可能与应用程序的逻辑相同。区别在于内容协商。

...

def show = {
    def elements = elementService.findByMasterVersion(params.master, params.version)
    withFormat {
        xml {
            render(status:200,text:elements as XML, contentType:"text/xml",encoding:"UTF-8")
        }
        json { ... }
        html { ... }
    }
}
  • Oauth 实现起来非常复杂,而且在很多情况下似乎都过大了。
于 2012-05-02T18:10:21.780 回答