Pagination and Error Source spec compliance

Hi,

after reading #851, #147 etc, I understood that

Unless otherwise noted, objects defined by this specification MUST NOT contain any additional members. Client and server implementations MUST ignore members not recognized by this specification.

This schema is as restrictive as possible, but has flexibility to be extended within your documentation. Validation will not yield false negatives, but could yield false positives for the sake of flexibility.

so to confirm, for Pagination links

the spec said:

The following keys MUST be used for pagination links:

  • first : the first page of data
  • last : the last page of data
  • prev : the previous page of data
  • next : the next page of data

But something like the following could pass the validation

    "links": {
        "next": "http://xxx/2",
        "otherLinks": {
            "3": "http://xxx/3",
            "4": "http://xxx/4"
        }
    }

Questions:

  1. can Pagination have keys other than ‘first’, ‘last’, ‘prev’, ‘next’ to be regarded as compliant with the spec (or media type ‘application/vnd.api+json’)?

  2. similarly, can Error Source property have keys other than ‘pointer’ and ‘parameter’? (e.g., other keys like ‘header’)

Hi @bokara,

A server MAY provide links to traverse a paginated data set (“pagination links”).

This is why the case above passes the validation, you are not required to always have these links in your message. However…

The following keys MUST be used for pagination links:

  • first : the first page of data
  • last : the last page of data
  • prev : the previous page of data
  • next : the next page of data

The schema cannot valid the constraint above, as it refers to how to use these labels (i.e., “first”, “last”, “prev”, and “next”). The only thing the schema can do is to check if these labels/fields are assigned to null or a URL string whenever they are present.

Other than that, you may implement the standard adding links other than the ones listed (for pagination or anything else that suits the purpose of the “links” object).

similarly, can Error Source property have keys other than ‘pointer’ and ‘parameter’? (e.g., other keys like ‘header’)

About this

An error object MAY have the following members:

source : an object containing references to the source of the error, optionally including any of the following members:

  • pointer : 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].
  • parameter : a string indicating which URI query parameter caused the error.

These are MAY conditions. You can implement these things however you so desire. I only recommend you to local around how people usually solve these problems so you avoid making bad design decisions.

P.s.: you could enjoy having a look at this here:

Conventions
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 [RFC2119].

@claudenirmf,
Thank you for the detailed and helpful response; greatly appreciated.

I would like to confirm about the links example in the original post (to help me better understand the spec)

  • technically, that should still fail the validation? because the otherLinks is not a valid link object?

i.e.,

This is VALID,

    "links": {
        "next": "http://xxx/2",
        "otherLinks": {
            "href": "http://xxx/3"
        }
    }

or this is also VALID:

    "links": {
        "next": "http://xxx/2",
        "3": "http://xxx/3",
        "4": "http://xxx/4"
    }

But this is INVALID?

    "links": {
        "next": "http://xxx/2",
        "otherLinks": {
            "3": "http://xxx/3",
            "4": "http://xxx/4"
        }
    }

would that be correct?

You must refer to the definition of “link”:

Links
Where specified, a links member can be used to represent links. The value of each links member MUST be an object (a “links object”).
Each member of a links object is a “link”. A link MUST be represented as either:

  • a string containing the link’s URL.
  • an object (“link object”) which can contain the following members:
    • href : a string containing the link’s URL.
    • meta : a meta object containing non-standard meta-information about the link.

But I admit that the sentence “which can contain the following members” is not as clear as I would like. So I would (personally) trust the schema and say that “otherLinks” is valid.

Still, avoid making choices that are too edgy unless you are certain of your requirements. They may very well be bad design decisions.

Btw, I have not tested it myself. I am trusting you when you said that the schema allows it.

Based on the text of the specification, “otherLinks”, “3”, and “4” are all invalid.

Thanks, @fdrake. I’ll try to test the schema later and submit an issue in case these need to be prevented.

this was my understanding,

  • the “3”, “4” examples could be VALID “links”, but not necessarily valid “pagination” (because according to spec, the ‘prev’ etc keys are MUST?)

  • the “otherLinks” object (with the “3” “4” properties) is INVALID link object because link object requires “href” property, according to the jsonapi schema, so the “otherLinks” object is INVALID both as pagination and/or just as a link?

    "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-reference"
        },
        {
          "type": "object",
          "required": [
            "href"
          ],
          "properties": {
            "href": {
              "description": "A string containing the link's URL.",
              "type": "string",
              "format": "uri-reference"
            },
            "meta": {
              "$ref": "#/definitions/meta"
            }
          }
        }
      ]
    },

