Проектуємо Enetri API

За запитом шановного Slik’а (автора новорічного Enetri Toolbar’у, якщо хто не в курсі:), виносимо тему розробки Enetri API на публічне обговорення технічно підкованою частиною спільноти Енетрі.

В самому елементарному випадку, наприклад, мова може йти про роздачу через API-інтерфейс поточної інформації про чинний рейтинг користувача, кількість нових коментарів в абонентській скриньці, et cetera.

Так, технічно реалізувати подібне API справа достатньо елементарна. Наприклад, у форматі JSON це може виглядати приблизно-наступним чином:
{
   "rating": 25.0,
   "inbox": 7
}
На перший погляд, все просто і навіть занадто просто. Достатньо було б організувати вивід подібного файлу з відповідними заголовками за першою-ліпшою адресою з beta.enetri.com. Проте, це все не зовсім так — швидше, з точністю дещо до навпаки.

Тому ми запрошуємо IT-професіоналів (а ще більше тих, хто прагне ним стати) до грамотного проектування майбутнього Enetri API. Адже разом ми достойно справимося з цим посильним завданням, правда?

Питання для обговорення:
  • формат
  • URL
  • версійність
  • обробка помилок
  • кешування
  • ліміти
  • тощо

доповнення:

Другий тестовий драфт EnetriAPI, v0.02

GET, JSON, UTF-8

http://api.enetri.com/draft/test.json?language=uk
http://api.enetri.com/draft/test.json?language=ru
http://api.enetri.com/draft/test.json?user=id
http://api.enetri.com/draft/test.json?user=id&timestamp=timestamp

http://api.enetri.com/draft/test.json?timestamp=test       » 701
http://api.enetri.com/draft/test.json?user=1000000         » 720

Коди помилок:

API   HTTP   Messages
-----------------------------------
405   405    Method not allowed
500   500    Internal server error
700   500    Enetri API error
701   500    Invalid argument value
710   500    Timestamp is too far in the future
720   404    No such user

Кількість нових публікацій та коментарів — за останні 24 години (якщо в запиті не вказаний явний UTC timestamp) та не більше 10. Поле inbox може приймати невизначене значення none у випадку, якщо точна цифра невідома (немає актуальних даних в мемкеші). Параметр language має значення за змовчуванням uk, проте його рекомендується вказувати у запиті явно.

Зразки даних:

HTTP 200

{
   "user": {
      "id": 1,
      "inbox": 7,
      "rating": null
   },
   "new": {
      "articles": 1,
      "comments": 3,
      "language": "uk"
   },
   "version": "draft",
   "draft": 0.2,
   "timestamp": 1234567890
}

HTTP 500, API 701

{
   "error": 701,
   "message": "Invalid argument value"
}
P.S. Поточна версія API є тестовою робочою чернеткою, тому просимо вас попередньо узгоджувати його не тестове використання.

коментарі:

slik 15.01.2010 14:30
На рахунок XML/JSON я руками і ногами за JSON. Хоча якщо API передбачає вибір - це навіть краще.
Може на рахунок цього + на рахунок URL подивитись на твіттер ? Там, по моєму, все логічно:
/api/comments.xml?param=value
/api/comments.json?param=value
або
beta.enetri.com/api/json?param=value
beta.enetri.com/api/xml?param=value
Обробка помилок, тут напевне треба подивитись в сторону ExtJS:
{
    success: true,
    data: {}
}

{
    success: false,
    code: 1,
    message: "Error"
}
Щось типу того.

Ліміти ? Тут складніше. З одної сторони хватить і раз в 15 хвилин. Але з іншої - якщо наприклад автор написав повідомлення/статтю перших кілька хвилин/годин він чекає на фідбеки, тому для нього важливо почастіше оновляти інформацію. Це і до кешу відноситься.

На рахунок версійності.. Тут одразу ж на думку спадає Google з своїм Maps Api, але в потрібності версій я не впевнений.

P.S. Чому акк Енетрі на твіттері мертвий ? :)
slik 15.01.2010 14:40
Мм. Тулбар шото глючить. Попередній перегляд після додавання коментаря не пропадає. День глюків %)
slik 15.01.2010 14:41
А, ше кількість коментарів не міняється після додавання %)
Enetri 15.01.2010 15:05
Факт, причому перший і другий. Даруйте, ці обидві комахи поки що лише в TODO.
Enetri 15.01.2010 17:32
Виловили і повідривали їм ніжки. Під наркозом... Повністю прибивати комах пошкодували — щоб не виглядало на відвертий садизм, перед Грінпісом. Даруйте за п’ятницевий чорний гумор .)

