IDL для интерфейса JSON REST/RPC

Мы разрабатываем довольно сложный REST API, в котором большая часть операций ввода-вывода — это закодированные в JSON объекты с определенной структурой. Одна из проблем, которую мы обнаружили, заключается в том, чтобы документировать API таким образом, чтобы клиентам было проще публиковать правильные входные данные и обрабатывать выходные данные. Поскольку данные как ввода, так и вывода требуют довольно сложных объектов JSON, разработчики клиентов часто вносят ошибки, связанные со структурой объектов ввода-вывода.

Со всеми веб-API JSON в наши дни я надеялся на общее решение, но мне трудно его найти. Я просмотрел json-schema, которая является схемой проверки json, но и проект IETF, и реализации кажутся довольно незрелыми (хотя они уже некоторое время, что не является хорошим признаком).

Несколько иной подход предлагают буферы протоколов и Apache Avro, где схема не используется для проверки, а фактически требуется для кодирования/декодирования сообщения. Из этих двух у Avro довольно ограниченная документация и реализации. ProtoBuf кажется лучше, но я не уверен, действительно ли это подходит для использования в браузере для вызова API JSON?

Теперь я начинаю сомневаться, смотрю ли я на это под правильным углом. Существуют ли другие методы, позволяющие сделать мой API немного более строго типизированным? Или формальное описание JSON REST/RPC API противоречит цели использования JSON?

Редактировать: через 6 месяцев после этой темы мы нашли mongoose, что очень близко к тому, что мы искали.


person Jeroen    schedule 27.05.2012    source источник
comment
Если вам действительно нужно использовать существующее решение, я бы просто использовал схему json, которая кажется достаточно простой в использовании. В противном случае я не думаю, что слишком сложно проверить структуру JSON самостоятельно - проверьте, что каждый объект имеет нужные вам свойства, и сделайте это рекурсивно, если у вас тоже есть. В отличие от XML, JSON довольно просто проверить, поэтому, возможно, не существует подходящего решения для проверки схемы.   -  person laurent    schedule 30.05.2012


Ответы (4)


Ниже ответ, который я получил по электронной почте от Дугласа Крокфорда.

Я не верю в схемы как альтернативу проверке ввода. Есть свойства, которые невозможно проверить по синтаксису. Я думаю, что это был один из способов неправильной работы XML.

Если ваши форматы слишком сложны, я бы посмотрел на их упрощение.

person Jeroen    schedule 01.06.2012

Такие системы существуют и я автор одной из них. Он называется Piqi-RPC и выполняет проверку входных и выходных параметров на основе IDL для API-интерфейсы в стиле RPC через HTTP.

Он поддерживает JSON, XML и Google Protocol Buffers в качестве форматов представления данных для ввода и вывода HTTP-запросов POST. Клиенты могут выбрать любой из трех форматов и указать свой выбор, используя стандартные HTTP-заголовки Accept и Content-Type.

Так что да, теоретически вы смотрите в правильном направлении. Однако на данный момент Piqi-RPC поддерживает запись серверов только на Erlang и вам будет не очень удобно, если вы будете использовать другой стек. Я слышал, что Apache Thrift также поддерживает передачу JSON через HTTP, но я не проверял. Известный мне другой тип подобной системы (также для Erlang) называется UBF. Я слышал о библиотеках для Java, которые могут анализировать и проверять JSON на основе спецификации Protocol Buffers (например, http://code.google.com/p/protostuff/).

Сама идея далеко не нова, но не так много систем, которые приближаются к ней на практике. Это сложная проблема.

Исторически IDL использовались для определения интерфейса и сериализации двоичных данных, а не столько для проверки форматов динамического обмена данными (например, XML и JSON), которые появились позже. Sun-RPC IDL и CORBA IDL относятся к первой категории. WSDL был бы одним из немногих примеров, охватывающих обе области, но это ужасная технология, и это был бы плохой выбор для большинства современных систем. Кроме того, существует множество языков схем (также известных как DDL — языки определения данных), большинство из которых являются узкоспециализированными и работают только с одним форматом представления, например. Схемы XML или JSON. Немногие из них имеют стабильные реализации.

проект Piqi и основанный на нем Piqi-RPC построены на нескольких довольно простых реализациях:

  • DLL не нужно явно привязывать к какому-либо конкретному формату представления данных или строить вокруг него. Вместо этого такой язык может быть довольно универсальным и охватывать широкий спектр практических вариантов использования (например, сериализацию данных на разных языках и проверку данных) и форматов данных (например, JSON, XML, протокольные буферы).

  • IDL для связи в стиле RPC может быть реализован как тонкий, в основном синтаксический слой поверх универсального DDL.

  • Такие спецификации IDL и интерфейса могут не зависеть от транспорта.

Говоря об API-интерфейсах в стиле REST через HTTP по сравнению с API-интерфейсами в стиле RPC через HTTP.

С API-интерфейсами в стиле RPC разработчик службы или автоматизированная система должны проверить три вещи: имя функции (в соответствии с некоторой схемой именования службы), ввод и, если вы выберете, вывод.

В случае API-интерфейсов в стиле REST люди попадают в беду без уважительной причины. Теперь у них есть намного больше вещей для проверки: произвольно сложный синтаксис URL, включая динамические параметры, закодированные в сегментах URL (для всех методов HTTP) и строка запроса URL (только для метода HTTP GET), метод HTTP переписка (будь то GET, POST, PUT, DELETE и т.д.), тело HTTP, когда туда идут какие-то параметры (иногда делают дважды вручную для параметров, представленных в JSON и XML), настраиваемые заголовки HTTP, и отдельно -- сервис документация. Представьте себе IDL, поддерживающий все это!

person alavrik    schedule 04.06.2012

XML лучше подходит для служб RESTful во многих отношениях. В нем есть собственные ссылки (<link href=, для всех поклонников HATEOAS), поддержка родного языка (lang="en") и отличная экосистема.

Это также лучше для будущих проверок и будущих рефакторингов API. Преобразование этого:

<profile>
    <username>alganet</username>
</profile>

Чтобы поддерживать больше имен пользователей:

<profile>
    <username>alganet</username>
    <username>alexandre</username>
</profile>

Гораздо проще сделать это без нарушения работы существующих клиентов с помощью XML. JSON сложен в этом.

Если вам действительно нужен JSON, вам подойдет JSON-Schema. Это незрело, но я не знаю ничего лучше в этом случае. Возможно, ваши потребители могли бы выбирать между XML и JSON, чтобы они могли выбирать между небольшой полезной нагрузкой (JSON) или леденцами RESTful (XML), используя согласование содержимого.

person alganet    schedule 01.06.2012

Я бы сказал, что ответ на ваш последний вопрос - да. Если вам нужен способ ограничить и задокументировать «схему» JSON, почему вы изначально не использовали XML? Его не так уж сложно разобрать, и возможность применить для него схему является большим преимуществом.

person vektor    schedule 30.05.2012