Обнаружение ссылок JSON-LD+Hydra

Я думал о том, как использовать JSON-LD для управления приложением в соответствии с принципом HATEOAS.

Например, у меня может быть простой объект точки входа, который определяет ссылку:

{
  "@context": {
    "users": { "@id": "http://example.com/onto#users", "@type": "@id" }
  },
  "@id": "http://example.com/api",
  "users": "http://example.com/users"
}

И предикат #users будет определен как Link с помощью Hydra:

{
  "@context": "http://www.w3.org/ns/hydra/context.jsonld",
  "@id": "http://example.com/onto#users",
  "@type": "Link"
}

Пока все хорошо: приложение извлекает ресурс, затем ресурс onto#users будет разыменован для обнаружения семантики.

Вопрос в том, как разработчик должен обнаружить URI свойства users из документа JSON-LD. Конечно, в моем примере это четко определено в @context, но этот URI можно было бы объявить как QName:

"@context": {
  "onto": "http://example.com/onto#",
  "users": { "@id": "onto:users", "@type": "@id" }
}

или внешний контекст может использоваться или несколько/вложенных контекстов.

Есть ли в библиотеке Javacript JSON-LD функция, которая возвращает абсолютные URI любого заданного свойства? Или есть простой способ найти его? Способ, который будет работать независимо от структуры @context? Что-то типа

var jsonLd = /* some odc */
var usersUri = jsonLd.uriOf('users');
expect(usersUri).toBe('http://example.com/onto#users');

Другими словами, я думаю, что ищу единый API для чтения @context.


person Tomasz Pluskiewicz    schedule 02.06.2014    source источник
comment
Я делаю это с помощью jsonld.expand: stackoverflow.com/questions/24265543/   -  person mb21    schedule 04.07.2014


Ответы (1)


Вот как вы можете делать то, что вы просите, с библиотекой JavaScript JSON-LD (jsonld.js):

var jsonld = require('jsonld');

var data = {
  "@context": {
    "onto": "http://example.com/onto#",
    "users": {"@id": "onto:users", "@type": "@id"}
  },
  "users": "http://example.com/users"
};

jsonld.processContext(null, [null, data['@context']], function(err, ctx) {
  if(err) {
    console.log('error', err);
    return;
  }
  var value = jsonld.getContextValue(ctx, 'users', '@id');
  console.log('users', value);
});

Однако сомнительно, является ли это хорошей идеей. Похоже, вы просто хотите использовать jsonld.expand(), который превратит все свойства в полные URL-адреса. Или вы можете использовать jsonld.compact() для преобразования любых входных данных JSON-LD с использованием контекста, который хорошо известен вашему приложению.

person dlongley    schedule 05.06.2014
comment
Докажите, что я ошибаюсь, но я думаю, что компактность не подходит, потому что она требует, чтобы клиент заранее знал о содержании ответа. - person Tomasz Pluskiewicz; 06.06.2014
comment
Ваш клиент также не может легко использовать ключи JSON (пользователи) в ответе без предварительного знания. Если у вас нет предварительных знаний, вам следует использовать полностью развернутые URL-адреса. Это означает использование jsonld.expand(). Если у вас есть какие-то дополнительные знания о том, как работает система, вы можете использовать jsonld.expand(), а затем создать свой собственный детерминированный контекст, чтобы создать упрощенный JSON для использования вашими клиентами. (Большинство API-интерфейсов на основе REST, вероятно, можно сопоставить с простыми ключами JSON, просто удалив некоторые базовые URI). - person dlongley; 06.06.2014
comment
Похоже, вы пытаетесь спроектировать систему, в которой сервер глупый, а клиент умный. Где клиент пытается выяснить значение ключей, которые отправляет сервер, чтобы он мог повторно использовать те же самые ключи, потому что сервер не сможет преобразовать URL-адрес в ключ. Я думаю, что большинство этих систем работают прямо противоположным образом: сервер может принимать ввод JSON-LD, который использует любой контекст, а затем может повторно сжимать его, используя контекст, который он понимает. Клиент может делать все, что захочет, используя любой контекст (или вообще не используя его). - person dlongley; 06.06.2014
comment
Возможно, я неправильно понимаю, как эта технология будет использоваться. Было бы полезно, если бы вы немного подробнее объяснили, как будет работать этот интеллектуальный клиент и как кто-то будет программировать приложение, использующее его. - person dlongley; 06.06.2014
comment
Сервер обязательно должен принимать любой документ JSON-LD с измененным контекстом. Пока данные эквивалентны. Мой вопрос полностью о клиенте, хотя я понимаю, что этот подход будет хрупким, потому что, когда сервер по какой-либо причине меняет свой контекст, клиент ломается. - person Tomasz Pluskiewicz; 08.06.2014
comment
Я ожидаю, что клиент должен знать только точку входа в API и следовать ссылкам. Однако в моем случае с AngularJS я борюсь с тем, что смешиваю общий клиент данных с маршрутизацией Angular. И поэтому, учитывая данные примера выше, будет пользовательский контроллер с маршрутом /#users. Учитывая, что я на самом деле не создаю общий клиент, а просто выделенный клиент для моего собственного API данных, я сомневаюсь, что есть какая-то большая прибыль от разработки полностью умного клиента. - person Tomasz Pluskiewicz; 08.06.2014
comment
Существует предположение, что использование контекста упрощает написание лаконичного, согласованного кода, который не нужно изменять только потому, что другое приложение, совместно использующее данные, использует другой контекст. Мне кажется, что вы бы хотели, чтобы клиент использовал общеизвестный контекст (или детерминированно сгенерированный), в противном случае любой код на стороне клиента должен был бы измениться, чтобы приспособиться к изменениям в контексте сервера. При написании собственного клиента разумно синхронизировать его с контекстом вашего собственного сервера, но попытка автоматизировать это выглядит как еще один уровень абстракции, который нужно отслеживать, IMO. - person dlongley; 09.06.2014