P.S. Дякуємо за підказку!
Enetri 15.01.2010 15:07
Давайте справді зосередимося спочатку на JSON, як компактному і красивому форматі. Після того, як сам API буде спроектовано і реалізовано — прикручування XML (при потребі) буде вже справою чисто рутинною і необтяжливою.
Enetri 17.01.2010 10:55
Відкрито перший драфт Enetri API, v0.001

P.S. Сподіваємося, що в результаті цього обговорення у нас вийде одразу дві хороші речі: по-перше, це власне сам Enetri API, а по-друге — Практичний посібник по проектуванню та використанню API, викладений у вільній формі коментарів на Енетрі :)
slik 18.01.2010 10:15
Я правильно зрозумів, в полі timestamp повертається саме timestamp той з часу якого обраховувалися дані про нове ? Чи моменту в який дані обраховувалися ?

Судячи з відповіді, останнє:
http://www.enetri.com/api/draft/test.json?user_id=1222&timestamp=1263709411

{ "timestamp": 1263809439, "version": "draft", "draft": "0.001", "user": { "rating": 51.0, "id": 1222, "inbox": 1 }, "new": { "articles": 1, "comments": 7 } }
Попробувавши ше кілька тамймштампів переконався що система на них не реагує, а жаль :)
Enetri 18.01.2010 11:15
Чому ж не реагує? Реагує, звичайно. Спробуйте-но ще раз:

http://www.enetri.com/api/draft/test.json
http://www.enetri.com/api/draft/test.json?timestamp=отриманий_від_сервера_таймстемп

timestamp = час відповіді сервера = актуальним даним на цей момент часу
+1slik 18.01.2010 11:34
Ага, ось так.. Зрозумів.. Оке, під вечір начеркаю draft версію плагіна для роботи з цим API :)
Enetri 18.01.2010 11:51
Давайте разом наскладаємо для нього також draft-версію ТЗ :) Тобто сформулюємо логіку його роботи.

А під це діло вже і модифікуватиметься чернетка нашого API. До речі, для сумісності з можливим варіантом XML-API в драфті 0.002 пропонується замість видачі даних типу null не віддавати ці поля взагалі. Тобто зробити їх необов’язковими, як це є зараз. Правда, для клієнта тоді знадобиться функція перевірки отриманих даних. Хоча будь-які зовнішні дані і так краще завжди перевіряти :)
slik 18.01.2010 13:11
Знаєте, все таки дуже не вистачає можливості вказувати любий відрізок часу.. Чому ? Я можу записувати час останнього візиту сайту з плагіну, і хотіло б ся щоб API повертало дані саме на цей час, себто від останніх відвідин до цього моменту.
http://www.enetri.com/api/draft/test.json?timestamp=час_останніх_відвідин&user_id=1222
Тоді можна буде показувати актуальні дані.
Enetri 18.01.2010 15:21
Якщо ми говоримо про частину new, то зараз власне так і відбувається:

Варіант 1. Час не заданий в запиті (timestamp відсутній)
- береться інтервал по змовчуванню (за останні 24 години)
- сервер повертає точний інтервал (параметр timestamp)

Варіант 2. Час заданий клієнтом в запиті явно (і timestamp менший за 24 години)
- інтервал ВІД вказаного timestamp ДО поточного часу на сервері

Чи ви маєте на увазі явну вибірку обох меж часового інтервалу, ВІД старішої дати і ДО новішої дати? Тобто можливість задавання параметру "ДО", коли обидві межі знаходяться в минулому часі? Якщо так, то навіщо? Переформулюйте питання, будь ласка :)
slik 18.01.2010 15:38
Моя помилка, недодивився :) сорі
Enetri 18.01.2010 16:05
Завжди раді допомогти :)

А ТЗ нас сильно виручить, хоча б мінімальне і схематичне. Наскладаєте? Можна було б навіть у вигляді окремого топіка — най спільнота теж долучиться до проектування власного віджета. А ми підтримаємо цієї корисної справи посильним внеском у вигляді методів API.
slik 18.01.2010 16:28
Що я хочу реалізувати:
1. Налаштування (вказування свого енетрі-id)
2. Показування кількості нових статтей/коментарів/відповідей_на_коментар (читайте інбокс) так як це зроблено тут
3. Логіка кліку по іконці: якщо кількість в інбоксі більше нуля - відкриваємо інбокс, інакше якщо нових статтей більше нуля - переходимо на нове, інакше якщо коментарів більше нуля - переходимо в коментарі, інакше відкриваємо головну.
Enetri 18.01.2010 17:27
Пропозиції, з інтелектуальними інтервалами:

