11

官方 Grails 文档说

2.0.x 版的脚手架插件包括不同的脚手架模板,这些模板与 Grails 2.3 及更高版本中引入的新 REST API 保持一致。(取自这里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 之类的 URL,但是任何访问应用程序的尝试,就像这样curl -i -H "Accept: application/json" localhost:8080/myapp/books/1返回 404 和一堆 HTML。

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

在 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"(resources:"book"),但没有找到任何可行的解决方案,可以使脚手架和 RESTful 背靠背工作。事实上,我设法让它们分开工作。

更新

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

  1. 用标记Book@Resource(uri = "/books")
  2. 移除脚手架控制器BookController
  3. 为 Book 创建带有脚手架的专用控制器:class HumanBookController {static scaffold = Book}

现在,带有类似 URL 的脚手架 GUI 页面http://localhost:8080/myapp/humanBook/index工作得很好。json 请求都可以通过http://localhost:8080/myapp/books/1. 但是让 2 个控制器为常见的 web 和 json 做同样的事情并不优雅。

4

6 回答 6

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 生成视图,但您只保留单个控制器和路径。

于 2014-01-06T20:33:12.880 回答
1

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

  1. 在 UrlMappings.groovy 中添加了指向资源映射的 URL,例如"/books"(resources:"book")
  2. 插入static scaffold = true到生成的控制器中

我没有验证以下是否有所不同,但我也在 Config.groovy 中设置了grails.mime.disable.accept.header.userAgents = []and grails.mime.use.accept.header = true(后者大概是新的默认值)。

脚手架的 REST 和 UI 界面都可以在以下测试中正常工作:

  • GET /app//1(传递 Accept 标头)
  • GET /app//1.json(没有 Accept 标头)
  • POST /app/(有效载荷为 json 或表单编码)
  • 删除 /app//1
  • PUT /app//1 (带有 json 有效负载。表单有效负载更新了对象,但发回了 302 重定向)

编辑

  1. 删除了资源注释步骤并阐明了 URL 映射设置
  2. URL 映射中分配的URI与控制器的默认 URI 不同。例如,“书”而不是“书”。添加此映射后,控制器的 URI 将默认为 UrlMapping 中的 URI,但原始 URI 将继续工作。
于 2014-12-25T17:02:10.503 回答
1

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

  • 控制器: BookController { 静态脚手架 = true }
  • 域: Book { .... } // 没有 @Resource

结果是您可以:

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

我很邪恶,我知道。我发现了这个,它让我继续前进。

于 2014-06-01T01:57:09.580 回答
1

我遇到了和你一样的问题。这可能是一个微不足道的解决方案,并非适用于所有情况,但请尝试更新您的 Grails 版本。至于我:Grails 2.3.4 -> Grails 2.3.6 有效。希望对任何人都有帮助。

于 2014-03-03T19:34:42.643 回答
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 的书的详细信息。最后

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 公开。该 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 |
于 2013-11-25T19:56:24.387 回答
0

只需要在 Domain 类上使用带有 uri 的 @Resource 注释。如果你想要特定的格式(默认格式是第一个),还包括格式:

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

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

grails url-mappings-report

这将为您提供所有 url 的一个很好的摘要,包括由 @Resource 域的脚手架控制器支持的那些。我发现在尝试“猜测” URL 时,我往往会犯一些愚蠢的错误——使用报告输出可确保您和 grails 达成一致。

于 2015-02-25T23:08:52.750 回答