So technically, for the documentation,

an object (“link object”) which can contain the following members:

  • href : a string containing the link’s URL.
  • meta : a meta object containing non-standard meta-information about the link.

the can contain is not really true for href (it’s a MUST for href)?

P.S…, the validation test I did in the first post was just from the jsonapi-validator link in the JSONAPI Implementations page.

I tried another schema validation site and seemed that this is indeed VALID:

  "links": {
    
    "self": "http://testxxx/2",
      "4": "http://testxxx/4",
      "prev": {
        "href": "http://testxxx/1"
      },
      "next": "http://testxxx/3"
  },

And with issue #887, it feels like the pagination schema is kinda redundant? i.e., it doesn’t really help in enforcing anything? (i.e., the ‘prev’, ‘next’, ‘first’, ‘last’ are kinda just recommended keywords to use for pagination? as “#/definitions/links” would be the real (and only) validating schema for links?)

@bokara: I think we’re mis-communicating a bit.

I see your link to the JSON Schema that describes JSON:API responses, but… that’s not the specification. (I can’t even find a link to that schema from the site, though I could just be overlooking something.)

This is the specification I’m referring to:

My understanding is that the specification is canonical, not the schema. Your initial post in this thread indicates you understand that the schema can validate non-conforming documents:

Validation will not yield false negatives, but could yield false positives for the sake of flexibility.

So, my understanding, which took some time to arrive at, is that if something is not specifically allowed in the specification, if is not allowed. What follows is that the links object CAN contain the following names:

  • self
  • related (when the links object is part of a relationship)
  • first
  • next
  • last
  • prev

self and related cannot be null; the pagination links can be. The pagination links can only be present for the primary data when it’s a collection, or for a to-many relationship.

JSON:API 1.1 changes things a bit, but that’s not final yet.

-Fred

@fdrake,
thank you for the clarification! yeah, I think we (me) mixed up the spec and schema a bit, sorry about that.

regarding

I can’t even find a link to that schema from the site…

It’s from the site’s FQA page

self and related cannot be null ; the pagination links can be.

That might be the intent of the spec, but seems not feasible technically. i.e., pagination links cannot be null; according to issues #887 / #1512

What follows is that the links object CAN contain the following names:

  • self
  • related (when the links object is part of a relationship)
  • first
  • next
  • last
  • prev

That’s actually what I tried to find out / confirm with this post originally… i.e., “CAN contain the following names”, so is it just “CAN contain”, or “CAN ONLY contain”? i.e.,

  1. other than those 6 names, CAN the links object contain other names?

  2. If the pagination links can NOT be null technically, then can some of the names be missing? e.g., if didn’t want to provide the last link, can it be missing? (currently the spec said prev, next, first, lastMUST be used for pagination links”)

The Pagination section says the pagination links can be null:

Keys MUST either be omitted or have a null value to indicate that a particular link is unavailable.

The Links section says a link must be represented as a string or a “link object”. That’s the “contradiction” referenced in issue #1512.

I’m interpreting this as:

  • the pagination keys may be present in the links object, but
  • if they are null, they aren’t actually links.

It’s not as clean as it should be (hence, the continuing confusion and those open issues), but that’s how things are in the 1.0 specification. (I don’t actually see anything in the specification that says a link object MUST contain an href property, which seems unfortunate.)

I don’t know what you mean about it not being technically feasible; perhaps you’re thinking about the JSON Schema specification, which isn’t canonical?

@fdrake,
thank you for pointing out the “… either be omitted or have a null value”, missed the “be omitted” part.

I don’t know what you mean about it not being technically feasible…

I was referring to currently if a pagination link is null (or any link for that matter), the (schema) validation will FAIL. the problem was captured in issue #887. i.e., the schema is not capable of distinguishing if it’s a pagination link and nullable…

so I guess if a pagination link is null, then just omit it?

Or use a better schema.

Omitting the property completely instead of including null has the advantage of being easy and compliant with a schema the client (or your tests) might already be using.

Using a better schema has the advantage that a better schema becomes available.

-Fred

1 Like