Окремий сервер і клієнт REST JSON API? [зачинено]


371

Я збираюся створити купу веб-додатків з нуля. (Див. Http://50pop.com/code для огляду.) Я хотів би, щоб вони мали доступ до багатьох різних клієнтів: передових веб-сайтів, смартфонів, додаткових веб-сервісів тощо. Тому я дуже хочу API JSON REST для кожного.

Крім того, я віддаю перевагу роботі над бек-ендом, тому мрію про те, щоб я зосереджувався лише на API та наймав когось іншого, щоб зробити інтерфейс інтерфейсу, будь-який веб-сайт, iPhone, Android чи інший додаток.

Будь ласка, допоможіть мені вирішити, який підхід я повинен використовувати:

РАЗОМ У РЕЙЛАХ

Зробіть дуже стандартний веб-додаток Rails. У контролері виконайте перемикач response_with, щоб обслуговувати або JSON, або HTML. Відповідь JSON - це мій API.

Про: Багато прецедентів. Великі стандарти та багато прикладів того, як робити так.

Con: Не обов’язково бажати, щоб API був таким самим, як веб-додаток. Не подобається, якщо / тоді відповідь_з підходом перемикання. Змішування двох дуже різних речей (UI + API).

ВІДПОВІДНИЙ СЕРВЕР + JAVASCRIPT-ВИСОКИЙ КЛІЕНТ

Зробіть сервер API REST API лише для JSON. Використовуйте Backbone або Ember.js для клієнтського JavaScript для доступу до API безпосередньо, відображаючи шаблони в браузері.

Pro: Я люблю розділення API та клієнта. Розумні люди кажуть, що це шлях. Чудово в теорії. Здається, найсучаснішим і захоплюючим

Кон: Не дуже великий прецедент. Не багато прикладів цього зроблено добре. Публічні приклади (twitter.com) відчувають себе мляво і навіть переходять від такого підходу.

ПОСЛУГИЙ СЕРВЕР + КЛІЕНТ HTML-КЛІЄНТА СЕРВЕРА

Зробіть сервер API REST API лише для JSON. Створіть базовий клієнт веб-сайту HTML, який має доступ лише до API REST. Менше клієнтського JavaScript.

Pro: Я люблю розділення API та клієнта. Але обслуговування звичайного HTML5 досить безглузде і не вимагає клієнтів.

Кон: Не дуже великий прецедент. Не багато прикладів цього зроблено добре. Рамки також не підтримують це. Не знаєте, як до цього підійти.

Особливо шукаючи поради з досвіду, а не лише теоретично.


50
як правило, ми вважаємо за краще, щоб спекулятивні, концептуальні запитання на дошці надходили на programmers.stackexchange.com, тоді як запитання тут щодо переповнення стека повинні містити фактичний вихідний код у 99% часу. Але, це добре задане питання, і я люблю вашу роботу, тож це зараз може потрапити в сіру зону.
Джефф Етвуд

2
Хтось має приклади / джерела (щоб зрозуміти їх причини) для тих, хто відходить від варіанту 2?
Víctor Лопес Гарсія

12
@frntk Первісна причина, що багато компаній (наприклад, Twitter) робили клієнти Javascript, тому що вони думали, що це буде швидше. Тепер вони розуміють, що це насправді повільніше. Дивіться Engineering.twitter.com/2012/05/… та openmymind.net/2012/5/30/Client-Side-vs-Server-Side-Rendering
Moshe Katz

1
Прочитайте коментарі за посиланнями вище. Багато припущень статті спростовано логікою та досвідом.
Ricalsin

1
У ці дні ви хочете зробити JSON API API після jsonapi.org специфікації ... :)
Askar

Відповіді:


136

На Boundless ми заглибилися з варіантом №2 і розгорнули його тисячам студентів. Наш сервер - це JSON REST API (Scala + MongoDB), і весь наш клієнтський код подається прямо з CloudFront (тобто: www.boundless.com - це лише псевдонім для CloudFront).

