Отдельный сервер REST JSON API и клиент? [закрыто]


371

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

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

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

ВМЕСТЕ В РЕЙЛЯХ

Сделайте очень стандартное веб-приложение Rails. В контроллере выполните переключатель response_with для обслуживания JSON или HTML. Ответ JSON - это мой API.

Pro: много прецедентов. Великолепные стандарты и множество примеров таких действий.

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

REST SERVER + JAVASCRIPT-ТЯЖЕЛЫЙ КЛИЕНТ

Создайте JSON-сервер REST API. Используйте Backbone или Ember.js для клиентского JavaScript для прямого доступа к API, отображая шаблоны в браузере.

Pro: Я люблю разделение API и клиента. Умные люди говорят, что это путь. Великолепно в теории. Кажется передовым и захватывающим.

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

REST SERVER + HTML-клиент на стороне сервера

Создайте JSON-сервер REST API. Создайте базовый клиент веб-сайта HTML, который обращается только к REST API. Меньше клиентского JavaScript.

Pro: Я люблю разделение API и клиента. Но обслуживание простого HTML5 довольно надежно и не требует большого количества клиентов.

Против: не так много прецедентов. Не много примеров этого сделано хорошо. Фреймворки также не поддерживают это. Не уверен, как подойти к нему.

Особенно ищет советы по опыту, а не только по теории.


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

2
У кого-нибудь есть примеры / источники (чтобы понять их причины) для тех, кто отходит от варианта 2?
Виктор Лопес Гарсия

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

1
Прочитайте комментарии в ссылках выше. Многие предположения статьи опровергнуты логикой и опытом.
Рикалсин

1
В эти дни вы захотите создать бэкэнд API JSON, следуя спецификациям jsonapi.org ... :)
Аскар

Ответы:


136

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

Плюсы:

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

Минусы:

  • Не оптимизированный для SEO / готовый без большого количества работы.
  • Требуется первоклассный пользовательский интерфейс, готовый справиться с реальностью сайта, который на 70% состоит из JavaScript и что это значит.

Я думаю, что это будущее всех веб-приложений.

Некоторые мысли для пользователей веб-интерфейса (вот где вся новизна / вызов дается этой архитектуре):

  • CoffeeScript. Гораздо проще производить качественный код.
  • Backbone. Отличный способ организовать свою логику и активное сообщество.
  • HAMLC. Шаблоны Haml + CoffeeScript => JS.
  • SASS

Мы создали жгут для нашей интерфейсной разработки под названием «Spar» (одностраничное приложение Rocketship), которое фактически представляет собой конвейер ресурсов от Rails, настроенный для разработки одностраничных приложений. В течение следующих нескольких недель на нашей странице GitHub будет открыт ресурс , а также будет опубликовано сообщение в блоге, объясняющее, как использовать его и общую архитектуру более подробно.

ОБНОВИТЬ:

Что касается проблем людей с Backbone, я думаю, что они переоценены. Магистраль - это скорее организационный принцип, чем глубокая структура. Сам сайт Твиттера - гигантский зверь Javascript, охватывающий каждый кейс для миллионов пользователей и устаревших браузеров, при этом загружая твиты в реальном времени, собирая мусор, отображая множество мультимедиа и т. Д. Из всех «чистых» js-сайтов, которые я имею видно, твиттер лишний. Было много впечатляюще сложных приложений, доставленных через JS, которые очень хорошо работают.

И ваш выбор архитектуры полностью зависит от ваших целей. Если вы ищете самый быстрый способ поддержки нескольких клиентов и имеете доступ к хорошим талантам переднего плана, инвестирование в автономный API - это отличный способ.


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

Такие вещи, как Parse и Kinvey, очень интересны, я не могу сказать, что у меня еще был шанс сыграть с ними. Зависит, если ваше значение находится в передней или задней части стека, я полагаю
Аарон

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

