Як ми зробили з JSON мова програмування

Через місяці напруженої роботи ми нарешті випустили додаток для iOS Relevant. З ним ми ламаємо існуючі засади взаємодії з сервісами і контентом в мережі, завдяки чому користувач витрачає значно менше часу на звичні речі. Досягається це шляхом подання додатків і веб-сервісів у вигляді карток (детальніше тут).

Картки, як незалежні інтерактивні одиниці, що показують, яким буде майбутнє мобільних інтерфейсів.
image
Коли ми тільки почали працювати над Relevant, нам були зрозумілі лише дві речі: картки повинні бути красивими, і вони повинні бути універсальними. Тобто їх зміст може формуватися з будь-якого джерела інформації в мережі з мінімальними обмеженнями. Що до красивості, так вона заслуговує окремої статті, і тут ми торкатися не будемо, а поговоримо саме про універсальності.

Картки як об'єкти JSON
Так як картки Relevant повинні бути легкими і скачиваемыми, ми вирішили представляти їх у вигляді JSON-файлів, що містять інструкції про те, як отримати доступ до різних джерел інформації і API в мережі і як перетворити отримані дані вмісту карток.
image
Потрібна була надзвичайно гнучка структура карток, яка б не ускладнювала процес їх створення. Повинна бути можливість, наприклад, отримання від API масиву з товарами, а потім і отримання детальної інформації про кожного з них. Причому отримання даних може відбуватися за допомогою різних API з подальшим збором всього цього воєдино.

Таким чином, стало ясно, що потрібно створити універсальний API-агрегатор: гнучкий, легко змінюваний і зберігається у файлах. Це дозволить створити екосистему, де картки зможуть розвиватися, на відміну від додатків, вміст яких недоступні для користувача, так як розробники просто захардкодили його.

API нестандартні
Веб-сервіси і API представлені у вигляді різних форм. Деякі API, коли потрібно повернути список, повертають просто масив, в той час як інші засовують його кудись у надра повернутого об'єкта. Одні використовують розбиття на сторінки, інші приймають явний варіант сторінки. [Не зовсім ясно, в чому полягає подразумевающаяся різниця] Додайте до цього сотні стандартів формату дати і часу, пару стандартів URL і випадкове обернення цілих і дробових чисел у лапки. Більшість розробників, які намагаються створити систему агрегації численних API, швидко занурюються в багаторівневий пекло з блоків if-else.

Нам хотілося чогось більш потужного. Потрібно було зробити нашу платформу незалежної від якості дизайну API і його даних. Після довгих проб і помилок Relevant Card's JSON став виглядати приблизно так:
image

Велика частина нашої інфраструктури агрегації API лежить на складних серверних і клієнтських системах. Тим не менш, придуманий нами JSON-орієнтована мова REL заслуговує окремої згадки.

Швидке введення в REL
REL виглядає як приукрашенный JSON, але по суті це чисто функціональний мову програмування з ледачими незмінними змінними (тобто вони обчислюються і виходять тільки тоді, коли необхідні) і динамічною областю видимості.

Типи і змінні
Типи REL — це стандартні типи JSON: числа, рядки, об'єкти та масиви. У більшості випадків вони парсятся безпосередньо. Однак деякі об'єкти мають особливе значення. Пари ключ-значення об'єкта, що має ключ "_RETURN", парсятся як пари змінна-значення. Звернення до змінних здійснюється за допомогою фігурних дужок: "{variable_name}".

Наприклад, наступний об'єкт
{
"foo":1,
"var":2,
"_RETURN":{"_MATH":"{foo}+{var}"}
}
REL представляє як число 3.


Ми часто добавляємо нові вбудовані функції в REL. Ці функції виглядають як об'єкти з певними спеціальними ключами, які починаються з символу підкреслення. Функція "_MATH" з прикладу вище розбирає рядок як математичний вираз і повертає його результат.

Серед інших вбудованих функцій можна виділити "_URL", яка завантажує JSON за заданою адресою, і "_PATH", яка шукає значення в об'єкті JSON або масиві. Ці дві функції є основними, що використовуються для агрегації API в REL Engine.

Можна навіть створювати користувальницькі функції. Більше інформації про це в документації.

Керування порядком виконання
Вбудовані функції, такі як {"_IF":, "_THEN":, "_ELSE":} і {"_LOOP": {"_ARRAY":, "_EACH":}} використовуються для керування порядком виконання, але, на відміну від функціональних мов (таких як C або Java), вони завжди повертають значення.

Більше інформації про поточної версії REL завжди можна знайти на документації.

Також доступна розвивається бібліотека карток з прикладами і описами на REL.

Від перекладача
Переклад місцями досить вільний, але не на шкоду змісту або вмісту. Все, що не відноситься безпосередньо до оригіналу, винесене в примітки. Автор публікації є за сумісництвом і автором програми, так що вихідний текст є кілька рекламним. Я постарався перенести акцент саме на розроблений мову. За великою кількістю посилань і різноманітних закликів звертайтеся до оригіналу.
З пропозиціями, побажаннями та зауваженнями, як зазвичай, в ЛС.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.