Json-api: JSON API / JSON-LD integration

Created on 1 May 2015  路  8Comments  路  Source: json-api/json-api

I've been looking over both specifications, and I can see two approaches for apps wishing to use both:

  1. LD over API: Serve the JSON-LD document as the "data" field in the JSON API result.
  2. API over LD: Augment the JSON API result with a JSON-LD context object defining the JSON API schema.

LD over API

The advantage is that JSON API wraps the data and JSON-LD formats the data, which seems in line with the intentions of both specs. The challenge is that the "data" object is required to have an "id" and "type" attribute, which is not part of the JSON-LD spec. It's workable but very inconvenient to use both the JSON API type/id and the JSON-LD @type/@id. It would be preferable to change JSON API to use JSON-LD-style @type/@id names and syntax.

API over LD

The advantage is that JSON-LD is general enough that JSON API is a valid subset (if the root object is augmented with an appropriate context/schema). The disadvantage is that because none of the JSON-API data includes @type or @id keys, they would need to be defined in the context. There would be a lot of duplication because each context would have to include definitions for the standard JSON API type/id/self fields.

Conclusion

It seems to me that the LD over API approach would be preferable, but that would require changes to JSON API that aren't backwards compatible (renaming type/self/id fields). I'd be happy to help make these changes.

extension

Most helpful comment

As I was thinking tonight about extensions, I wanted to mock up what a JSON-LD鈥揳nnotated version of a JSON-API resource object would look like. Below is what I came up with. I'm leaving it here for reference, in case it helps other implementors and/or our efforts at interoperability. Others can comment here too if they figure out a simpler way to do it.

{
  "@context": {
    "links": {"@id": "_:links", "@container": "@set"},
    "attributes": {"@id": "_:attributes", "@container": "@set"},
    "relationships": {"@id": "_:relationships", "@container": "@set"}
  },

  "@id": "http://example.com/live-events/4",
  "@type": "http://schema.org/Event",

  "id": "4",
  "type": "live-events",
  "links": {
    "@context": {
      "self": "@id",
      "collection": {"@id": "http://www.iana.org/assignments/link-relations/collection"}
    },
    "self": "http://example.com/live-events/4",
    "collection": ["http://example.com/events", "http://example.com/live-events"]
  },
  "attributes": {
    "@id": "http://example.com/live-events/4",
    "@context": {
      "startDateTime": {
        "@id": "http://www.schema.org/startDate",
        "@type": "http://www.schema.org/Date"
      }
    },
    "startDateTime": "2015-05-19T06:26:20.167Z"
  },
  "relationships": {
    "@id": "http://example.com/live-events/4",
    "@context": {
      "venue": {"@id": "_:venue", "@container": "@set"}
    },
    "venue": {
      "@id": "http://example.com/live-events/4",
      "@context": {
        "related": {"@id": "http://www.schema.org/location", "@type": "http://schema.org/Place"}
      },
      "related": "http://example.com/venues/1"
    }
  }
}

Note that I'm using the collection relation just as an example; it isn't part of the spec (yet).

All 8 comments

We have discussed using prefixes such as @ many times previously and decided against it. I'm sure that we won't be making such a change to the base spec this close to 1.0 (May 21).

My suggestion is to explore hybrid approaches in (non-additive) extensions.

As I was thinking tonight about extensions, I wanted to mock up what a JSON-LD鈥揳nnotated version of a JSON-API resource object would look like. Below is what I came up with. I'm leaving it here for reference, in case it helps other implementors and/or our efforts at interoperability. Others can comment here too if they figure out a simpler way to do it.

{
  "@context": {
    "links": {"@id": "_:links", "@container": "@set"},
    "attributes": {"@id": "_:attributes", "@container": "@set"},
    "relationships": {"@id": "_:relationships", "@container": "@set"}
  },

  "@id": "http://example.com/live-events/4",
  "@type": "http://schema.org/Event",

  "id": "4",
  "type": "live-events",
  "links": {
    "@context": {
      "self": "@id",
      "collection": {"@id": "http://www.iana.org/assignments/link-relations/collection"}
    },
    "self": "http://example.com/live-events/4",
    "collection": ["http://example.com/events", "http://example.com/live-events"]
  },
  "attributes": {
    "@id": "http://example.com/live-events/4",
    "@context": {
      "startDateTime": {
        "@id": "http://www.schema.org/startDate",
        "@type": "http://www.schema.org/Date"
      }
    },
    "startDateTime": "2015-05-19T06:26:20.167Z"
  },
  "relationships": {
    "@id": "http://example.com/live-events/4",
    "@context": {
      "venue": {"@id": "_:venue", "@container": "@set"}
    },
    "venue": {
      "@id": "http://example.com/live-events/4",
      "@context": {
        "related": {"@id": "http://www.schema.org/location", "@type": "http://schema.org/Place"}
      },
      "related": "http://example.com/venues/1"
    }
  }
}

Note that I'm using the collection relation just as an example; it isn't part of the spec (yet).

Seems like the most reasonable approach. The "links" objects would need "self" keys as well, right?

The one concern I have is naming collisions between the jsonapi keywords and possible schema-defined terms. For example, if someone is trying to represent data that requires a "links" term and attempts to use a context mapping rather than an absolute IRI, they will overwrite the jsonapi "links" data.

The "links" objects would need "self" keys as well, right?

Sure, the self key could exist in the JSON-API response, though that wouldn't be required. I've updated the example from my earlier comment to show what that would look like.

The one concern I have is naming collisions between the jsonapi keywords and possible schema-defined terms.

Yes, this is a risk/inconvenience. It can always be solved by moving the context closer to the data, but it might be a bit of a pain. Not sure there's anything to do about it, though.

This seems like a great discussion for http://discuss.jsonapi.org. There is nothing actionable we can do about this here now, so I'm going to give this a close. Thanks guys!

Noting for #794.

@tkellen ... I'd love to follow any conversation that happened about this somewhere else. Does anyone else have any resources on how this has evolved?

@nathanv Check out #995. That was merged and should allow total integration. If there's something it doesn't support, please let me know.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jfinkels picture jfinkels  路  15Comments

ZenCocoon picture ZenCocoon  路  14Comments

beauby picture beauby  路  12Comments

Ilyes512 picture Ilyes512  路  8Comments

csexton picture csexton  路  5Comments