如何在Rails中为控制器编写JSON模式

时间:2017-03-10 13:04:39

标签: ruby-on-rails json api jsonschema

是否有人可以为控制器编写JSON模式的示例 1)使用CRUD动作 2)使用自定义操作

我有一个api,我需要用JSON模式来描述它,但我不知道如何描述控制器。

我的模型

的JSON模式
{
  "$schema": "http://json-schema.org/draft-04/hyper-schema",
  "title": "Story",
  "description": "Story",
  "type": "object",
  "definitions": {
    "id": {
      "description": "Unique identifier",
      "type": "integer",
      "example": 1
    },
    "user": { "$ref": "#/definitions/user" },
    "title": {
      "description": "Title",
      "type": "string",
      "example": "Example Title"
    },
    "updated_at": {
      "description": "Updated date",
      "type": "string",
      "example": "Mon, 06 Mar 2017 11:07:34 UTC +00:00"
    },
    "created_at": {
      "description": "Created date",
      "type": "string",
      "example": "Mon, 06 Mar 2017 11:07:34 UTC +00:00"
    }
  },
  "properties": {
    "id": {
      "$ref": "#/definitions/id"
    },
    "user": {
      "$ref": "#/definitions/user"
    },
    "title": {
      "$ref": "#/definitions/title"
    },
    "updated_at": {
      "$ref": "#/definitions/updated_at"
    },
    "created_at": {
      "$ref": "#/definitions/created_at"
    }
  },
  "required": [
    "id",
    "title",
    "user"
  ],
  "links": [
    {
      "title": "Index",
      "description": "List of stories",
      "href": "/api/stories",
      "method": "GET",
      "rel": "index",
      "targetSchema": {
        "type": "array",
        "items": { "rel": "self" }
      }
    },
    {
      "title": "Show",
      "description": "Show story",
      "href": "/api/stories/:id",
      "method": "GET",
      "rel": "show",
      "schema": {
        "$ref": "#"
      },
      "targetSchema": {
        "$ref": "#"
      }
    },
    {
      "title": "Create",
      "description": "Create a story",
      "href": "/api/stories",
      "method": "POST",
      "rel": "create",
      "schema": {
        "properties": {
          "title": {
            "$ref": "#/definitions/title"
          }
        }
      }
    },
    {
      "title": "Update",
      "description": "Update a story",
      "href": "/api/stories/:id",
      "method": "PUT",
      "rel": "update",
      "schema": {
        "properties": {
          "title": {
            "$ref": "#/definitions/title"
          }
        }
      },
      "targetSchema": {
        "$ref": "#"
      }
    },
    {
      "title": "Destroy",
      "description": "Destroy a story",
      "href": "/api/stories/:id",
      "method": "DELETE",
      "rel": "destroy",
      "schema": {
        "$ref": "#"
      },
      "targetSchema": {
        "$ref": "#"
      }
    }
  ]
}

1 个答案:

答案 0 :(得分:1)

您没有使用JSON Hyper-Schema描述Rails控制器。这些概念并不完全排列。链接描述资源之间的关系。有时这些关系指的是同一控制器上的动作,但有时它们并不是。根据你到目前为止,你正在看两个模式。一个用于描述故事的模式,另一个用于描述故事列表(索引)。尽管描述控制器没有意义,但我可以帮助您了解如何描述链接。

基本

让我们看看一些关键字并描述如何使用它们。

HREF

除了你使用错误的URI模板语法之外,你在这里得到了正确的想法。 JSON Hyper-Schema使用RFC 6570描述的URI模板语法,该语法与Rails语法不兼容。你必须在两者之间进行翻译。例如,您的"显示" href链接将是。

{
  "href": "/api/stories/{id}"
}

相对

rel描述了资源与链接资源的关系。例如,故事可能具有author链接关系,表示描述故事作者的资源。

棘手的部分是,关系不仅仅是你给它的任何描述性名称。它们必须是IANA Link Relation registry中列出的值,JSON Hyper-Schema defined relations或绝对URI。

如果在这两个位置之一中定义了关系,则该关系应符合它们记录的语义。如果没有适合您需求的现有关系,则需要使用URI而不是字符串。此URI只能是唯一标识符,但建议将其链接到描述关系语义的文档。

{
  "rel": "author"
}

{
  "rel": "http://example.com/relations/foo"
}

模式

将其中一个链接视为HTML表单。 schema描述了用户输入。如果methodGET,则输入将用于构建包含schema所述查询参数的链接。如果methodPOST,则输入将在请求正文中传递。例如,以下内容将构建类似/api/stories?page=1&perPage=10的链接。

{
  "rel": "instances",
  "href": "/api/stories",
  "method": "GET",
  "schema": {
    "type": "object",
    "properties": {
      "page": { "type": "integer" },
      "perPage": { "type": "integer" }
    }
  }
}

targetSchema

此关键字定义请求结果应符合的模式。我建议您不要使用此关键字。回应应该是自我描述的。您不应该需要这个来解释响应。把它留下来吧。

链接

现在我们已经掌握了基础知识,以下是您描述目前为止尝试过的链接的方法。

索引

此链接可能在故事架构上给出。我已经包含了一些分页选项的例子。

{
  "title": "Index",
  "description": "List of stories",
  "rel": "instances",
  "href": "/api/stories",
  "method": "GET",
  "schema": {
    "type": "object",
    "properties": {
      "page": { "type": "integer" },
      "perPage": { "type": "integer" }
    }
  }
}

显示

此链接可能会显示在索引架构上,显示如何从故事列表中检索单个故事。

{
  "title": "Show",
  "description": "Show story",
  "rel": "http://example.com/relations/story",
  "href": "/api/stories/{id}"
}

这样的事情也可能出现在故事​​模式上,但作为一个自我链接。

{
  "rel": "self",
  "href": "/api/stories/{id}"
}

创建

此链接可能会显示在您的api流程中有意义的任何位置。

{
  "title": "Create",
  "description": "Create a story",
  "rel": "create",
  "href": "/api/stories",
  "method": "POST",
  "schema": {
    "properties": {
      "title": {
        "$ref": "#/definitions/title"
      }
    }
  }
}

更新

此示例假定此链接位于故事架构上。由于href指向自身,因此无需定义schema关键字,因为资源的架构已知。

{
  "title": "Update",
  "description": "Update a story",
  "rel": "edit",
  "href": "/api/stories/{id}",
  "method": "PUT"
}

破坏

此示例假定此链接位于故事架构上。 DELETE操作不采用请求正文,因此您不应在此处包含schema关键字。

{
  "title": "Destroy",
  "description": "Destroy a story",
  "rel": "http://example.com/relations/destroy",
  "href": "/api/stories/{id}",
  "method": "DELETE"
}