Стандартне опитування API до моменту, поки найпріоритетніший пункт в ієрархії check-списку не приймає значення True ("старший лічильник" більший від нуля). Далі вже включається політес, наприклад — інтервал збільшується до години. Або й в прогресії — година, дві, чотири і т.д.

"Чемна поведінка" може включатися вже й з того моменту, коли хоча б один з параметрів стає позитивним. Скажімо, з 5 хв до 15, чи щось таке :)

P.S. Можливість вибору користувачем пріоритетності: інбокс, статті, коментарі? Хоча, можливо, й не факт, що це буде дійсно потрібно юзерам.
Enetri 18.01.2010 11:18
Загалом, клієнт повинен орієнтуватися на таймстемп сервера, а не на свій власний. З двох банальних причин:

1. між запитом клієнта і та отримання відповіді сервера може пройти більше однієї секунди
2. час, встановлений в клієнта і сервера може значно відрізнятися

В останньому випадку мова може йти про різницю в хвилини/години і навіть роки (але в рідкісних випадках, якщо в клієнта просто неправильно встановлений час).
Enetri 15.01.2010 15:12
Версійність
На рахунок версійності.. Тут одразу ж на думку спадає Google з своїм Maps Api, але в потрібності версій я не впевнений.
Немає нічого постійнішого, ніж процес змін :) Тому краще закладати/передбачати можливість розвитку ще з самого початку. Енетрі ростуть (хоча й достатньо поступово) — наше API, відповідно, теж розвиватиметься. А що робити з часом із застарілими ("мертвими") API?

Скажімо, для версії нотифікатора у вигляді розширення для браузера? В нашому конкретному випадку, може з’явитися додаткове поле з кількістю непрочитаних приватних повідомлень, наприклад. Чи ще якась корисна модифікація. Або й "не дуже корисна" — переїзд на інакший URL...

Добре було б, якби клієнт та сервер мали можливість хоча б мінімально порозумітися один з одним в таких випадках.
slik 15.01.2010 15:27
Оке. Пропоную 2 постійні поля які будуть приходити від сервера:
success
date (time?)
Для чого останнє ? Кешування. Так, клієнту потрібно знати за який час дані він приймає, просто записувати час запиту або час відповіді не годиться.

І відповідно до значення поля success буде інший формат відповіді (периклад вище, просто без поля).

Серверу ж клієнт постійно повинен передавати версію API з якою він хотів би працювати. Повертати цю версію з відповіддю напевне недоцільно.
slik 15.01.2010 15:31
(приклад вище, просто без поля date/time) *
slik 15.01.2010 16:00
Подумав про таке:
якщо клієнт робить запит "а чи були нові повідомлення/статті" то, по моєму, повинно бути 2 варіанта, якщо клієнт передає дату/час, то сервер повинен оріентуватись по ньому, якщо не передає, то по останніх відвідинах сайту (такі дані записуються ?)

Тобто:
> чи були нові повідомлення від 1.1.2010 ?
< так
< 1.1.2010
< 10

> чи були нові повідомлення ?
< так
< 15.1.2010 (сьогодні)
< 1
Enetri 18.01.2010 11:42
У нас є два типи даних (A) персональні (B) загальні

(A) user.inbox → це персоніфікована інформація (лічильник, який нулиться лише при авторизованому заході користувачем на сторінку /my/inbox/)

(B) new.articles, new.comments → це той другий тип інформації (загальної для всіх), на нього і впливає параметр timestamp.
то по останніх відвідинах сайту (такі дані записуються ?)
Користувач може бути просто не зареєстрований (чи не авторизований) на сервері. Тому API в частині new віддає дані типу «B» (себто не-персоналізовані).
Enetri 15.01.2010 17:40
Без докладнішого розбору польотів, як цей велосипед спроектовано у Слонів типу Google, Yahoo, Twitter, Yandex, et cetera ми навряд-чи обійдемся. Звичайно, він у нас їздитиме, в будь-якому випадку, навіть на квадратних колесах — але останнього хотілось би, по-можливості, уникнути :)

Перевірені реальною (і значною) практикою рішення можуть бути самими оптимальними, в нашому випадку також.
slik 15.01.2010 18:08
Ну от тому я і беру за приклад реалізацію різних API :) мені пощастило працювати з багатьма
slik 15.01.2010 18:13
Точніче, реалізацїї API різних сервісів %)
luckyredhot 15.01.2010 21:26
Чи не цей велосипед згадали?))
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/jchrQqH6bT0&hl=ru_RU&fs=1&"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/jchrQqH6bT0&hl=ru_RU&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>
Enetri 19.01.2010 14:10
Увага! API переїхало на окремий субдомен: http://api.enetri.com
slik 19.01.2010 18:07
Потяну я трохи з реалізацією.. Часу нема :(

додати коментар: