REST API include relationships data?

Hi, I’d like to retrieve the data for an item including the data of its related media through a single API call.

Currently, the /api/items/[item id] returns only links to some related objects like media, resource classes, resource templates etc.:

Is there a way to programmatically request the API to include the data of a set of related objects that would be passed as parameters and merge these data in the resulting tree?

There’s no extend/expand feature for the REST API. Your best possibility on this front without modifying/extending the API with a module is two requests, api/items/<id> and api/media?item_id=<id> to get all the media for that item.

Yes I know how to get the data with 2 requests. My question is about retrieving them with only one request. And of course Programmatically means for example extending the API with a module. I only need directions on where to start from.

The event rep.resource.json is the usual way to add to or modify the JSON output for a resource.

In a module you’d attach to that event in the Module class’s attachListeners method:

$sharedEventManager->attach(
    'Omeka\Api\Representation\ItemRepresentation',
    'rep.resource.json',
    [$this, 'yourListener']
);

The media in the regular output are using “reference” objects, which produce those links when serialized to JSON. You’d want to instead have the representation object for them, which will serialize to the full output. If you instead have specific data you want to include you can do that instead, of course.

1 Like

Awesome, thanks John. My approach is inspired by the JSON:API concepts in their way to include resources linked to the item being requested, thus reducing the amount of code and network requests.

Note that one of most important quality of omeka is to be semantic, so rdf and json-ld, so not sure if json-api can be used. The interest of json-ld is to be structured and standard, and not to repeat everything everywhere. Anyway, you can use your own module to add anything to json, as many modules do.

About json serialization, note that the method $resource->jsonSerialize() is currently not a real json, because there are php objects inside it. So you will have to do json_decode(json_encode($resource), true) for now to have a real json. There is a pr here about this issue : Full json serializing representations by Daniel-KM · Pull Request #2317 · omeka/omeka-s · GitHub .

1 Like

Hehe… Daniel is in the place! Looks like this subject is more critical then I expected :sweat_smile:

Well I don’t know if the JSON-LD specification allows data of the linked resources to be embedded in addition to the links :thinking:

Yes, it is allowed. So you can replace media [o:id and @id] with the full media serialization, but take care of recursion.

Cool! Thanks Daniel, I will be careful :wink:

So I have written a small working module that gets data for some linked resources (primary media in the example below).

You can configure the way the linked data is merged with the original tree: under the key of the linked resource (example below) or under a specific key attached to the tree root.

Now, I would like to get the same functionality when requesting the REST API. Which event should I attach to?

If you’re using the event we discussed, it should already be affecting the REST API output. Or maybe I’m not understanding what you mean when you say you want “the same functionality when requesting the REST API.”

Oups… I had an erroneous condition on isSiteRequest() in my code :face_with_hand_over_mouth:

It works fine, thanks again John :slightly_smiling_face: