Создание клиентской библиотеки HATEOAS

Предположим, у меня есть RESTful API для управления заказами, который использует HAL для облегчения HATEOAS:

GET /orders/2
  {
    "_links": {
      "self": "/orders/2",
      "items": "/orders/2/items"
    },
    "subtotal": 30.0,
    "shipped": false
  }

Я хочу написать свой клиент (приложение), используя набор интерфейсов, так что, предполагая, что реализации этих интерфейсов являются DI-d/построены фабриками DI-d и т. д., мне действительно (хочу) не нужно заботиться что они поддерживаются моим RESTful API. В качестве примера (псевдо С#/Java):

public interface Order {
  public void addItem(Item item);
  public float getSubtotal();
  public boolean getShipped();
}

Order order = ...;
Item item = ...;
order.addItem(item);
...(order.getSubtotal())...;

У меня вопрос: есть ли смысл создавать реализации интерфейса Order/Item из API? Под этим я подразумеваю способ, аналогичный тому, что предлагается в C#/веб-сервисах, которые экспортируют WSDL.

Я думал о реализации OPTIONS для таких ресурсов, как /orders и /orders/{id}, чтобы у меня был API HATEOAS для обхода схемы API:

GET /orders/* (I'd need a suitable wildcard of course)
  {
    "_links": {
      "addItem": {
        "href": "/orders/{id}/items",
        "templated": true,
        "type": "method"
      }
    }
  }

Конечно, я мог бы сделать так, чтобы эта часть объекта _links возвращалась с любым заданным ресурсом (например, /orders/2), но это исключает генерацию статического кода.

Мне интересно, есть ли разумный способ инкапсулировать тот факт, что если указана конкретная ссылка, соответствующее действие должно быть доступно/выполнено, иначе нет.

Примечание. Если это имеет значение, на самом деле я работаю с JavaScript (в частности, с AngularJS). Однако я все же хотел бы написать свое приложение, используя набор концептуальных интерфейсов/контрактов.


person lunaris    schedule 15.08.2013    source источник
comment
Поскольку вы используете JavaScript, знаете ли вы / рассматривали ли вы основу для чего-то вроде hyperagent.js? weluse.github.io/hyperagent   -  person Jonathan W    schedule 04.10.2013
comment
Спасибо, я проверю. Не могли бы вы прислать мне учебник о том, почему HAL хорош в использовании?   -  person inf3rno    schedule 06.10.2013


Ответы (1)


Мой вопрос: могу ли я/имеет ли смысл генерировать реализации интерфейса Order/Item из API? Под этим я подразумеваю способ, аналогичный тому, что предлагается в C#/веб-сервисах, которые экспортируют WSDL.

Частично это имеет смысл. С помощью простого CRUD API вы можете сопоставить ресурсы с объектами. В сложных приложениях это не работает, потому что вы сопоставляете пары URIs с resources и METHOD URI с operations. Поэтому каждый раз, когда вам нужна операция, не определенная HTTP, вы должны создавать новый ресурс или, по крайней мере, новый URI для уже существующего ресурса.

Некоторые примеры:

  • перевести деньги с одного счета на другой: POST /transfer [acc1, acc2, amount, currency] - перевод не обязательно существует как объект в логике вашего домена (не пытайтесь использовать такое решение в рабочем коде, если вы не хотите банкротства: D)
  • отправка электронного письма другому пользователю: POST /messages [recipient, message]
  • вы также можете сопоставлять ресурсы с объектами-значениями: GET /users/123/address
  • вы можете использовать URI для отображения коллекции: GET /users?name="John"
  • вы можете использовать PUT /users/123 [details] вместо POST /users [details] для создания нового пользователя
  • вы можете использовать POST /player/123/xp/increment 10 вместо PUT /player/123/xp [xp+10] для обновления очков опыта игрока

О решениях, подобных WSDL, вы можете прочитать намного больше здесь: -linked-data.pdf" rel="nofollow">Веб-API третьего поколения — Маркус Ланталер.

Мое личное мнение, что строить такую ​​систему не стоит, потому что у нее больше недостатков, чем достоинств.

person inf3rno    schedule 06.10.2013