Как вы обрабатываете один домен, на котором работают два отдельных приложения? Например. У меня есть www.mysite.com, и я хочу предоставить общедоступный API-интерфейс и предоставить интерфейс для этого URL. В соответствии с принципами REST, mysite.com/product/24, доступ к которому осуществляется через веб-браузер, должен возвращать HTML-страницу, просматривая заголовок HTTP Accept, а GET с JSON в заголовке Accept на mysite.com/product/24 должен возвращать JSON ,
Эрих

Как AngularJS справится с этим?
Анкан-Зероб

48

Очень хорошо спросил. +1. Конечно, это будущие полезные ссылки для меня. Также @Aaron и другие добавили ценность для обсуждения. Как и Ruby, этот вопрос в равной степени применим к другим средам программирования.

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

Опция 1

Этот, без сомнения, самый популярный. Но я считаю, что реализация очень много http-иш. Каждый исходный код API относится к объекту запроса. Таким образом, код API - это больше, чем просто код ruby ​​/ python / другого языка.

Вариант 2

Я всегда любил это.

Эта опция также подразумевает, что HTML не генерируется во время выполнения на сервере. Это отличает вариант 2 от варианта 3. Но он создается как статический html с использованием сценария сборки. При загрузке на стороне клиента эти HTML будут вызывать сервер API как клиент JS API.

  • Разделение интересов является большим преимуществом. И очень по вашему вкусу (и моему) бэкэнд-эксперты реализуют API-интерфейсы бэкэнда, легко тестируют их, как обычный языковой код, не беспокоясь о коде запроса framework / http.

  • Это действительно не так сложно, как звучит на внешней стороне. Делать вызовы API и полученные данные (в основном, json) можно на вашем клиентском шаблоне или в MVC.

  • Меньше обработки на стороне сервера. Это означает, что вы можете перейти на обычное оборудование / менее дорогой сервер.

  • Легче тестировать слои независимо, проще создавать документы API.

У него есть некоторые недостатки.

  • Многим разработчикам это сложно и сложно понять. Таким образом, есть вероятность, что архитектура может подвергнуться критике.

  • i18n / l10n сложно. Поскольку HTML по сути генерируется, время сборки статично, для каждого поддерживаемого языка требуется несколько сборок (что не обязательно плохо). Но даже с этим у вас могут быть угловые случаи около l10n / i18n и вам нужно быть осторожным.

Вариант 3

Кодирование бэкенда в этом случае должно совпадать со вторым вариантом. Большинство пунктов для варианта 2 применимы и здесь.

Веб-страницы отображаются во время выполнения с использованием шаблонов на стороне сервера. Это значительно облегчает работу с более устоявшимися / принятыми методами. Может быть на один HTTP-вызов меньше для некоторого существенного контекста, необходимого для рендеринга страницы, такого как пользователь, язык, валюта и т. Д. Таким образом, обработка на стороне сервера увеличивается при рендеринге, но, возможно, компенсируется меньшим количеством http-вызовов к API-серверу.

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

Чехол для твиттера

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

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

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

  • API-сервер: Python Быстрая веб-микро-фреймворк - Flask
  • Фронтенд-сервер: Nginx
  • Клиентская сторона MVC: Knockout.js
  • Другие соответствующие инструменты / библиотеки:
    • Jquery
    • Accounting.js для денежной валюты
    • Webshim : кросс-браузерный полифилл
    • директор : клиентская маршрутизация
    • sphc : генерация HTML

Мой вывод и рекомендация

Вариант 3!

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


Мне также нравится вариант 2, но у варианта 3 есть много преимуществ, от которых мы не можем избавиться. Я пытаюсь найти какое-нибудь гидрид-решение, объединяющее оба варианта opt2 + opt3, но это приведет к головной боли, такой как Twitter.
Блю Смит

Мне нравится вариант 3, и я хочу использовать его для текущего проекта. Любой например, или Git репо вы можете указать на помощь?
AmaChefe

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

28

Мы выбрали № 2 при создании gaug.es. Я работал над API (ruby, sinatra и т. Д.), А мой деловой партнер Стив Смит работал над интерфейсом (клиент javascript).

Плюсы:

  1. Двигайтесь быстро параллельно. Если бы я работал раньше Стива, я мог бы продолжать создавать API для новых функций. Если бы он работал впереди меня, он мог бы очень легко подделать API и создать пользовательский интерфейс.

  2. API бесплатно. Наличие открытого доступа к данным в вашем приложении быстро становится стандартной функцией. Если вы начнете с API с нуля, вы получите это бесплатно.

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

Минусы:

  1. Обратная совместимость. Это больше относится к API, чем к вашему прямому вопросу, но как только ваш API появится, вы не сможете просто сломать его или сломать всех своих клиентов на двоих. Это не означает, что вам нужно двигаться медленнее, но это означает, что вам часто приходится заставлять две вещи работать одновременно. Добавление в API или новые поля - это хорошо, но изменение / удаление не должно выполняться без контроля версий.

Я не могу больше думать о минусах прямо сейчас.

Заключение: клиент API + JS - это то, что нужно, если вы планируете выпустить API.

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

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 / whats / etc.js. Я думаю, это здорово, но, как мы видим в твиттере, это не оптимально. НО ... Твиттер также огромный зверь компании и имеет сотни миллионов пользователей. Таким образом, любое улучшение может иметь огромное влияние на практический результат в различных областях различных бизнес-единиц. Я думаю, что в этом есть нечто большее, чем просто скорость, и нас это не пускает. Но это только мое мнение. Однако я не сбрасываю со счетов магистраль и его конкурентов. Эти приложения удобны в использовании, очень чисты и очень отзывчивы (по большей части).

Третий вариант также имеет некоторое действительное очарование. Здесь я следую принципу Парето (правило 80/20) и получаю 20% от вашей основной разметки (или наоборот), отображаемой на сервере, а затем получаю хороший JS-клиент (магистраль / и т. Д.) Для запуска остальной части. , Возможно, вы не на 100% обмениваетесь данными с API REST через JS-клиент, но при необходимости вы будете выполнять некоторую работу, чтобы улучшить работу с suer.

Я думаю, что это одна из тех «это зависит» от вида проблем, и ответ «это зависит» от того, что вы делаете, кому вы служите и какой опыт вы хотите, чтобы они получили. Учитывая, что я думаю, вы можете выбрать между 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)
  • Upfront собирает шаблоны и позволяет выбирать, какие из них отправляются клиенту.
    (https://github.com/mrDarcyMurphy/upfront)
  • Express Expose передает извлеченные данные, некоторые модули и шаблоны внешнему интерфейсу.
    (https://github.com/visionmedia/express-expose)
  • Backbone создает модели и представления во внешнем интерфейсе после проглатывания полученных данных.
    (https://github.com/documentcloud/backbone)

Это ядро ​​стека. Некоторые другие модули, которые я нашел полезными:

  • fleck (https // github.com / trek / fleck)
  • момент (https // github.com / timrwood / момент)
  • стилус (https // github.com / LearnBoost / стилус)
  • 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, как и в вашем варианте, не является клиентом сервера API REST. Вместо этого два сверстники. Недалеко от поверхности находится внутренний API, который обеспечивает функциональность, необходимую двум серверам.

Мы не знаем ни о каком прецеденте, так что это экспериментально. Пока (собирается войти в бета-версию), это сработало довольно хорошо.


Я думаю об этой опции, чтобы избежать некоторых проблем, связанных с тем, чтобы быть надлежащим клиентом API, таких как аутентификация. Я хотел бы узнать больше о том, как вы структурировали все это и как вы управляете разделением и связью между тремя различными частями. Я могу что-нибудь прочитать? Спасибо!
MartinodF

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

Спасибо за понимание, это очень полезно!
MartinodF

7

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

Я сделал презентацию об этом подходе на последнем RubyDay.it : http://www.slideshare.net/matteocollina/enter-the-app-era-with-ruby-on-rails-rubyday

Для третьего варианта, чтобы получить отзывчивость второго, вы можете попробовать pajax, как это делает Github.


6

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

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

Пока что мы только что работали с одним API, но на следующем этапе проекта мы будем работать со вторым API. Первый предназначен для больших объемов данных, а второй действует больше как CMS через API.

Наличие этих двух частей проекта, полностью независимых друг от друга, было ключевым фактором при выборе этой инфраструктуры. Если вы ищете архитектуру для объединения различных независимых ресурсов без каких-либо зависимостей, то этот подход стоит посмотреть.

Боюсь, я не Ruby парень, поэтому я не могу комментировать другие подходы. Иногда можно рисковать. В других случаях лучше не рисковать. Вы будете в зависимости от типа проекта.

Желаем удачи с вашим выбором здесь. Стремится увидеть то, что разделяют и другие.


1
Таким образом, вы определяете, поступает ли запрос от поискового бота, и обслуживаете предварительно отрендеренный HTML, если он есть, и шаблоны JS +, если это не так?
Шеннон

4

Мне нравится № 3, когда мой сайт не будет 100% CRUD-реализацией моих данных. Что еще должно произойти.

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

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

Вот очень простой пример использования нескольких стоечных приложений. Я добавил быстрый пример jquery, чтобы вы увидели, что он работает с приложением API. Вы можете увидеть, насколько просто это может быть с sinatra и монтированием нескольких стоечных приложений для разных целей.

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.

Ember - зрелая структура, поддержанная сильным сообществом. Это очень мощный фреймворк, в котором в последнее время выполняется много работы, ориентированной на производительность, например, новый движок рендеринга Glimmer (вдохновленный React).

Ember Core Team находится в процессе разработки FastBoot , который позволит вам выполнить вашу логику JavaScript Ember на стороне сервера (в частности, node.js) и отправить пользователю предварительно обработанный HTML-код вашего приложения (который обычно выполняется в браузере). Это отлично подходит для SEO и пользовательского опыта, так как он не ждет так долго, чтобы страница отображалась.

Ember CLI - отличный инструмент, который помогает вам организовать ваш код, и он хорошо масштабировался с ростом кодовой базы. У Ember также есть своя собственная аддонная экосистема, и вы можете выбирать из множества аддонов Ember . Вы можете легко получить 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 и клиента. Умные люди говорят, что это путь. Великолепно в теории. Кажется передовым и захватывающим.

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

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

Теперь все выглядит иначе. Есть много примеров использования REST API + много клиентов, использующих его.


1

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

Преимущество этого заключается в том, что серверы 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 и т. Д. Для обслуживания маршрутов страниц (тонкие шаблоны), чтобы представить REST API, который веб-приложение может использовать. На ранних этапах разработки такие вещи, как заполнение опций выбора, выполняются посредством рендеринга помощников в тонкий шаблон, но по мере приближения к производству это заменяется вызовом AJAX REST API, поскольку мы начинаем больше заботиться о скорости загрузки страниц и так далее.

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

Тестирование это проблема. Сейчас я в тупике, пытаясь передать данные JSON в тест Rack :: Test POST .


0

Я лично предпочитаю вариант (3) в качестве решения. Он используется почти на всех сайтах моего бывшего (фамилии) работодателя. Это означает, что вы можете получить некоторых разработчиков интерфейса, которые знают все о Javascript, особенностях браузера и еще много чего, чтобы закодировать ваш интерфейс. Им нужно знать только "curl xyz, и вы получите немного json", и они уходят.

Тем временем ваши тяжелые бэкэнды могут кодировать провайдеров Json. Этим ребятам вообще не нужно думать о представлении, а вместо этого беспокоятся о нестабильных бэкэндах, тайм-аутах, изящной обработке ошибок, пулах соединений с базами данных, потоке, масштабировании и т. Д.

Вариант 3 дает вам хорошую, прочную трехуровневую архитектуру. Это означает, что то, что вы выплевываете из внешнего интерфейса, оптимизировано для SEO, может быть приспособлено для работы со старыми или новыми браузерами (и с отключенным JS), и все же может быть Javascript-шаблоном на стороне клиента, если вы хотите (так что вы можете делайте что-то вроде обработки старых браузеров / 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.