воскресенье, 3 мая 2015 г.

Как обоблачиться с YandexDisk - 2.5 Протокольные компоненты, часть 2. TREST~ и TDataSet

§2.5. Протокольные компоненты

часть 2. TREST~ и TDataSet

Часть I. Теория
2.1 Подключение ЯД к Windows
2.2 Создание папки приложения
2.3 Indy и HTTPS
2.4 Скрипач как прокси
2.5 Протокольные компоненты, часть 1. TidHTTP и JSON
2.5 Протокольные компоненты, часть 2. TREST~ и TDataSet

Если подумать, то в большинстве случаев REST-протокол - это только транспорт, доставляющий нам такие же данные, что мы получали в старых настольных клиент-серверных приложениях в виде TDataSet. А поскольку TDataSet прекрасно подходит и для хранения локальных данных, то было бы неплохо и вполне естественно приводить получаемый от сервера JSON к этому формату. Особенно, если принять во внимание возможности компонента TFDLocalSQL из палитры FireDAC, который позволяет строить запросы одновременно по нескольким независимым TDataSet.


Разумеется, в компании Embarcadero, которая делает ставку именно на RAD-технологии, позаботились о том, чтобы прикладному программисту не пришлось бы писать свой код для рутинной операции преобразования REST-ответа от сервера в TDataSet. Достаточно набросать на форму полдюжины (да, это не для графоманов) компонентов, как вся цепочка преобразования не только будет готова к запуску приложения, но может начать действовать (если, конечно, ваша MS-Windows к этому готова) уже в процессе проектирования!

Давайте же, запустив предварительно Fiddler, кинем на форму (или модуль данных) компонент TRESTClient, расположенный на палитре RESTClient, и заполним его свойства и параметры:
  BaseURL = 'https://cloud-api.yandex.net/v1/disk' 
  Params = <
    item
      Kind = pkHTTPHEADER
      name = 'Authorization'
      Value = 'токен'//[OAutht ]<OAuthtoken>
    end>
  ProxyPort = 8888
  ProxyServer = '127.0.0.1' //смотрим Fiddler
 
Замечу, что в документации ЯД сказано, что OAuth-токен должен предваряться типом токена - словом "OAuth " с пробелом, но REST API прекрасно работает и без этого префикса. Однако, если вы через HTTP пытаетесь скачать файлы по полученным через REST ссылкам, то такая приставка уже становится строго обязательна.
 
Далее кладём TRESTRequest с увеличенным лимитом потребления (100 вместо 20):
  Params = <
    item
      name = 'path'
      Value = 'app:/'
    end
    item
      name = 'limit'
      Value = '100'
    end
    item
      name = 'offset'
      Value = '0'
    end>
  Resource = 'resources'
 
Ну что, можно уже делать запрос? Да, можно! Прямо в ObjectInspector у TRequest имеется команда Execute..., которая сделает запрос к ЯД без всякой компиляции и запуска программы.  Не верите? Даже после того как появилось сообщение "Response: 200 - OK"? Тогда загляните в Fiddler, и вы увидите и запрос к ЯД, и ответ:



А хотите использовать REST Debugger из меню Tools? Посмотрите на эту программу с громким названием хотя бы из интереса - она построена именно на тех компонентах, что мы сейчас используем. Если у вас не триальная версия Делфи, то вы найдете исходники в каталоге $(BDS)\source\data\rest.

Dернувшись в Делфи, присовокупим к уже имеющимся компонентам TRESTResponse для сохранения результата запроса и укажем JSON-путь до интересующего нас списка файлов, записав '_embedded.items' (эти  слова можно скопировать из дерева Фиддлера или со вкладки Response\Body программки RESTDebugger) в свойство RootElement. Добавим к этому преобразователь JSON → TDataSet  - TRESTResponseDataSetAdapter и собственно сам набор данных - TFDMemTable, который расположен на палитре FireDAC. Надо только связать эти компоненты: TRESTResponse → TRESTRequest.Response,  TRESTResponse → TRESTResponseDataSetAdapter.ResponseJSONTFDMemTable → TRESTResponseDataSetAdapter.Dataset.

Я до сих пор помню своё удивление, когда не в интерпретаторе, а в компилирующей среде разработки прямо во время дизайна вдруг ожила таблица на форме FishFаctory в первой версии Делфи. И двадцать лет спустя, когда компоненты Делфи начинают работать в то время, когда ещё нет самой программы,  я никак не могу отделаться от ощущения маленького чуда.

Итак, продолжаем волшебство. Снова запустим запрос, чтобы наши компоненты пропитались данными, а потом дважды щёлкнем на TFDMemTable или откроем Fields Editor с помощью Object Inspector. Здесь есть команда Add all fields, которая добавит в таблицу все поля из полученного JSON.



Имея таблицу с полями, мы положим на форму TBindSourceDB, привяжем к таблице, а потом разместим удобным образом TListView и запустить на нём команду Bind Visualy. Не правда ли, это волшебство - протягивая стрелки от значения к значению, видеть, как на форме список заполняется данными?

А если хочется добавить иконок, то можно добавить поле в таблицу, и грузить в него с помощью TIdHTTP данные по ссылке из поля preview. Но чтобы получить ссылку для скачивания самого файла нужен будет ещё один запрос по адресу 'cloud-api.yandex.net/v1/disk/resources/download'. Сходите на Полигон ЯД, и вы легко во всём разберётесь. Удачи!

-----------------------

Всё, больше я не буду продолжать эту статью о сервисах Яндекса, авторизации OAuth, о том, как держать бубен, чтобы коробочный Indy выполнял запросы по HTTPS. Пока я её писал Яндекс добавил новый сервис DataSync API для хранения и синхронизации структурированных пользовательских данных в облаке, а Embarcadero выпустила Delphi XE8 с новыми компонентами для HTTP-протокола, а мой младший сын научился кататься на двухколёсном велосипеде. Надеюсь, мои скромные заметки принесут пользу не только мне, приводящему этой писаниной свои мысли в порядок, но и кому-то из прочитавших сей скучный трактат.

Часть I. Теория
2.1 Подключение ЯД к Windows
2.2 Создание папки приложения
2.3 Indy и HTTPS
2.4 Скрипач как прокси
2.5 Протокольные компоненты, часть 1. TidHTTP и JSON
2.5 Протокольные компоненты, часть 2. TREST~ и TDataSet