如何在Grails 2.3中一起使用scaffolding和RESTfulness

时间:2013-10-19 11:12:38

标签: rest grails scaffolding

官方Grails文档说明

  

脚手架插件的2.0.x版包括不同的脚手架   与Grails中引用的新REST API对齐的模板   2.3及以上。   (取自http://grails.org/doc/latest/guide/scaffolding.html

但是我不能制作(或者我不理解这个概念)和脚手架一起工作RESTful。

让我们从头开始:

grails create-app myapp
cd myapp/
grails create-domain-class Book
grails create-scaffold-controller myapp.Book

向域类添加字段

class Book {
    String text

    static constraints = {
    }
}

并使用grails run-app运行应用。 在http://localhost:8080/myapp/上进行冲浪表明脚手架效果很好:

  • http://localhost:8080/myapp/book/index页面显示图书清单
  • http://localhost:8080/myapp/book/show/1页面显示id = 1
  • 的图书的详细信息
  • http://localhost:8080/myapp/book/create页面创建了一本书
  • 所以用力,好旧的脚手架。

让我们看看REST的情况。 官方文档称我应该使用http://localhost:8080/myapp/books/...之类的网址作为REST,但是任何访问该应用的尝试,例如此curl -i -H "Accept: application/json" localhost:8080/myapp/books/1都会返回带有大量HTML的404。

好的,让我们仔细阅读文档:

  

在Grails中创建RESTful API的最简单方法是公开一个   域类作为REST资源。这可以通过添加   grails.rest.Resource转换到任何域类

没问题,现在Book类标题是

import grails.rest.*

@Resource(uri='/books') class Book {

现在在http://localhost:8080/myapp/上进行冲浪表明脚手架已损坏:

  • http://localhost:8080/myapp/book/index页面显示图书清单
  • http://localhost:8080/myapp/book/create页面显示了xml输出<?xml version="1.0" encoding="UTF-8"?><book><text /></book>
  • 所以强制,坏的新xml输出。

我在URLMappings.groovy中玩过 @Resource “/ books”(资源:“book”)但是没有找到任何可行的解决方案可能的脚手架和RESTfulness背靠背工作。实际上,我设法使它们分开工作。

更新

我找到了如何实现预期目标的方法。我发现的方式是:

  1. 使用@Resource(uri = "/books")标记 Book 课程。
  2. 删除脚手架控制器 BookController
  3. 使用脚手架为本书创建专用控制器:class HumanBookController {static scaffold = Book}
  4. 现在,带有http://localhost:8080/myapp/humanBook/index等网址的脚手架GUI页面运行良好。使用http://localhost:8080/myapp/books/1之类的URL可以很好地处理json请求。但是让2个控制器为普通的web和json做同样的事情并不优雅。

6 个答案:

答案 0 :(得分:15)

你可以这样做:

import grails.rest.RestfulController

class BookController extends RestfulController {

    static responseFormats = ['html', 'json']

    BookController() {
        super(Book)
    }
}

然后在UrlMappings.groovy中:

 "/books"(resources:"book")
 "/$controller/$action?/$id?(.${format})?"{
    constraints {
        // apply constraints here
    }
  }

无需在域中添加@Resource。 您现在可以将/books/1.json或/books/1.html指向正确的位置。您可能仍需要grails generate-view Book来生成视图。但是,虽然您需要为html生成视图,但只保留单个控制器和路径。

答案 1 :(得分:1)

我和你的问题一样。 这可能是一个简单的解决方案,并非适用于所有情况,但请尝试更新您的Grails版本。 至于我:Grails 2.3.4 - &gt; Grails 2.3.6工作。 希望能帮助任何人。

答案 2 :(得分:1)

我目前正在使用Grails 2.4.0,解决方法是这样做的:

  • 控制器: BookController {static scaffold = true}
  • 域名预订{....} //没有@Resource

结果是你可以:

  • /book.json获取JSONized列表
  • / book / index获取HTML标准脚手架
  • / book /为新项创建html脚手架
  • / book / show / 1 html scaffold edit item 1
  • /book/show/1.json项目ID的JSON:1

我知道,我是邪恶的。我找到了this,它让我走了。

答案 3 :(得分:1)

使用Grails 2.4.4我可以使用以下步骤使脚手架与单个控制器一起工作:

  1. 在UrlMappings.groovy中添加了资源映射的URL,例如: "/books"(resources:"book")
  2. static scaffold = true插入生成的控制器
  3. 我做了验证以下是否有所不同,但我还在Config.groovy中设置了grails.mime.disable.accept.header.userAgents = []grails.mime.use.accept.header = true(后者可能是新的默认值)

    支架式REST和UI界面都可以通过以下测试正常工作:

    • GET / app // 1(传递Accept标头)
    • GET /app//1.json(没有接受标题)
    • POST / app /(有效负载为json或表单编码)
    • DELETE / app // 1
    • PUT / app // 1(使用json有效负载。表单有效负载更新了对象,但发送回302重定向)

    修改

    1. 删除了资源注释步骤并阐明了URL映射设置
    2. URL映射中指定的URI 与控制器的默认URI相同。例如,“书籍”而不是“书”。添加此映射后,控制器的URI将默认为UrlMapping中的URI,但原始URI将继续有效。

答案 4 :(得分:0)

生成的控制器是Restful控制器,因为它实现了对以下请求的操作:

curl -i -X GET yourDomain:8080/yourApp/books.json

它返回json格式的书籍列表。 (10本书,假设你创建了测试数据,是吗?)

您可以附加如下参数:

curl -i -X GET yourDomain:8080/yourApp/books.xml?40

默认情况下,您将获得html格式。您需要附加.json.xml才能获得正确的数据。

您也可以使用Accept标题

curl -i -X GET -H "Accept: application/xml" yourDomain/books/1

以xml格式返回id = 1的book的详细信息。最后

curl -i -X POST -H "Content-Type: application/json" -d "{name: 'Book'}" yourDomain/books

创建一本新书

curl -i -X PUT -H "Content-Type: application/json" -d "{name: 'Book'}" yourDomain/books/1

更新ID = 1

的图书名称

所有资源都需要通过和url公开。您没有为您生成网址,您应该将其写在UrlMappings文件:

"/v1/books"(resources: "book")

第一个字符串"/v1/books"是uri,第二个字符串"book"是遵循grails约定的控制器名称。 (前面的v1字符串是因为我总是将版本号放到我的API URI中)

 | GET    | /v1/books            | Action: index  |
 | GET    | /v1/books/create     | Action: create |
 | POST   | /v1/books            | Action: save   |
 | GET    | /v1/books/${id}      | Action: show   |
 | GET    | /v1/books/${id}/edit | Action: edit   |
 | PUT    | /v1/books/${id}      | Action: update |
 | DELETE | /v1/books/${id}      | Action: delete |

答案 5 :(得分:0)

所有应该要求的是在Domain类上使用uri的@Resource注释。如果您需要特定格式(默认格式是第一个),还包括格式:

@Resource(uri='/books', formats=['json', 'xml'])

那应该是它。如果ypu仍然无法找到动态@Resource端点,请尝试运行:

grails url-mappings-report

这将为您提供所有网址的精彩摘要,包括由@Resource域支持的脚手架控制器支持的网址。我发现在尝试&#34;猜测时,我往往会犯下愚蠢的错误。 URL - 使用报告输出可确保您和Grails达成一致。