mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-22 22:06:50 +00:00
Mapping JSON API spec / schema to AMS [ci skip]
This commit is contained in:
parent
48b041ecae
commit
cf34a66527
138
docs/jsonapi/schema.md
Normal file
138
docs/jsonapi/schema.md
Normal file
@ -0,0 +1,138 @@
|
||||
[](http://jsonapi.org/)
|
||||
|
||||
## JSON API Requests
|
||||
|
||||
[Query Parameters Spec](http://jsonapi.org/format/#query-parameters)
|
||||
|
||||
Headers:
|
||||
|
||||
- Request: `Accept: application/vnd.api+json`
|
||||
- Response: `Content-Type: application/vnd.api+json`
|
||||
|
||||
### [Fetching Data](http://jsonapi.org/format/#fetching)
|
||||
|
||||
A server MUST support fetching resource data for every URL provided as:
|
||||
|
||||
- a `self` link as part of the top-level links object
|
||||
- a `self` link as part of a resource-level links object
|
||||
- a `related` link as part of a relationship-level links object
|
||||
|
||||
Example supported requests
|
||||
|
||||
- Individual resource or collection
|
||||
- GET /articles
|
||||
- GET /articles/1
|
||||
- GET /articles/1/author
|
||||
- Relationships
|
||||
- GET /articles/1/relationships/comments
|
||||
- GET /articles/1/relationships/author
|
||||
- Optional: [Inclusion of related resources](http://jsonapi.org/format/#fetching-includes) `ActiveModel::Serializer::Fieldset`
|
||||
- GET /articles/1?`include`=comments
|
||||
- GET /articles/1?`include`=comments.author
|
||||
- GET /articles/1?`include`=author,comments.author
|
||||
- GET /articles/1/relationships/comments?`include`=comments.author
|
||||
- Optional: [Sparse Fieldsets](http://jsonapi.org/format/#fetching-sparse-fieldsets) `ActiveModel::Serializer::Fieldset`
|
||||
- GET /articles?`include`=author&`fields`[articles]=title,body&`fields`[people]=name
|
||||
- Optional: [Sorting](http://jsonapi.org/format/#fetching-sorting)
|
||||
- GET /people?`sort`=age
|
||||
- GET /people?`sort`=age,author.name
|
||||
- GET /articles?`sort`=-created,title
|
||||
- Optional: [Pagination](http://jsonapi.org/format/#fetching-pagination)
|
||||
- GET /articles?`page`[number]=3&`page`[size]=1
|
||||
- Optional: [Filtering](http://jsonapi.org/format/#fetching-filtering)
|
||||
- GET /comments?`filter`[post]=1
|
||||
- GET /comments?`filter`[post]=1,2
|
||||
- GET /comments?`filter`[post]=1,2
|
||||
|
||||
### [CRUD Actions](http://jsonapi.org/format/#crud)
|
||||
|
||||
### [Asynchronous Processing](http://jsonapi.org/recommendations/#asynchronous-processing)
|
||||
|
||||
### [Bulk Operations Extension](http://jsonapi.org/extensions/bulk/)
|
||||
|
||||
## JSON API Document Schema
|
||||
|
||||
| JSON API object | JSON API properties | Required | ActiveModelSerializers representation |
|
||||
|-----------------------|----------------------------------------------------------------------------------------------------|----------|---------------------------------------|
|
||||
| schema | oneOf (success, failure, info) | |
|
||||
| success | data, included, meta, links, jsonapi | | ActiveModel::SerializableResource
|
||||
| success.meta | meta | | ActiveModel::Serializer::Adapter::Base#meta
|
||||
| success.included | UniqueArray(resource) | | ActiveModel::Serializer::Adapter::JsonApi#serializable_hash_for_collection
|
||||
| success.data | data | |
|
||||
| success.links | allOf (links, pagination) | | ActiveModel::Serializer::Adapter::JsonApi#links_for
|
||||
| success.jsonapi | jsonapi | |
|
||||
| failure | errors, meta, jsonapi | errors |
|
||||
| failure.errors | UniqueArray(error) | | #1004
|
||||
| meta | Object | |
|
||||
| data | oneOf (resource, UniqueArray(resource)) | | ActiveModel::Serializer::Adapter::JsonApi#serializable_hash_for_collection,#serializable_hash_for_single_resource
|
||||
| resource | String(type), String(id), attributes, relationships, links, meta | type, id | ActiveModel::Serializer::Adapter::JsonApi#primary_data_for
|
||||
| links | Uri(self), Link(related) | | #1028, #1246, #1282
|
||||
| link | oneOf (linkString, linkObject) | |
|
||||
| link.linkString | Uri | |
|
||||
| link.linkObject | Uri(href), meta | href |
|
||||
| attributes | patternProperites(`"^(?!relationships$|links$)\\w[-\\w_]*$"`), any valid JSON | | ActiveModel::Serializer#attributes, ActiveModel::Serializer::Adapter::JsonApi#resource_object_for
|
||||
| relationships | patternProperites(`"^\\w[-\\w_]*$"`); links, relationships.data, meta | | ActiveModel::Serializer::Adapter::JsonApi#relationships_for
|
||||
| relationships.data | oneOf (relationshipToOne, relationshipToMany) | | ActiveModel::Serializer::Adapter::JsonApi#resource_identifier_for
|
||||
| relationshipToOne | anyOf(empty, linkage) | |
|
||||
| relationshipToMany | UniqueArray(linkage) | |
|
||||
| empty | null | |
|
||||
| linkage | String(type), String(id), meta | type, id | ActiveModel::Serializer::Adapter::JsonApi#primary_data_for
|
||||
| pagination | pageObject(first), pageObject(last), pageObject(prev), pageObject(next) | | ActiveModel::Serializer::Adapter::JsonApi::PaginationLinks#serializable_hash
|
||||
| pagination.pageObject | oneOf(Uri, null) | |
|
||||
| jsonapi | String(version), meta | | ActiveModel::Serializer::Adapter::JsonApi::ApiObjects::JsonApi
|
||||
| error | String(id), links, String(status), String(code), String(title), String(detail), error.source, meta | |
|
||||
| error.source | String(pointer), String(parameter) | |
|
||||
| pointer | [JSON Pointer RFC6901](https://tools.ietf.org/html/rfc6901) | |
|
||||
|
||||
|
||||
The [http://jsonapi.org/schema](schema/schema.json) makes a nice roadmap.
|
||||
|
||||
### Success Document
|
||||
- [ ] success
|
||||
- [ ] data: `"$ref": "#/definitions/data"`
|
||||
- [ ] included: array of unique items of type `"$ref": "#/definitions/resource"`
|
||||
- [ ] meta: `"$ref": "#/definitions/meta"`
|
||||
- [ ] links:
|
||||
- [ ] link: `"$ref": "#/definitions/links"`
|
||||
- [ ] pagination: ` "$ref": "#/definitions/pagination"`
|
||||
- [ ] jsonapi: ` "$ref": "#/definitions/jsonapi"`
|
||||
|
||||
### Failure Document
|
||||
|
||||
- [ ] failure
|
||||
- [ ] errors: array of unique items of type ` "$ref": "#/definitions/error"`
|
||||
- [ ] meta: `"$ref": "#/definitions/meta"`
|
||||
- [ ] jsonapi: `"$ref": "#/definitions/jsonapi"`
|
||||
|
||||
### Info Document
|
||||
|
||||
- [ ] info
|
||||
- [ ] meta: `"$ref": "#/definitions/meta"`
|
||||
- [ ] links: `"$ref": "#/definitions/links"`
|
||||
- [ ] jsonapi: ` "$ref": "#/definitions/jsonapi"`
|
||||
|
||||
### Definitions
|
||||
|
||||
- [ ] definitions:
|
||||
- [ ] meta
|
||||
- [ ] data: oneOf (resource, array of unique resources)
|
||||
- [ ] resource
|
||||
- [ ] attributes
|
||||
- [ ] relationships
|
||||
- [ ] relationshipToOne
|
||||
- [ ] empty
|
||||
- [ ] linkage
|
||||
- [ ] meta
|
||||
- [ ] relationshipToMany
|
||||
- [ ] linkage
|
||||
- [ ] meta
|
||||
- [ ] links
|
||||
- [ ] meta
|
||||
- [ ] links
|
||||
- [ ] link
|
||||
- [ ] uri
|
||||
- [ ] href, meta
|
||||
- [ ] pagination
|
||||
- [ ] jsonapi
|
||||
- [ ] meta
|
||||
- [ ] error: id, links, status, code, title: detail: source [{pointer, type}, {parameter: {description, type}], meta
|
||||
366
docs/jsonapi/schema/schema.json
Normal file
366
docs/jsonapi/schema/schema.json
Normal file
@ -0,0 +1,366 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "JSON API Schema",
|
||||
"description": "This is a schema for responses in the JSON API format. For more, see http://jsonapi.org",
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/success"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/failure"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/info"
|
||||
}
|
||||
],
|
||||
|
||||
"definitions": {
|
||||
"success": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/data"
|
||||
},
|
||||
"included": {
|
||||
"description": "To reduce the number of HTTP requests, servers **MAY** allow responses that include related resources along with the requested primary resources. Such responses are called \"compound documents\".",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/resource"
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
},
|
||||
"links": {
|
||||
"description": "Link members related to the primary data.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/links"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/pagination"
|
||||
}
|
||||
]
|
||||
},
|
||||
"jsonapi": {
|
||||
"$ref": "#/definitions/jsonapi"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"failure": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"errors"
|
||||
],
|
||||
"properties": {
|
||||
"errors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/error"
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
},
|
||||
"jsonapi": {
|
||||
"$ref": "#/definitions/jsonapi"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"info": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
},
|
||||
"links": {
|
||||
"$ref": "#/definitions/links"
|
||||
},
|
||||
"jsonapi": {
|
||||
"$ref": "#/definitions/jsonapi"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"meta": {
|
||||
"description": "Non-standard meta-information that can not be represented as an attribute or relationship.",
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"data": {
|
||||
"description": "The document's \"primary data\" is a representation of the resource or collection of resources targeted by a request.",
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/resource"
|
||||
},
|
||||
{
|
||||
"description": "An array of resource objects, an array of resource identifier objects, or an empty array ([]), for requests that target resource collections.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/resource"
|
||||
},
|
||||
"uniqueItems": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"resource": {
|
||||
"description": "\"Resource objects\" appear in a JSON API document to represent resources.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"id"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"attributes": {
|
||||
"$ref": "#/definitions/attributes"
|
||||
},
|
||||
"relationships": {
|
||||
"$ref": "#/definitions/relationships"
|
||||
},
|
||||
"links": {
|
||||
"$ref": "#/definitions/links"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"links": {
|
||||
"description": "A resource object **MAY** contain references to other resource objects (\"relationships\"). Relationships may be to-one or to-many. Relationships can be specified by including a member in a resource's links object.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"self": {
|
||||
"description": "A `self` member, whose value is a URL for the relationship itself (a \"relationship URL\"). This URL allows the client to directly manipulate the relationship. For example, it would allow a client to remove an `author` from an `article` without deleting the people resource itself.",
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"related": {
|
||||
"$ref": "#/definitions/link"
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
},
|
||||
"link": {
|
||||
"description": "A link **MUST** be represented as either: a string containing the link's URL or a link object.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "A string containing the link's URL.",
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"href"
|
||||
],
|
||||
"properties": {
|
||||
"href": {
|
||||
"description": "A string containing the link's URL.",
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"attributes": {
|
||||
"description": "Members of the attributes object (\"attributes\") represent information about the resource object in which it's defined.",
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^(?!relationships$|links$)\\w[-\\w_]*$": {
|
||||
"description": "Attributes may contain any valid JSON value."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"relationships": {
|
||||
"description": "Members of the relationships object (\"relationships\") represent references from the resource object in which it's defined to other resource objects.",
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^\\w[-\\w_]*$": {
|
||||
"properties": {
|
||||
"links": {
|
||||
"$ref": "#/definitions/links"
|
||||
},
|
||||
"data": {
|
||||
"description": "Member, whose value represents \"resource linkage\".",
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/relationshipToOne"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/relationshipToMany"
|
||||
}
|
||||
]
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"relationshipToOne": {
|
||||
"description": "References to other resource objects in a to-one (\"relationship\"). Relationships can be specified by including a member in a resource's links object.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/empty"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/linkage"
|
||||
}
|
||||
]
|
||||
},
|
||||
"relationshipToMany": {
|
||||
"description": "An array of objects each containing \"type\" and \"id\" members for to-many relationships.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/linkage"
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"empty": {
|
||||
"description": "Describes an empty to-one relationship.",
|
||||
"type": "null"
|
||||
},
|
||||
"linkage": {
|
||||
"description": "The \"type\" and \"id\" to non-empty members.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"id"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"pagination": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"first": {
|
||||
"description": "The first page of data",
|
||||
"oneOf": [
|
||||
{ "type": "string", "format": "uri" },
|
||||
{ "type": "null" }
|
||||
]
|
||||
},
|
||||
"last": {
|
||||
"description": "The last page of data",
|
||||
"oneOf": [
|
||||
{ "type": "string", "format": "uri" },
|
||||
{ "type": "null" }
|
||||
]
|
||||
},
|
||||
"prev": {
|
||||
"description": "The previous page of data",
|
||||
"oneOf": [
|
||||
{ "type": "string", "format": "uri" },
|
||||
{ "type": "null" }
|
||||
]
|
||||
},
|
||||
"next": {
|
||||
"description": "The next page of data",
|
||||
"oneOf": [
|
||||
{ "type": "string", "format": "uri" },
|
||||
{ "type": "null" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"jsonapi": {
|
||||
"description": "An object describing the server's implementation",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"error": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "A unique identifier for this particular occurrence of the problem.",
|
||||
"type": "string"
|
||||
},
|
||||
"links": {
|
||||
"$ref": "#/definitions/links"
|
||||
},
|
||||
"status": {
|
||||
"description": "The HTTP status code applicable to this problem, expressed as a string value.",
|
||||
"type": "string"
|
||||
},
|
||||
"code": {
|
||||
"description": "An application-specific error code, expressed as a string value.",
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"description": "A short, human-readable summary of the problem. It **SHOULD NOT** change from occurrence to occurrence of the problem, except for purposes of localization.",
|
||||
"type": "string"
|
||||
},
|
||||
"detail": {
|
||||
"description": "A human-readable explanation specific to this occurrence of the problem.",
|
||||
"type": "string"
|
||||
},
|
||||
"source": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"pointer": {
|
||||
"description": "A JSON Pointer [RFC6901] to the associated entity in the request document [e.g. \"/data\" for a primary data object, or \"/data/attributes/title\" for a specific attribute].",
|
||||
"type": "string"
|
||||
},
|
||||
"parameter": {
|
||||
"description": "A string indicating which query parameter caused the error.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user