Плюси:

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

Мінуси:

  • Не є SEO-дружнім / готовим без значно більшої роботи.
  • Потрібні найпопулярніші веб-передовики, готові впоратися з реальністю досвіду сайту, який становить 70% JavaScript і що це означає.

Я думаю, що це майбутнє всіх веб-додатків.

Деякі думки для людей, що знаходяться в передній частині веб-сторінки (саме там, де ця нова архітектура / виклик задається цій архітектурі):

  • CoffeeScript. Набагато простіше виготовити високоякісний код.
  • Хребта. Чудовий спосіб організувати свою логіку та активну спільноту.
  • HAMLC. Шаблони Haml + CoffeeScript => JS.
  • SASS

Ми створили джгут для нашої розробки під назвою "Spar" (Single Page App Rockethip), яка фактично є конвеєром активів з Rails, налаштованим на розробку додатків для однієї сторінки. Протягом наступних кількох тижнів ми відкриємо пошук на нашій сторінці github , а також допис у блозі, де пояснюється, як її використовувати та загальну архітектуру.

ОНОВЛЕННЯ:

Що стосується занепокоєння людей щодо Хребта, я думаю, що вони завищені. Основа є набагато більш організаційним принципом, ніж глибокою основою. Сам сайт Twitter - це гігантський звір Javascript, який охоплює кожен кутовий випадок мільйонів користувачів та застарілих браузерів, а завантажуєте твіти в режимі реального часу, збираєте сміття, показуєте багато мультимедіа тощо. З усіх "чистих" сайтів, які я маю бачите, Twitter - це незвичайне. Було багато вражаючих складних програм, що доставляються через JS, які дуже добре коштують.

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


1
Невеликий момент, який слід додати: Хоча я створив лише варіант №1, я знаю декількох розробників мобільних додатків, які починають використовувати parse.com у якості резервного , щоб увімкнути швидкий шлях до №2.
Rhb123

Такі речі, як Парс і Кінві, дуже цікаві, не можу сказати, що я ще мав шанс грати з ними. Залежить, чи є ваша вартість в передній чи задній частині стека, я думаю
Аарон

Я використовую той самий підхід із spinejs для фронтену.
Ніколя Гой

Як обробляти один домен із двома окремими програмами? Напр. У мене є www.mysite.com, і я хочу розкрити загальнодоступний інтерфейс API та подати на нього URL-адресу. Вірно принципам REST, доступ до веб-браузера mysite.com/product/24 повинен повернути HTML-сторінку, переглянувши заголовок HTTP Accept, а GET з JSON у заголовку Accept на mysite.com/product/24 повинен повернути JSON .
Еріх

Як AngularJS зможе вирішити це?
Ankan-Zerob

48

Дуже добре запитав. +1. Напевно, це майбутня корисна довідка для мене. Також @Aaron та інші додали цінності дискусіям. Як і Ruby, це питання однаково стосується інших програмних середовищ.

Я використав перші два варіанти. Перший для численних застосувань і другий для мого проекту з відкритим кодом Cowoop

Варіант 1

Цей, без сумніву, найпопулярніший. Але я вважаю, що це дуже багато http-ish. Кожен початковий код API стосується об'єкта запиту. Отже код API - це більше, ніж чистий код рубіну / пітона / іншого мови.

Варіант 2

Я завжди це любив.

Цей параметр також передбачає, що HTML не виконується на сервері. Ось як варіант 2 відрізняється від варіанту 3. Але будують як статичний html, використовуючи сценарій збірки. Завантажуючись на стороні клієнта, цей HTML буде викликати сервер API як клієнт API JS.

  • Розлучення проблем - це велика перевага. І дуже на ваш смак (і мій) бекенд-експерти впроваджують API бекенду, тестуйте їх легко, як звичайний код мови, не турбуючись про frame / http-код запиту.

  • Це дійсно не так складно, як це звучить на фронтальній стороні. Чи доступні дзвінки API та отримані дані (в основному json) доступні шаблону на стороні клієнта або MVC.

  • Менша обробка на стороні сервера. Це означає, що ви можете піти на товарне обладнання / менш дорогий сервер.

  • Простіше тестувати шари незалежно, простіше створювати документи API.

