如何在 Rails 中为控制器编写 JSON 架构

How to write JSON schema for controllers in Rails

任何人都可以为控制器编写 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": "#"
      }
    }
  ]
}

您没有使用 JSON Hyper-Schema 描述 Rails 控制器。这些概念不太一致。链接描述了资源之间的关系。有时这些关系指的是同一控制器上的操作,但有时它们不是。根据您目前所拥有的,您正在查看两个模式。一个模式描述故事,另一个模式描述故事列表(索引)。虽然描述控制器没有意义,但我可以帮助您理解如何描述 links.

#基础知识 让我们看一些关键字并描述如何使用它们。

##href 除了使用错误的 URI 模板语法外,您的想法是正确的。 JSON Hyper-Schema 使用 RFC 6570 描述的 URI 模板语法,它与 Rails 语法不兼容。您将不得不在两者之间进行翻译。例如,您的“节目”link 的 href 将是。

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

##rel rel 描述资源与被 link 编辑的资源的关系。例如,一个故事可能有一个 author link 关系,表示描述故事作者的资源。

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

如果关系是在这两个地方之一定义的,则该关系应符合它们被记录为具有的语义。如果没有满足您需要的现有关系,您需要使用 URI 而不是字符串。此 URI 可以只是一个唯一标识符,但建议将其 link 用于描述关系语义的文档。

{
  "rel": "author"
}

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

##架构 将这些 link 之一视为 HTML 形式。 schema 描述用户输入。如果 methodGET,输入将用于构建一个 link,其查询参数由 schema 描述。如果 methodPOST,输入将在请求正文中传递。例如,下面将构建一个 link 类似 /api/stories?page=1&perPage=10.

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

##目标架构 此关键字定义请求结果应符合的架构。我建议您不要使用此关键字。响应应该是自我描述的。您永远不需要这个来解释响应。别管它了。

#链接 现在我们已经掌握了基础知识,下面是您如何描述您迄今为止尝试过的 links。

##索引 这个 link 可能会在故事模式中给出。我提供了一些分页选项的示例。

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

##显示 link 可能会显示在索引模式中,展示如何从故事列表中检索单个故事。

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

像这样的东西也可能出现在故事​​模式中,但作为一个自我 link。

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

##创建 此 link 可能会出现在您的 api.

流程中任何有意义的地方
{
  "title": "Create",
  "description": "Create a story",
  "rel": "create",
  "href": "/api/stories",
  "method": "POST",
  "schema": {
    "properties": {
      "title": {
        "$ref": "#/definitions/title"
      }
    }
  }
}

##更新 此示例假定此 link 在故事模式中。因为 href 指向它自己,所以没有必要定义 schema 关键字,因为资源的模式是已知的。

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

##销毁 此示例假定此 link 在故事模式中。 DELETE 操作没有请求主体,因此您不应在此处包含 schema 关键字。

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