Сходу нашлась такая технология, как WADL — Web Application Description Language. Но это XML, с ним не хотелось возиться в javascript, python и perl. Был выбран его более легковесный JSON-аналог — JSDL — JSON Service Description Language.
Требования к сервисам
Оказалось, что в JSDL (как и в WADL) не помещается вся информация, нужная для формирования полноценных формочек, и ряд дополнительных соглашений с веб-сервисами должны быть установлены:
- Для начала нужно получить список сервисов, и как они называются. Понятие сервиса (в терминах JSDL или WADL) здесь соответствует манипулируемой сущности (ресурсу в терминах REST). У сервиса есть набор операций, которые и описывает JSDL. Поэтому сервисов может быть (и обычно есть) несколько, и они могут быть объединены в группы для удобства отображения. Поэтому первым делом наш клиент запрашивает URL
GET /service_groupsи получает JSON вида[
{
"description": "Manipulate resource1",
"services": ["resource1"]
},
{
"description": "Manipulate resource2 and its statistics",
"services": ["resource2", "resource2_stat"]
}
]
- Далее нужно получить JSDL для всех этих сервисов. Можно сделать по запросу для каждого сервиса, но для удобства было так же реализовано получение всех объектов одним запросом
GET /jsdls. Получаем JSON вида[["resource1", {...object...}], ["resource2", {...object...}], ["resource2_stat", {...object...}]]
гдеobject— JSDL-описание сервиса (операции, их параметры и т.д.).
- Казалось бы, всё. Но не всё. Наш клиент — просто html-файлик, который может быть доступен с произвольного домена, либо вообще без домена, если мы натравим броузер прямо на него. Далее мы вводим в формочку корневой URL нашего RESTful API, и туда делаются запросы, являющиеся cross-domain. И мы неизбежно сталкиваемся с безопасностью. Если бы мы могли ограничиться GET-запросами, можно было бы использовать JSONP, но и это наложило бы дополнительные требования собственно на RESTful API.
Вместо этого сервер должен поддерживать OPTIONS метод, про который мало кто знает, и который практически не используется, хотя броузер неявно делает такой запрос при кросс-доменных ajax-вызовах. В RFC про этот метод написано по-моему довольно расплывчато. На практике сервер должен выдавать на этот запрос заголовок Allow:Allow: HEAD,GET,PUT,POST,DELETE,OPTIONS
Кроме того, для каждого запроса нужно слать заголовки вида:Access-Control-Allow-Origin: *Access-Control-Allow-Headers: content-type,X-Requested-WithAccess-Control-Allow-Methods: HEAD,GET,PUT,POST,DELETE,OPTIONS
Тогда броузер доволен.
Валидируем JSDL
Наш клиент валидирует пришедшие от сервера JSON-объекты в соответствии со схемой JSDL, описанной с помощью JSON Schema. Мы просто взяли JSDL-схему, метасхему JSONa, и первый валидатор из предложенных на сайте, вот этот. Метасхема нужна, так как параметр в JSDL является схемой и описывается метасхемой, которую мы немного расширили, как указано ниже. Надеюсь, понятно (мне лично не всегда).
Расширяем JSDL
К сожалению, средствами стандартного JSDL всё равно не получается полностью выразить наши формочки.
Схеме параметра не хватало следующих выразительных средств:
- Параметру нужно имя. Его нужно задать.
- Параметр передаётся серверу разными способами:
- В URL, после ресурса:
http://ift.tt/1mJZ4as - В строке запроса (если GET) или в теле запроса:
http://ift.tt/1riVrA5 - В теле запроса, единым куском, не образуя key-value пары. Специфичный случай, но встречается
- В URL, после ресурса:
- Для каких параметров типа string нужно рисовать textarea, а каким достаточно text input?
Для решения этих проблем схему JSDL-описания параметра (ту самую метасхему) пришлось расширить следующим образом:
//добавим атрибут name
ParamJSONSchema["properties"]["name"] = {
"type": "string"
}
//добавим атрибут passing - как передавать значение
ParamJSONSchema["properties"]["passing"] = {
"type": "string",
"default": "keyvalue",
"enum": ["keyvalue", "positional", "raw"]
}
//добавим в типы параметра multistring для случая textarea
ParamJSONSchema["definitions"]["simpleTypes"]["enum"].push("multistring");
Теперь есть все данные, чтобы нарисовать формочку для запроса и правильно отправить её содержимое сервису. Результат выводим на страничку.
Сам проект лежит на гитхабе и может быть использован для реализации единого веб-интерфейса к сервисам в вашей компании, например.
This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.
Комментариев нет:
Отправить комментарий