У нього є деякі недоліки.

  • Багато розробників вважають це надмірно розробленим і важко зрозумілим. Тож існує ймовірність, що архітектура може бути піддана критиці.

  • i18n / l10n важко. Оскільки HTML по суті генерується, час збірки є статичним, потрібно декілька збірок на підтримуваній мові (що не обов'язково погано). Але навіть при цьому у вас можуть бути кутові корпуси навколо l10n / i18n і вам потрібно бути обережними.

Варіант 3

Кодування бекенду в цьому випадку має бути таким же, як і другий варіант. Тут також застосовано більшість балів за варіант 2.

Веб-сторінки надаються під час виконання з використанням шаблонів на стороні сервера. Це значно спрощує i18n / l10n за допомогою більш усталених / прийнятих методик. Може бути один менш http-дзвінок для якогось істотного контексту, необхідного для візуалізації сторінки, наприклад користувача, мови, валюти тощо. Отже, обробка на стороні сервера збільшується за допомогою рендерінгу, але, можливо, компенсується меншою кількістю дзвінків http на сервер API.

Тепер, коли сторінки серверні, що відображаються на сервері, фронтенд тепер більше пов'язаний із середовищем програмування. Для багатьох застосунків це може не враховуватись.

Випадок у Twitter

Як я розумію, Twitter може зробити своє початкове відображення сторінок на сервері, але для оновлення сторінок все ще є деякі дзвінки API та шаблони клієнтської сторони для маніпулювання DOM. Тож у такому випадку у вас є подвійні шаблони, які потрібно підтримувати, що додає певних витрат та складності. Не кожен може дозволити собі цей варіант, на відміну від Twitter.

Наш проект Стек

Я випадково використовую Python. Я використовую JsonRPC 2.0 замість REST. Я пропоную REST, хоча мені подобається ідея JsonRPC з різних причин. Я використовую бібліотеки нижче. Хтось, хто розглядає варіант 2/3, може вважати його корисним.

  • API-сервер: Python Швидкий веб-мікро-фреймворк - колба
  • Frontend сервер: Nginx
  • Сторона клієнта MVC: Knockout.js
  • Інші відповідні інструменти:

Мій висновок та рекомендація

Варіант 3 !.

Все сказане, я успішно використовував варіант 2, але тепер для деякої простоти схиляюся до варіанту 3. Створення статичних HTML-сторінок за допомогою сценарію складання та обслуговування їх на одному із надшвидких серверів, що спеціалізуються на обслуговуванні статичних сторінок, дуже привабливо (Варіант 2).


Мені також подобається варіант 2, але варіант 3 має багато переваг, від яких ми не можемо позбутися. Я намагаюся знайти гідридне рішення, що поєднує в собі opt2 + opt3, але це призведе до головного болю, як Twitter.
Blue Smith

Я люблю варіант 3, і націлений на використання, якщо для поточного проекту. Будь-яке, наприклад, чи git repo, на яке можна звернутися за допомогою?
AmaChefe

@AmaChefe Я бажаю. Для поточного проекту, де SEO має вирішальне значення, ми використовуємо варіант 3. Але код не є відкритим кодом. Ми використовуємо flask + jinja2 та knockout / react.js.
Шехар

28

Ми обрали номер 2 при будівництві gaug.es. Я працював над API (рубін, синатра та ін.), А мій бізнес-партнер Стів Сміт працював над переднім (клієнтом javascript).

Плюси:

  1. Рухайтеся швидко паралельно. Якби я працював попереду Стіва, я міг би продовжувати створювати API для нових функцій. Якби він працював попереду мене, він міг легко підробити API і створити інтерфейс користувача.

  2. API безкоштовно. Відкритий доступ до даних у вашому додатку швидко стає стандартною функцією. Якщо ви починаєте з API з нуля, ви отримуєте це безкоштовно.

  3. Чисте відділення. Краще думати про свою програму як про API з клієнтами. Звичайно, перший і найважливіший клієнт може бути веб-клієнтом, але він налаштовує вас на легке створення інших клієнтів (iPhone, Android).

Мінуси:

  1. Зворотна сумісність. Це більше пов'язано з API, ніж з вашим прямим запитанням, але як тільки ваш API є там, ви не можете просто розірвати його або розірвати всіх своїх клієнтів на двох. Це не означає, що вам потрібно рухатися повільніше, але це означає, що вам потрібно часто робити дві речі одночасно. Додавання до API чи нових полів є нормальним, але зміна / видалення не повинно бути виконано без версії версії.

Я не можу придумати більше мінусів зараз.

Висновок: API + JS-клієнт - це шлях, якщо ви плануєте випустити API.

PS Я також рекомендую повністю задокументувати ваш API, перш ніж випускати його. Процес документування API Gaug.es насправді допоміг нам

http://get.gaug.es/documentation/api/


13
Чи можу я запитати, як ви автентифікуєте веб-інтерфейс за допомогою REST API? Я побачив, що вам потрібен ключ API для спілкування з API, який отримується при вході в профіль користувача. Але як веб-клієнт отримує свій ключ API, якщо ви знаєте, що я маю на увазі?
Себастьян Врамба

@SebastianWramba Це пізно, але оскільки ваш коментар отримав 12 відгуків ... я б розглядав щось на зразок авторизації пароля OAuth2 . Якщо ви творець програми, яка викликає API, ви, мабуть, саме цього підходу, оскільки він не використовує безпосередньо ключ API. Якщо це програма третьої сторони, ви маєте ввійти на свій веб-сайт, щоб отримати ключ API, а потім користувач використовує цей ключ (та будь-які інші необхідні облікові дані) для доступу до API через їх додаток, веб-сайт тощо
GreeKatrina

10

Я вважаю за краще пройти маршрут №2 та №3. Головним чином, тому, що №1 порушує розділення проблем і переплітає всі речі. Врешті-решт у вас з’явиться необхідність мати кінцеву точку API, яка не має збігається HTML-сторінки / тощо, і ви будете перетікати з перемежованими кінцевими точками HTML та JSON в одній базі коду. Це перетворюється на вигадливий безлад, навіть якщо його MVP, вам доведеться його переписати зрештою, тому що його суто безладно, що його навіть не варто врятувати.

Перехід на №2 або №3 дозволяє вам повністю мати API, який діє однаково (здебільшого) незалежно. Це забезпечує велику гнучкість. Я ще не продаюсь на 100% на Backbone / ember / what / etc.js. Я думаю, що це чудово, але, як ми бачимо з твіттером, це не є оптимальним. Але ... Twitter також є величезним звіром компанії та має сотні мільйонів користувачів. Таким чином, будь-яке вдосконалення може мати величезний вплив на підсумки на різних ділянках різних бізнес-підрозділів. Я думаю, що рішення має більше, ніж швидкість поодинці, і вони не дозволяють нам у цьому. Але це лише моя думка. Однак я не знижую хребет і його конкурентів. Ці програми чудово використовувати, вони дуже чисті та чутливі (здебільшого).

Третій варіант також має певну привабливість. Тут я б дотримувався принципу Парето (правило 80/20) і мав 20% вашої основної розмітки (або навпаки), зробленої на сервері, а потім маю приємного клієнта JS (магістраль і т.д.) запускати решту цього . Можливо, ви не спілкуєтесь на 100% з RIP api через клієнт JS, але ви зробите певну роботу, якщо це потрібно, щоб покращити досвід роботи.

Я думаю, що це одна з тих проблем "це залежить", і відповідь - це "залежить" від того, що ти робиш, кому служиш і який досвід ти хочеш отримати. Враховуючи, що я думаю, ви можете вибрати між 2 або 3 або їх гібридом.


+1 до гібриду 2 і 3
Ujjwal Ojha

7

Зараз я працюю над перетворенням величезної CMS з варіанту 1 в варіант 3, і це йде добре. Ми вирішили візуалізувати розмітку на стороні сервера, оскільки SEO - це велика справа для нас, і ми хочемо, щоб сайти працювали на мобільних телефонах.

Я використовую node.js для бек-енду клієнта і кілька модулів, щоб допомогти мені. Я дещо рано в цьому процесі, але фундамент встановлюється, і справа в тому, щоб передати дані, щоб забезпечити все це правильно. Ось що я використовую:

  • Експрес за основу програми
    (https://github.com/visionmedia/express)
  • Запит на отримання даних.
    (https://github.com/mikeal/request)
  • Шаблони підкреслення, які отримують сторону сервера. Я повторно їх використовую на клієнті.
    (https://github.com/documentcloud/underscore)
  • UTML обгортає шаблони підкреслення, щоб вони працювали з Express.
    (https://github.com/mikefrey/utml)
  • Наперед збирає шаблони, і ми дамо вам вибрати, які надсилати клієнту.
    (https://github.com/mrDarcyMurphy/upfront)
  • Express Expose передає отримані дані, деякі модулі та шаблони на передній план.
    (https://github.com/visionmedia/express-expose)
  • Магістраль створює моделі та види на передній частині після проковтування даних, що передаються разом.
    (https://github.com/documentcloud/backbone)

Ось серцевина стека. Деякі інші модулі, які мені здаються корисними:

  • fleck (https // github.com / trek / fleck)
  • момент (https // github.com / timrwood / moment)
  • стилус (https // github.com / LearnBoost / stylus)
  • smoosh (https // github.com / fat / smoosh)
    … хоча я шукаю грунт (https // github.com / cowboy / grunt)
  • консольний слід (//github.com/LearnBoost/console-trace).

Ні, я не використовую coffeescript.

Цей варіант працює для мене дуже добре. Моделі на задній панелі відсутні, оскільки дані, які ми отримуємо від API, добре структуровані, і я передаю їх дослівно до передніх. Єдиним винятком є ​​наша модель компонування, де я додаю єдиний атрибут, який робить візуалізацію розумнішою та легшою. Я не використовував для цього жодної фантазійної бібліотеки моделей, а лише функцію, яка додає те, що мені потрібно при ініціалізації, і повертається сама.

(вибачте за дивні посилання, я занадто багато n00b для переповнення стека, щоб дозволити мені публікувати стільки)


1
Отже, ви рендеруєте розмітку на стороні сервера, але ви все ще надаєте шаблони клієнтові та використовуєте Backbone?
Шеннон

7

Ми використовуємо наступний варіант №3: Зробіть сервер REST API лише для JSON. Зробіть сервер веб-сайтів HTML. Веб-сервер HTML не є клієнтом на сервері REST API. Натомість двоє - однолітки. Недалеко від поверхні є внутрішній API, який забезпечує функціонал, необхідний обом серверам.

Ми не знаємо жодного прецеденту, тому це начебто експериментально. Поки що (збирається ввести бета-версію), це склалося досить добре.


Я роздумую над цим варіантом, щоб уникнути деяких проблем, пов’язаних із належним клієнтом API, наприклад автентифікацією. Мені хотілося б дізнатися більше про те, як ви структурували всю справу і як керуєте поділом та спілкуванням між трьома різними частинами. Чи можна щось прочитати? Дякую!
MartinodF

2
@MartinodF Ми розміщуємо в Google App Engine, який обмежується Java або Python. Хотіли використати Python, але були змушені в Java, тому що ми стискаємо числа (не можемо продовжити Py за допомогою C / C ++ на GAE). Ми обрали смуги (Stripes, не Struts, не Spring) для основи презентації. Дуже задоволений цим. Вся справа в одному додатку Java на GAE. Основна функціональність реалізована у купі Java-пакетів та відкрита у внутрішньому API. Є сервлет, який надає послугу JSON REST, та інший, який налаштований як веб-додаток Stripes. Оскільки це все одне додаток GAE Java, спілкування є тривіальним.
Томас Бекер

Дякую за розуміння, це дуже корисно!
MartinodF

7

Я зазвичай збираюся для другого варіанту, використовуючи Rails для складання API та основи для JS. Ви навіть можете безкоштовно отримати панель адміністратора за допомогою ActiveAdmin . Я поставив десятки мобільних додатків із подібним способом. Однак сильно залежить, чи ваш додаток інтерактивне чи ні.

Я презентував цей підхід на останньому RubyDay.it : http://www.slideshare.net/matteocollina/enter-the-app-era-with-ruby-on-rails-rubyday

Для третього варіанту, щоб отримати чуйність другого, ви можете спробувати піжакс, як це робить Github.


6

Мені приблизно за два місяці є проект на три місяці, який використовує другий підхід, який ви тут окреслили. Ми використовуємо сервер RESTful API з backbone.js на передній панелі. Handlebars.js керує шаблонами, а jQuery обробляє маніпуляції AJAX та DOM. Для старих веб-переглядачів та павуків пошуку ми повернулися до візуалізації на стороні сервера, але ми використовуємо ті самі шаблони HTML, що й передній панелі рульових рухів за допомогою Mozilla Rhino.

Ми вибрали такий підхід з багатьох різних причин, але, як відомо, це мало ризиковано, враховуючи, що це ще не було доведено широко. Все те саме, поки все йде досить гладко.

Поки ми лише працювали з одним API, але на наступній фазі проекту ми будемо працювати з другим API. Перший призначений для великої кількості даних, а другий більше схожий на CMS через API.

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

Боюся, що я не Рубін, і не можу коментувати інші підходи. Іноді добре ризикувати. В інших випадках краще відіграти його в безпеці. Ви будете володіти собою залежно від типу проекту.

Пощастить з вибором тут. Хочеться побачити, що поділяють і інші.


1
Отже, ви визначаєте, чи надходить запит від пошукового бота, і подаєте попередньо виведений HTML, якщо він є, та JS + шаблони, якщо він не?
Шеннон

4

Мені подобається №3, коли мій веб-сайт не буде 100-відсотковою реалізацією моїх даних. Що ще має відбутися.

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

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

Ось дуже простий приклад використання декількох додатків для стійок. Я додав там швидкий приклад jquery, щоб побачити, як він потрапляє на додаток API. Ви можете бачити, наскільки це просто може бути із синатри та монтажу декількох стелажних додатків з різними цілями.

https://github.com/dusty/multi-rack-app-app


1

Тут вже є кілька чудових відповідей - я б точно рекомендував №2 або №3 - розмежування є хорошим концептуально, але також на практиці.

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

Між №2 №3 це дійсно залежить від ваших цілей - я погоджуюся, що №2 - це, мабуть, майбутнє веб-сайтів, - але, можливо, ви хочете чогось більш прямого, якщо цей канал буде лише одним із багатьох!


1

Для atyourservice.com.cy ми використовуємо шаблони візуалізованих на сервері сторінок, особливо для того, щоб покрити частину. І використання API для взаємодії після завантаження сторінки. Оскільки наша рамка є MVC, всі функції контролера дублюються на вихід json та вихід html. Шаблони чисті та отримують просто об’єкт. Це може бути перетворено на js-шаблони за лічені секунди. Ми завжди підтримуємо шаблони серверів і просто повертаємось до js за запитом.


1

Ізоморфне відображення та прогресуюче посилення. Який я вважаю, що вас очолив у варіанті три.

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

прогресивне вдосконалення означає почати виконувати клієнтську сторону та рендерінг та прослуховування подій, як тільки ви завантажите всі ресурси та зможете визначити можливості клієнта. Повернення до функціональних можливостей, які не потребують сценаріїв клієнтів, де це можливо для доступності та зворотної сумісності.

Так, звичайно, напишіть автономну програму json api для цієї програми. Але не заходьте так далеко, що ви пишете json api для речей, які добре працюють як статичні HTML-документи.


1

Сервер REST + клієнт-важкий JavaScript був принципом, якого я дотримувався у своїй недавній роботі.

Сервер REST був реалізований в node.js + Express + MongoDB (дуже хороша продуктивність для запису) + Mongoose ODM (чудово підходить для моделювання даних, включені перевірки) + CoffeeScript (зараз я б пішов на ES2015), який добре працював для мене. Node.js може бути відносно молодим порівняно з іншими можливими серверними технологіями, але це дозволило мені написати надійний API з інтегрованими платежами.

Я використовував Ember.js як фреймворк JavaScript, і більша частина логіки програми виконувалася в браузері. Я використовував SASS (спеціально SCSS) для попередньої обробки CSS.

Ембер - це зріла рамка, підкріплена сильною спільнотою. Це дуже потужна основа, яка нещодавно проводила багато робіт, орієнтованих на продуктивність, як абсолютно новий двигун візуалізації Glimmer (натхненний React).

Основна команда Ember знаходиться в стадії розробки FastBoot , який дозволить вам виконати вашу логіку JavaScript Ember на стороні сервера (конкретно node.js) та надіслати користувачеві попередньо виведений HTML (який, як правило, запускається у браузері) користувачеві. Це чудово для SEO та досвіду користувачів, оскільки він не чекає так довго, щоб відобразити сторінку.

Ember CLI - чудовий інструмент, який допомагає вам впорядкувати свій код, і він добре підходив до збільшення кодової бази. Ембер також має власну екосистему Аддон, і ви можете вибрати з різних Ембер Аддонів . Ви можете легко схопити Bootstrap (в моєму випадку) або Foundation та додати його у свою програму.

Щоб не обслуговувати все через Express, я вирішив використовувати nginx для розміщення зображень та клієнта, що перешкоджає JavaScript. Використання проксі-сервера nginx було корисним у моєму випадку:

upstream app_appName.com {
  # replace 0.0.0.0 with your IP address and 1000 with your port of node HTTP server
  server 0.0.0.0:1000;
  keepalive 8;
}

server {
  listen 80 default_server;
  listen [::]:80 default_server ipv6only=on;

  client_max_body_size 32M;

  access_log  /var/log/nginx/appName.access.log;
  error_log  /var/log/nginx/appName.error.log;

  server_name appName.com appName;

  location / {
     # frontend assets path
     root /var/www/html;
     index index.html;

     # to handle Ember routing
     try_files $uri $uri/ /index.html?/$request_uri;
  }

  location /i/ {
    alias /var/i/img/;
  }

  location /api/v1/ {
    proxy_pass  http://app_appName.com;

    proxy_next_upstream error timeout invalid_header http_500 http_502
http_503 http_504;
    proxy_redirect off;
    proxy_buffering off;
    proxy_set_header        Host            $host;
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

Pro: Я люблю розділення API та клієнта. Розумні люди кажуть, що це шлях. Чудово в теорії. Здається, найсучаснішим та захоплюючим.

Я можу сказати, що це також чудово на практиці. Ще одна перевага розділення API REST полягає в тому, що ви можете його повторно використовувати для інших програм. У ідеальному світі ви повинні мати можливість використовувати той же API REST не тільки для веб-сторінки, але і для мобільних додатків, якщо ви вирішите написати його.

Кон: Не дуже великий прецедент. Не багато прикладів цього зроблено добре. Публічні приклади (twitter.com) відчувають себе мляво і навіть переходять від такого підходу.

Зараз речі виглядають інакше. Існує маса прикладів того, як REST API + багато клієнтів споживають його.


1

Я вирішив зайнятися архітектурою Варіант №2 для Інфініформ , оскільки це забезпечив чудовий спосіб відокремити інтерфейс користувача від бізнес-логіки.

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

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


1

Дуже приємне запитання, і я здивований, бо думав, що це сьогодні дуже поширене завдання, що у мене буде багато ресурсів для цієї проблеми, однак виявилося неправдою.

Мої думки такі: - Створіть якийсь модуль, який має загальну логіку між контролерами API та контролерами HTML, не повертаючи json або передаваючи html, і включіть цей модуль як у контролер HTML, так і в контролер API, тоді робіть все, що завгодно, наприклад :

module WebAndAPICommon
    module Products

        def index
            @products = # do some logic here that will set @products variable
        end

    end
end


class ProductsController < ApplicationController
    # default products controlelr, for rendering HMTL pages 
    include WebAndAPICommon

    def index
        super
    end

end



module API
    class ProductsController
        include WebAndAPICommon

        def index
            super
            render json: @products
        end

    end
end

0

Я пішов на гібридний підхід, коли ми використовуємо Sinatra як базу, ActiveRecord / Postgress тощо, щоб обслуговувати маршрутні сторінки (тонкі шаблони) відкрити API REST, який веб-додаток може використовувати. У ранній розробці такі речі, як заповнення параметрів вибору, здійснюються за допомогою помічників, що перетворюються на тонкий шаблон, але, коли ми підходимо до виробництва, це заміняється на виклик AJAX до API REST, оскільки ми починаємо піклуватися про швидкість завантаження сторінки тощо.

Речі, які легко відобразити в Slim, обробляються таким чином, і речі (заповнення форм, отримання даних форми POST від jQuery.Validation і submitHandlerт. Д. , Все очевидно AJAX)

Тестування - це проблема. Зараз я наткнувся, намагаючись передати дані JSON в Rack :: Test POST тест .


0

Я особисто віддаю перевагу варіант (3) як рішення. Він використовується майже на всіх сайтах, які має колишній (домашнє ім’я) роботодавець у мене. Це означає, що ви можете придбати розробників, які знають все про Javascript, химерність браузера та інше, щоб кодувати ваш передній край. Їм потрібно лише знати "curl xyz, і ти отримаєш трохи json", і вони відійдуть.

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

Варіант 3 дає хорошу, надійну трирівневу архітектуру. Це означає, що речі, які ви випльовуєте з переднього кінця, є оптимізаційними для SEO, вони можуть бути зроблені для роботи зі старими чи новими браузерами (і тими, у яких JS вимкнено). виконайте такі дії, як обробляти старі веб-переглядачі / googlebot зі статичним HTML, але надсилайте вбудовані JS динамічні враження людям, які використовують найновіший браузер Chrome або будь-який інший).

У всіх випадках, коли я бачив Варіант 3, це була спеціальна реалізація деяких PHP, які не особливо передаються між проектами, не кажучи вже про те, щоб відкрити вихідну землю. Думаю, нещодавно PHP, можливо, було замінено на Ruby / Rails, але все одно це все одно.

FWIW, $ current_employer може виконати варіант 3 у кількох важливих місцях. Я шукаю гарну рамку Ruby, на якій щось побудувати. Я впевнений, що я можу склеїти безліч дорогоцінних каменів, але я віддаю перевагу одному продукту, який в основному надає шаблонні, «керлінг», необов'язкову автентифікацію, необов’язкове рішення кешування, пов'язане з memcache / nosql. Там мені не вдається знайти щось узгоджене :-(


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.