diff --git a/.github/workflows/node.yml b/.github/workflows/node.yml new file mode 100644 index 000000000..21917fc17 --- /dev/null +++ b/.github/workflows/node.yml @@ -0,0 +1,27 @@ +name: Schema validation tests + +on: + push: + branches: [ gh-pages, schema-1.0 ] + pull_request: + branches: [ gh-pages ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16.x] + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - name: Install dependencies + run: npm ci + - name: Test schemas + run: npm run test-schema \ No newline at end of file diff --git a/.gitignore b/.gitignore index e369c5255..7ae6b8609 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,7 @@ Gemfile.lock /bin /b .rbx + +# Ignore the node_modules directory + +/node_modules diff --git a/CNAME b/CNAME index 7ccb154b0..f8f8a9e05 100644 --- a/CNAME +++ b/CNAME @@ -1 +1 @@ -jsonapi.org +jsonapi.org \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 551f1251d..4fdfb8d1a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,3 +17,28 @@ place. Ideas for new extensions and questions about how to correctly implement or consume an API that adheres to the JSON:API specification belong here. [about]: http://jsonapi.org/about + +## JSON Schema +If you would like to update the JSON schemas, you must first install the node.js dependencies : + +` +npm install +` + +Then you can run the schema validator by running one of the following commands : + +` +node ./_schemas/scripts/validator.js +` + +or + +` +npm run test-schema +` + +This script validates all test files against all available versions of the specification. +Some options can be used : +- `--verbose` : allows more verbose output. +- `-f relative-path` : the relative path of the only file to test. For example : `npm run test-schema -- -f _schemas/1.0/response/valid/with_success/complete.json` +- `-v version` : the version of the specification to use to test the files. For example : `npm run test-schema -- -v 1.0` diff --git a/Gemfile b/Gemfile index 3beb7ee23..a00780760 100644 --- a/Gemfile +++ b/Gemfile @@ -2,19 +2,20 @@ source "https://rubygems.org" # http://jekyllrb.com/docs/github-pages/ require 'json' +require 'uri' require 'open-uri' versions = begin - JSON.parse(open('https://pages.github.com/versions.json').read) + JSON.parse(URI.parse('https://pages.github.com/versions.json').open.read) rescue SocketError { 'github-pages' => 67 } end gem 'github-pages', versions['github-pages'] -gem "rake", "~> 10.0" +gem "rake", "~> 13.0" gem "rb-fsevent", "~> 0.9" gem "compass", "~> 1.0" gem "sass", "~> 3.4" -gem "launchy", "~> 2.3" +gem "launchy", "~> 3.0" gem "redcard", "~> 1.0" diff --git a/_format/1.1/index.md b/_format/1.1/index.md index 54a96e775..108ec9c79 100644 --- a/_format/1.1/index.md +++ b/_format/1.1/index.md @@ -49,7 +49,7 @@ The JSON:API specification supports two media type parameters: `ext` and > Note: A media type parameter is an extra piece of information that can accompany a media type. For example, in the header -`Content-Type: text/html; charset="utf-8"`, the media type is `text/html` and +`Content-Type: text/html;charset="utf-8"`, the media type is `text/html` and `charset` is a parameter. ### Extensions @@ -120,7 +120,7 @@ versioning. This member might appear as follows: ```json HTTP/1.1 200 OK -Content-Type: application/vnd.api+json; ext="https://jsonapi.org/ext/version" +Content-Type: application/vnd.api+json;ext="https://jsonapi.org/ext/version" // ... { @@ -142,7 +142,7 @@ The rules for profile usage are dictated by [RFC A profile **MAY** define document members and processing rules that are reserved for implementors. -A profile **MUST NOT** define any query parameters. +A profile **MUST NOT** define any query parameters except [implementation-specific query parameters](#query-parameters-custom). A profile **MUST NOT** alter or remove processing rules that have been defined by this specification or by an [extension][extensions]. However, a profile @@ -169,7 +169,7 @@ With such a profile applied, a response might appear as follows: ```json HTTP/1.1 200 OK -Content-Type: application/vnd.api+json; profile="https://example.com/resource-timestamps" +Content-Type: application/vnd.api+json;profile="https://example.com/resource-timestamps" // ... { @@ -302,7 +302,7 @@ The members `data` and `errors` **MUST NOT** coexist in the same document. A document **MAY** contain any of these top-level members: * `jsonapi`: an object describing the server's implementation. -* `links`: a [links object][links] related to the primary data. +* `links`: a [links object][links] related to the document as a whole. * `included`: an array of [resource objects] that are related to the primary data and/or each other ("included resources"). @@ -473,7 +473,7 @@ as attributes. Instead, [relationships] **SHOULD** be used. ##### Relationships The value of the `relationships` key **MUST** be an object (a "relationships -object"). Each member of a relationships object ("relationships") represents +object"). Each member of a relationships object represents a "relationship" from the [resource object][resource objects] in which it has been defined to other resource objects. @@ -2090,13 +2090,19 @@ family. A "query parameter family" is the set of all query parameters whose name starts with a "base name", followed by zero or more instances of empty square brackets -(i.e. `[]`) or square-bracketed legal [member names]. The family is referred to +(i.e. `[]`), square-bracketed legal [member names], or square-bracketed +dot-separated lists of legal member names. The family is referred to by its base name. For example, the `filter` query parameter family includes parameters named: `filter`, `filter[x]`, `filter[]`, `filter[x][]`, `filter[][]`, `filter[x][y]`, -etc. However, `filter[_]` is not a valid parameter name in the family, because -`_` is not a valid [member name][member names]. +`filter[x.y]`, etc. However, `filter[_]` is not a valid parameter name in the +family, because `_` is not a valid [member name][member names]. + +> Note: Dot separated lists of legal member names are intended to be used for +> relationship paths. For example, this allows filtering strategies using +> relationship paths as defined for [sorting][fetching sorting] in query parameters +> such as `GET /posts?sort=author.name&filter[author.status]=active`. ### Extension-Specific Query Parameters @@ -2149,10 +2155,10 @@ least one of: * `id`: a unique identifier for this particular occurrence of the problem. * `links`: a [links object][links] that **MAY** contain the following members: * `about`: a [link][link] that leads to further details about this - particular occurrence of the problem. When derefenced, this URI **SHOULD** + particular occurrence of the problem. When dereferenced, this URI **SHOULD** return a human-readable description of the error. * `type`: a [link][link] that identifies the type of error that this - particular error is an instance of. This URI **SHOULD** be dereferencable to + particular error is an instance of. This URI **SHOULD** be dereferenceable to a human-readable explanation of the general error. * `status`: the HTTP status code applicable to this problem, expressed as a string value. This **SHOULD** be provided. @@ -2204,7 +2210,7 @@ parsing algorithm. The resulting value might not be a string. > as delimiters. These issues motivate the exception that JSON:API defines above. Similarly, to serialize a query parameter into a URI, an implementation **MUST** -use the [the `application/x-www-form-urlencoded` serializer](https://url.spec.whatwg.org/#concept-urlencoded-serializer), +use [the `application/x-www-form-urlencoded` serializer](https://url.spec.whatwg.org/#concept-urlencoded-serializer), with the corresponding exception that a parameter's value — but not its name — may be serialized differently than that algorithm requires, provided the serialization does not interfere with the ability to parse back the resulting URI. @@ -2241,7 +2247,12 @@ request as equivalent to one in which the square brackets were percent-encoded. [profiles]: #profiles [error details]: #errors [error object]: #error-objects -[error objects]: #errror-objects +[error objects]: #error-objects [member names]: #document-member-names [pagination]: #fetching-pagination [query parameter family]: #query-parameters-families +[fetching filtering]: #fetching-filtering +[fetching pagination]: #fetching-pagination +[fetching resources]: #fetching-resources +[fetching sorting]: #fetching-sorting +[fetching sparse fieldsets]: #fetching-sparse-fieldsets diff --git a/_format/1.2/index.md b/_format/1.2/index.md index f647647a4..acff1ac7b 100644 --- a/_format/1.2/index.md +++ b/_format/1.2/index.md @@ -17,6 +17,14 @@ JSON:API requires use of the JSON:API media type ([`application/vnd.api+json`](http://www.iana.org/assignments/media-types/application/vnd.api+json)) for exchanging data. +> For additional needs of HTTP APIs, like authentication, documentation, file +> uploads, and more, JSON:API can and should be combined with additional +> standards such as [OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc6749) +> for authorization and [Open API](https://spec.openapis.org/oas/latest.html) +> for documentation. It is allowed for a server supporting JSON:API to also +> support other API standards on the same or other endpoints, such as +> [OData](https://www.odata.org/) or [GraphQL](https://graphql.org/). + ## Semantics All document members, query parameters, and processing rules defined by @@ -50,7 +58,7 @@ The JSON:API specification supports two media type parameters: `ext` and > Note: A media type parameter is an extra piece of information that can accompany a media type. For example, in the header -`Content-Type: text/html; charset="utf-8"`, the media type is `text/html` and +`Content-Type: text/html;charset="utf-8"`, the media type is `text/html` and `charset` is a parameter. ### Extensions @@ -85,6 +93,13 @@ values of the `ext` and `profile` parameters **MUST** equal a space-separated > specification requires that parameter values be surrounded by quotation marks > (U+0022 QUOTATION MARK, "\""). +In the following example, two extensions and one profile have been applied: + +```http +HTTP/1.1 200 OK +Content-Type: application/vnd.api+json;ext="https://example.com/version https://example.com/bulk";profile="https://example.com/resource-timestamps" +``` + #### Rules for Extensions An extension **MAY** impose additional processing rules or further restrictions @@ -121,7 +136,7 @@ versioning. This member might appear as follows: ```json HTTP/1.1 200 OK -Content-Type: application/vnd.api+json; ext="https://jsonapi.org/ext/version" +Content-Type: application/vnd.api+json;ext="https://jsonapi.org/ext/version" // ... { @@ -143,7 +158,7 @@ The rules for profile usage are dictated by [RFC A profile **MAY** define document members and processing rules that are reserved for implementors. -A profile **MUST NOT** define any query parameters. +A profile **MUST NOT** define any query parameters except [implementation-specific query parameters](#query-parameters-custom). A profile **MUST NOT** alter or remove processing rules that have been defined by this specification or by an [extension][extensions]. However, a profile @@ -170,7 +185,7 @@ With such a profile applied, a response might appear as follows: ```json HTTP/1.1 200 OK -Content-Type: application/vnd.api+json; profile="https://example.com/resource-timestamps" +Content-Type: application/vnd.api+json;profile="https://example.com/resource-timestamps" // ... { @@ -303,7 +318,7 @@ The members `data` and `errors` **MUST NOT** coexist in the same document. A document **MAY** contain any of these top-level members: * `jsonapi`: an object describing the server's implementation. -* `links`: a [links object][links] related to the primary data. +* `links`: a [links object][links] related to the document as a whole. * `included`: an array of [resource objects] that are related to the primary data and/or each other ("included resources"). @@ -474,7 +489,7 @@ as attributes. Instead, [relationships] **SHOULD** be used. ##### Relationships The value of the `relationships` key **MUST** be an object (a "relationships -object"). Each member of a relationships object ("relationships") represents +object"). Each member of a relationships object represents a "relationship" from the [resource object][resource objects] in which it has been defined to other resource objects. @@ -2091,13 +2106,19 @@ family. A "query parameter family" is the set of all query parameters whose name starts with a "base name", followed by zero or more instances of empty square brackets -(i.e. `[]`) or square-bracketed legal [member names]. The family is referred to +(i.e. `[]`), square-bracketed legal [member names], or square-bracketed +dot-separated lists of legal member names. The family is referred to by its base name. For example, the `filter` query parameter family includes parameters named: `filter`, `filter[x]`, `filter[]`, `filter[x][]`, `filter[][]`, `filter[x][y]`, -etc. However, `filter[_]` is not a valid parameter name in the family, because -`_` is not a valid [member name][member names]. +`filter[x.y]`, etc. However, `filter[_]` is not a valid parameter name in the +family, because `_` is not a valid [member name][member names]. + +> Note: Dot separated lists of legal member names are intended to be used for +> relationship paths. For example, this allows filtering strategies using +> relationship paths as defined for [sorting][fetching sorting] in query parameters +> such as `GET /posts?sort=author.name&filter[author.status]=active`. ### Extension-Specific Query Parameters @@ -2150,10 +2171,10 @@ least one of: * `id`: a unique identifier for this particular occurrence of the problem. * `links`: a [links object][links] that **MAY** contain the following members: * `about`: a [link][link] that leads to further details about this - particular occurrence of the problem. When derefenced, this URI **SHOULD** + particular occurrence of the problem. When dereferenced, this URI **SHOULD** return a human-readable description of the error. * `type`: a [link][link] that identifies the type of error that this - particular error is an instance of. This URI **SHOULD** be dereferencable to + particular error is an instance of. This URI **SHOULD** be dereferenceable to a human-readable explanation of the general error. * `status`: the HTTP status code applicable to this problem, expressed as a string value. This **SHOULD** be provided. @@ -2205,7 +2226,7 @@ parsing algorithm. The resulting value might not be a string. > as delimiters. These issues motivate the exception that JSON:API defines above. Similarly, to serialize a query parameter into a URI, an implementation **MUST** -use the [the `application/x-www-form-urlencoded` serializer](https://url.spec.whatwg.org/#concept-urlencoded-serializer), +use [the `application/x-www-form-urlencoded` serializer](https://url.spec.whatwg.org/#concept-urlencoded-serializer), with the corresponding exception that a parameter's value — but not its name — may be serialized differently than that algorithm requires, provided the serialization does not interfere with the ability to parse back the resulting URI. @@ -2242,7 +2263,12 @@ request as equivalent to one in which the square brackets were percent-encoded. [profiles]: #profiles [error details]: #errors [error object]: #error-objects -[error objects]: #errror-objects +[error objects]: #error-objects [member names]: #document-member-names [pagination]: #fetching-pagination [query parameter family]: #query-parameters-families +[fetching filtering]: #fetching-filtering +[fetching pagination]: #fetching-pagination +[fetching resources]: #fetching-resources +[fetching sorting]: #fetching-sorting +[fetching sparse fieldsets]: #fetching-sparse-fieldsets diff --git a/_layouts/page.html b/_layouts/page.html index 6555a979c..acd1e512c 100644 --- a/_layouts/page.html +++ b/_layouts/page.html @@ -47,7 +47,7 @@