Serveur et client API REST JSON séparés? [fermé]

371

Je suis sur le point de créer un tas d'applications Web à partir de zéro. (Voir http://50pop.com/code pour un aperçu.) J'aimerais qu'ils soient accessibles à partir de nombreux clients différents: sites Web frontaux, applications pour smartphones, services Web principaux, etc. Je veux donc vraiment un API JSON REST pour chacun.

De plus, je préfère travailler sur le back-end, donc je rêve de me concentrer uniquement sur l'API et d'embaucher quelqu'un d'autre pour créer l'interface utilisateur frontale, qu'il s'agisse d'un site Web, d'un iPhone, d'Android ou d'une autre application.

Veuillez m'aider à décider de l'approche à adopter:

ENSEMBLE EN RAILS

Créez une application web Rails très standard. Dans le contrôleur, effectuez le commutateur respond_with pour servir JSON ou HTML. La réponse JSON est alors mon API.

Pro: Beaucoup de précédents. De grandes normes et de nombreux exemples de faire les choses de cette façon.

Inconvénient: vous ne voulez pas nécessairement que l'API soit la même que l'application Web. Je n'aime pas l'approche du commutateur if / then respond_with. Mélanger deux choses très différentes (UI + API).

SERVEUR REST + CLIENT LOURD JAVASCRIPT

Créez un serveur d'API REST uniquement JSON. Utilisez Backbone ou Ember.js pour JavaScript côté client pour accéder directement à l'API, en affichant les modèles dans le navigateur.

Pro: J'aime la séparation de l'API et du client. Les gens intelligents disent que c'est la voie à suivre. Génial en théorie. Semble de pointe et passionnant.

Con: Pas beaucoup de précédents. Pas beaucoup d'exemples de cela bien fait. Les exemples publics (twitter.com) se sentent lents et s'éloignent même de cette approche.

SERVEUR REST + CLIENT HTML CÔTÉ SERVEUR

Créez un serveur d'API REST uniquement JSON. Créez un client de site Web HTML de base, qui accède uniquement à l'API REST. Moins de JavaScript côté client.

Pro: J'aime la séparation de l'API et du client. Mais servir du HTML5 simple est assez infaillible et ne demande pas beaucoup de clients.

Con: Pas beaucoup de précédents. Pas beaucoup d'exemples de cela bien fait. Les cadres ne prennent pas en charge cela également. Je ne sais pas comment l'aborder.

Surtout à la recherche de conseils d'expérience, pas seulement en théorie.

sivers
la source
50
nous préférons généralement que les questions spéculatives et conceptuelles du tableau blanc soient envoyées sur programmers.stackexchange.com tandis que les questions ici sur Stack Overflow devraient contenir le code source réel 99% du temps. Mais, c'est une question bien posée et j'aime votre travail, donc cela peut tomber dans la zone grise pour l'instant.
Jeff Atwood
2
Quelqu'un a-t-il des exemples / sources (pour comprendre leurs raisons) pour ceux qui s'éloignent de l'option 2?
Víctor López García
12
@frntk La raison initiale pour laquelle de nombreuses entreprises (comme Twitter) utilisaient des clients Javascript était parce qu'elles pensaient que ce serait plus rapide. Maintenant, ils se rendent compte que c'est en fait plus lent. Voir engineering.twitter.com/2012/05/… et openmymind.net/2012/5/30/Client-Side-vs-Server-Side-Rendering
Moshe Katz
1
Lisez les commentaires dans les liens ci-dessus. De nombreuses hypothèses de l'article sont réfutées par la logique et l'expérience.
Ricalsin
1
Ces jours-ci, vous voudriez faire un backend API JSON en suivant les spécifications de jsonapi.org ... :)
Askar

Réponses:

136

Chez Boundless , nous avons approfondi l'option n ° 2 et l'avons déployée auprès de milliers d'étudiants. Notre serveur est une API JSON REST (Scala + MongoDB), et tout notre code client est servi directement à partir de CloudFront (par exemple: www.boundless.com n'est qu'un alias pour CloudFront).

Avantages:

  • Avant-gardiste / passionnant
  • Beaucoup pour votre argent: l'API vous donne une base pour votre propre client Web, clients mobiles, accès tiers, etc.
  • chargement de site / transitions de page extrêmement rapides

Les inconvénients:

  • Pas compatible avec le référencement / prêt sans beaucoup de travail.
  • Nécessite des utilisateurs Web haut de gamme qui sont prêts à faire face à la réalité d'une expérience de site qui est à 70% javascript et ce que cela signifie.

Je pense que c'est l'avenir de toutes les applications Web.

Quelques réflexions pour les gens du front web (c'est là que toute la nouveauté / le défi reçoit cette architecture):

  • CoffeeScript. Il est beaucoup plus facile de produire du code de haute qualité.
  • Colonne vertébrale. Excellent moyen d'organiser votre logique et votre communauté active.
  • HAMLC. Modèles Haml + CoffeeScript => JS.
  • TOUPET

Nous avons construit un harnais pour notre développement frontal appelé `` Spar '' (Single Page App Rocketship) qui est en fait le pipeline d'actifs de Rails réglé pour le développement d'applications sur une seule page. Nous allons faire de l'open source dans les prochaines semaines sur notre page github , avec un article de blog expliquant comment l'utiliser et l'architecture globale plus en détail.

MISE À JOUR:

En ce qui concerne les préoccupations des gens avec Backbone, je pense qu'elles sont surévaluées. L'épine dorsale est bien plus un principe organisationnel qu'un cadre profond. Le site de Twitter lui-même est une bête géante de Javascript couvrant chaque coin de cas sur des millions d'utilisateurs et de navigateurs hérités, tout en chargeant les tweets en temps réel, la collecte des ordures, l'affichage de nombreux contenus multimédias, etc. De tous les sites js «purs» que j'ai vu, Twitter est le plus étrange. De nombreuses applications incroyablement compliquées livrées via JS fonctionnent très bien.

Et votre choix d'architecture dépend entièrement de vos objectifs. Si vous recherchez le moyen le plus rapide de prendre en charge plusieurs clients et d'avoir accès à de bons talents front-end, investir dans une API autonome est une excellente façon de procéder.

Aaron
la source
1
Un point mineur à ajouter: Bien que je n'ai construit que l'option # 1, je connais plusieurs développeurs d'applications mobiles qui commencent à utiliser parse.com comme backend afin de permettre un accès rapide à # 2.
Rhb123
Des choses comme Parse et Kinvey sont très intéressantes, je ne peux pas dire que j'ai encore eu la chance de jouer avec. Cela dépend si votre valeur est à l'avant ou à l'arrière de la pile, je suppose
Aaron
J'utilise la même approche avec spinejs pour le frontend.
Nicolas Goy
Comment gérez-vous un seul domaine exécutant deux applications distinctes? Par exemple. J'ai www.mysite.com et je veux exposer une API publique et servir un frontal sur cette URL. Fidèle aux principes REST, mysite.com/product/24 accessible à partir d'un navigateur Web doit retourner une page HTML en regardant l'en-tête HTTP Accept, et un GET avec JSON dans l'en-tête Accept sur mysite.com/product/24 doit retourner JSON .
Erich
Comment AngularJS se comporterait-il pour cela?
Ankan-Zerob
48

Très bien demandé. +1. Pour sûr, c'est une future référence utile pour moi. @Aaron et d'autres ont également ajouté de la valeur à la discussion. Comme Ruby, cette question est également applicable à d'autres environnements de programmation.

J'ai utilisé les deux premières options. Première pour de nombreuses applications et deuxième pour mon projet open source Cowoop

Option 1

Celui-ci est sans aucun doute le plus populaire. Mais je trouve que la mise en œuvre est très http-ish. Le code initial de chaque API sert à traiter l'objet de demande. Le code API est donc plus qu'un pur code ruby ​​/ python / autre langage.

Option 2

J'ai toujours aimé ça.

Cette option implique également que HTML n'est pas généré à l'exécution sur le serveur. C'est en cela que l'option 2 est différente de l'option 3. Mais sont construits en HTML statique à l'aide d'un script de construction. Lorsqu'ils sont chargés côté client, ces HTML appellent le serveur API en tant que client API JS.

  • La séparation des préoccupations est un grand avantage. Et à votre goût (et le mien), les experts backend implémentent des API backend, testez-les facilement comme le code de langage habituel sans vous soucier du code de requête framework / http.

  • Ce n'est vraiment pas aussi difficile qu'il y paraît du côté frontal. Les appels API et les données résultantes (principalement json) sont disponibles pour votre modèle côté client ou MVC.

  • Moins de traitement côté serveur. Cela signifie que vous pouvez opter pour du matériel de base / un serveur moins cher.

  • Plus facile de tester les couches indépendamment, de générer plus facilement des documents API.

Il a des inconvénients.

  • De nombreux développeurs trouvent cela trop complexe et difficile à comprendre. Il y a donc de fortes chances que l'architecture soit critiquée.

  • i18n / l10n est difficile. Étant donné que le HTML est essentiellement généré, le temps de construction est statique, il faut plusieurs versions par langue prise en charge (ce qui n'est pas nécessairement une mauvaise chose). Mais même avec cela, vous pouvez avoir des cas d'angle autour de l10n / i18n et devez être prudent.

Option 3

Le codage backend dans ce cas doit être identique à la deuxième option. La plupart des points pour l'option 2 sont également applicables ici.

Les pages Web sont rendues à l'exécution à l'aide de modèles côté serveur. Cela rend i18n / l10n beaucoup plus facile avec des techniques plus établies / acceptées. Peut être un appel http de moins pour un contexte essentiel nécessaire au rendu de page comme l'utilisateur, la langue, la devise, etc. Ainsi, le traitement côté serveur est augmenté avec le rendu mais peut-être compensé par moins d'appels http au serveur API.

Maintenant que les pages sont rendues par le serveur sur le serveur, le frontend est désormais plus lié à l'environnement de programmation. Cela pourrait même ne pas être une considération pour de nombreuses applications.

Cas Twitter

Si je comprends bien, Twitter peut effectuer son rendu de page initial sur le serveur, mais pour les mises à jour de page, il a toujours des appels d'API et des modèles côté client pour manipuler DOM. Donc, dans ce cas, vous avez deux modèles à maintenir, ce qui ajoute un peu de surcharge et de complexité. Tout le monde ne peut pas se permettre cette option, contrairement à Twitter.

Notre projet Stack

Il se trouve que j'utilise Python. J'utilise JsonRPC 2.0 au lieu de REST. Je suggère REST, bien que j'aime l'idée de JsonRPC pour diverses raisons. J'utilise les bibliothèques ci-dessous. Quelqu'un qui envisage l'option 2/3 pourrait la trouver utile.

  • Serveur API: Python Un micro framework web rapide - Flask
  • Serveur frontal: Nginx
  • MVC côté client: Knockout.js
  • Autres outils / bibliothèques pertinents:

Ma conclusion et ma recommandation

Option 3 !.

Cela dit, j'ai utilisé avec succès l'option 2, mais je penche maintenant vers l'option 3 pour plus de simplicité. Il est très tentant de générer des pages HTML statiques avec un script de construction et de les servir avec l'un des serveurs ultra rapides spécialisés dans la diffusion de pages statiques (option 2).

Shekhar
la source
J'aime aussi l'option 2, mais l'option 3 présente de nombreux avantages dont nous ne pouvons nous débarrasser. J'essaie de trouver une solution d'hydrid combinant les deux opt2 + opt3, mais cela entraînera des maux de tête comme Twitter.
Blue Smith
J'adore l'option 3 et viser à l'utiliser si pour un projet en cours. Par exemple, ou git repo, vous pouvez demander de l'aide?
AmaChefe du
@AmaChefe je souhaite. Pour le projet actuel où le référencement est crucial, nous utilisons l'option 3. Mais le code n'est pas open source. Nous utilisons flask + jinja2 et knockout / react.js.
Shekhar
28

Nous avons opté pour # 2 lors de la construction de gaug.es. J'ai travaillé sur l'API (ruby, sinatra, etc.) et mon partenaire commercial, Steve Smith, a travaillé sur le front-end (client javascript).

Avantages:

  1. Déplacez-vous rapidement en parallèle. Si je travaillais avant Steve, je pourrais continuer à créer des API pour de nouvelles fonctionnalités. S'il travaillait devant moi, il pourrait simuler l'API très facilement et créer l'interface utilisateur.

  2. API gratuitement. Avoir un accès ouvert aux données de votre application devient rapidement une fonctionnalité standard. Si vous commencez avec une API à partir de zéro, vous l'obtenez gratuitement.

  3. Séparation nette. Il est préférable de considérer votre application comme une API avec des clients. Bien sûr, le premier et le plus important client peut être un client Web, mais il vous permet de créer facilement d'autres clients (iPhone, Android).

Les inconvénients:

  1. Rétrocompatibilité. Cela est plus lié à une API qu'à votre question directe, mais une fois que votre API est disponible, vous ne pouvez pas simplement la casser ou casser tous vos clients à deux. Cela ne signifie pas que vous devez vous déplacer plus lentement, mais cela signifie que vous devez souvent faire fonctionner deux choses à la fois. L'ajout à l'API ou à de nouveaux champs est correct, mais la modification / suppression ne doit pas se faire sans versioning.

Je ne peux plus penser à des inconvénients pour le moment.

Conclusion: le client API + JS est la voie à suivre si vous prévoyez de publier une API.

PS Je recommanderais également de documenter entièrement votre API avant de la publier. Le processus de documentation de l'API Gaug.es nous a vraiment aidés à

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

John Nunemaker
la source
13
Puis-je vous demander comment vous authentifiez l'interface Web avec l'API REST? J'ai vu que vous avez besoin d'une clé API pour communiquer avec l'API qui est obtenue en vous connectant à votre profil utilisateur. Mais comment le client Web obtient-il sa clé API, si vous voyez ce que je veux dire?
Sebastian Wramba
@SebastianWramba Il est tard, mais comme votre commentaire a reçu 12 votes positifs ... je regarderais quelque chose comme l' autorisation de mot de passe d'OAuth2 . Si vous êtes le créateur de l'application appelant l'API, c'est l'approche que vous souhaitez probablement, car elle n'utilise pas directement la clé API. S'il s'agit d'une application tierce, l'utilisateur doit se connecter à votre site Web pour obtenir sa clé API, puis l'utilisateur utilise cette clé (et toute autre information d'identification nécessaire) pour accéder à l'API via son application, son site Web, etc.
GreeKatrina
10

Je préfère emprunter la route des # 2 et # 3. Principalement parce que le n ° 1 viole la séparation des préoccupations et mêle toutes sortes de choses. Finalement, vous trouverez la nécessité d'avoir un point de terminaison API qui n'a pas de page HTML / etc correspondante et vous serez dans un ruisseau avec des points de terminaison HTML et JSON entremêlés dans la même base de code. Il se transforme en un désordre flippant, même si son MVP, vous devrez éventuellement le réécrire parce que c'est tellement désordonné qu'il ne vaut même pas la peine d'être récupéré.

Aller avec # 2 ou # 3 vous permet d'avoir complètement une API qui agit de la même manière (pour la plupart) indépendamment. Cela offre une grande flexibilité. Je ne suis pas encore vendu à 100% sur Backbone / ember / que ce soit / etc.js. Je pense que c'est génial, mais comme nous le voyons avec Twitter, ce n'est pas optimal. MAIS ... Twitter est aussi une énorme bête d'entreprise et compte des centaines de millions d'utilisateurs. Ainsi, toute amélioration peut avoir un impact énorme sur le résultat net dans divers domaines des différentes unités commerciales. Je pense qu'il y a plus dans la décision que la vitesse seule et ils ne nous laissent pas entrer. Mais c'est juste mon opinion. Cependant, je n'écarte pas l'épine dorsale et ses concurrents. Ces applications sont géniales à utiliser et sont très propres et très réactives (pour la plupart).

La troisième option a également une allure valable. C'est là que je suivrais le principe de Pareto (règle 80/20) et que 20% de votre balisage principal (ou vice versa) serait rendu sur le serveur, puis qu'un bon client JS (backbone / etc) exécuterait le reste . Il se peut que vous ne communiquiez pas à 100% avec l'API REST via le client JS, mais vous ferez du travail si nécessaire pour améliorer l'expérience suer.

Je pense que c'est l'un de ces types de problèmes «cela dépend» et la réponse est «cela dépend» de ce que vous faites, de qui vous êtes en train de servir et du type d'expérience que vous souhaitez qu'ils reçoivent. Étant donné que je pense que vous pouvez choisir entre 2 ou 3 ou un hybride d'entre eux.

Donn Felker
la source
+1 à l'hybride de 2 et 3
Ujjwal Ojha
7

Je travaille actuellement sur la conversion d'un énorme CMS de l'option 1 à l'option 3, et ça se passe bien. Nous avons choisi de rendre le balisage côté serveur parce que le référencement est un gros problème pour nous, et nous voulons que les sites fonctionnent bien sur les téléphones mobiles.

J'utilise node.js pour le back-end du client et une poignée de modules pour m'aider. Je suis un peu tôt dans le processus, mais les bases sont établies et il s'agit de passer en revue les données pour s'assurer que tout se passe bien. Voici ce que j'utilise:

  • Express pour la fondation de l'application.
    (https://github.com/visionmedia/express)
  • Demande de récupération des données.
    (https://github.com/mikeal/request)
  • Modèles de soulignement qui sont rendus côté serveur. Je les réutilise sur le client.
    (https://github.com/documentcloud/underscore)
  • UTML encapsule les modèles de soulignement pour les faire fonctionner avec Express.
    (https://github.com/mikefrey/utml)
  • Upfront collecte des modèles et vous permet de choisir ceux à envoyer au client.
    (https://github.com/mrDarcyMurphy/upfront)
  • Express Expose transmet les données extraites, certains modules et modèles au frontal.
    (https://github.com/visionmedia/express-expose)
  • Backbone crée des modèles et des vues sur le front-end après avoir avalé les données transmises.
    (https://github.com/documentcloud/backbone)

C'est le cœur de la pile. Quelques autres modules que j'ai trouvés utiles:

  • fleck (https // github.com / trek / fleck)
  • moment (https // github.com / timrwood / moment)
  • stylet (https // github.com / LearnBoost / stylus)
  • smoosh (https // github.com / fat / smoosh)
    … bien que je cherche à grogner (https // github.com / cowboy / grunt)
  • trace de la console (//github.com/LearnBoost/console-trace).

Non, je n'utilise pas coffeescript.

Cette option fonctionne très bien pour moi. Les modèles sur le back-end sont inexistants car les données que nous obtenons de l'API sont bien structurées et je les transmets textuellement au front-end. La seule exception est notre modèle de disposition où j'ajoute un seul attribut qui rend le rendu plus intelligent et plus léger. Je n'ai pas utilisé de bibliothèque de modèles sophistiqués pour cela, juste une fonction qui ajoute ce dont j'ai besoin à l'initialisation et se retourne.

(désolé pour les liens étranges, je suis trop n00b pour le débordement de pile pour me laisser en poster autant)

Darcy Murphy
la source
1
Vous effectuez donc un balisage côté serveur, mais vous donnez toujours des modèles au client et utilisez Backbone?
Shannon
7

Nous utilisons la variante suivante de # 3: créer un serveur d'API REST JSON uniquement. Créez un serveur de site Web HTML. Le serveur Web HTML n'est pas, comme dans votre variante, un client du serveur API REST. Au lieu de cela, les deux sont des pairs. Non loin sous la surface, il existe une API interne qui fournit les fonctionnalités dont les deux serveurs ont besoin.

Nous ne connaissons aucun précédent, c'est donc un peu expérimental. Jusqu'à présent (sur le point d'entrer en version bêta), cela a plutôt bien fonctionné.

Thomas Becker
la source
Je pense à cette option pour éviter certains problèmes liés au bon client API, comme l'authentification. J'aimerais en savoir plus sur la façon dont vous avez structuré le tout et comment vous gérez la séparation et la communication entre les trois parties différentes. Y a-t-il quelque chose que je pouvais lire? Merci!
MartinodF
2
@MartinodF Nous hébergeons sur Google App Engine, qui se limite à Java ou Python. Voulait utiliser Python, mais a été forcé en Java parce que nous crunch les nombres (ne peut pas étendre Py avec C / C ++ sur GAE). Nous avons choisi Stripes (Stripes, not Struts, not Spring) pour le cadre de présentation. Très content de ça. Le tout est une application Java sur GAE. La fonctionnalité de base est implémentée dans un tas de packages Java et exposée dans une API interne. Il existe un servlet qui fournit le service JSON REST et un autre qui est configuré en tant qu'application Web Stripes. Comme il s'agit d'une seule application GAE Java, la communication est triviale.
Thomas Becker
Merci pour la perspicacité, c'est très utile!
MartinodF
7

Je vais généralement pour la 2ème option, en utilisant Rails pour construire l'API et le backbone pour les trucs JS. Vous pouvez même obtenir un panneau d'administration gratuitement en utilisant ActiveAdmin . J'ai expédié des dizaines d'applications mobiles avec ce type de backend. Cependant, cela dépend fortement si votre application est interactive ou non.

J'ai fait une présentation sur cette approche lors du dernier RubyDay.it : http://www.slideshare.net/matteocollina/enter-the-app-era-with-ruby-on-rails-rubyday

Pour la troisième option, afin d'obtenir la réactivité de la 2ème, vous voudrez peut-être essayer pajax comme le fait Github.

Matteo Collina
la source
6

Je suis environ 2 mois dans un projet de 3 mois qui prend la deuxième approche que vous avez décrite ici. Nous utilisons un serveur API RESTful avec backbone.js à l'avant. Handlebars.js gère les modèles et jQuery gère la manipulation AJAX et DOM. Pour les navigateurs plus anciens et les araignées de recherche, nous sommes retombés sur le rendu côté serveur, mais nous utilisons les mêmes modèles HTML que le frontend Handlebars utilisant Mozilla Rhino.

Nous avons choisi cette approche pour de nombreuses raisons différentes, mais nous sommes très conscients qu'elle est un peu risquée car elle n'a pas encore été prouvée à grande échelle. Tout de même, tout se passe bien jusqu'à présent.

Jusqu'à présent, nous travaillons avec une seule API, mais dans la prochaine phase du projet, nous travaillerons avec une deuxième API. Le premier est pour de grandes quantités de données, et le second agit plus comme un CMS via une API.

Le fait que ces deux éléments du projet agissent de façon complètement indépendante l'un de l'autre a été un facteur clé dans le choix de cette infrastructure. Si vous recherchez une architecture pour mélanger différentes ressources indépendantes sans aucune dépendance, cette approche mérite le détour.

J'ai bien peur de ne pas être un mec Ruby donc je ne peux pas commenter les autres approches. Parfois, c'est correct de prendre un risque. D'autres fois, il vaut mieux jouer prudemment. Vous vous connaîtrez en fonction du type de projet.

Bonne chance avec votre choix ici. Désireux de voir ce que les autres partagent également.

Iarfhlaith Kelly
la source
1
Donc, vous détectez si la demande provient d'un bot de recherche, et diffusez du HTML pré-rendu si c'est le cas, et des modèles JS + si ce n'est pas le cas?
Shannon
4

J'aime # 3 lorsque mon site Web ne sera pas une implémentation 100% CRUD de mes données. Ce qui n'est pas encore arrivé.

Je préfère sinatra et je vais simplement diviser l'application en quelques applications rack différentes à des fins différentes. Je vais créer une application rack spécifique à l'API qui couvrira ce dont j'ai besoin pour l'API. Ensuite, peut-être une application de rack utilisateur qui présentera ma page Web. Parfois, cette version interroge l'API si nécessaire, mais généralement elle ne concerne que le site html.

Je ne m'en fais pas et je fais juste une requête de couche de persistance du côté utilisateur si j'en ai besoin. Je ne suis pas trop préoccupé par la création d'une séparation complète car ils finissent généralement par servir à des fins différentes.

Voici un exemple très simple d'utilisation de plusieurs applications en rack. J'ai ajouté un exemple rapide de jquery là-bas pour que vous puissiez le voir frapper l'application API. Vous pouvez voir à quel point cela peut être simple avec sinatra et monter plusieurs applications de rack à des fins différentes.

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

Poussiéreux
la source
1

Quelques bonnes réponses ici déjà - je recommanderais certainement # 2 ou # 3 - la séparation est bonne conceptuellement mais aussi dans la pratique.

Il peut être difficile de prédire des éléments tels que les modèles de charge et de trafic sur une API et les clients que nous voyons qui servent l'API indépendamment ont un temps de provisionnement et de mise à l'échelle plus facile. Si vous devez faire cela avec des modèles d'accès Web humain, c'est moins facile. De plus, votre utilisation de l'API pourrait finir par évoluer beaucoup plus rapidement que votre client Web et vous pourrez alors voir où diriger vos efforts.

Entre # 2 # 3, cela dépend vraiment de vos objectifs - je conviens que # 2 est probablement l'avenir des webapps - mais peut-être que vous voulez quelque chose de plus simple si ce canal ne sera que l'un des nombreux!

Steve
la source
1

Pour atyourservice.com.cy, nous utilisons des modèles de rendu côté serveur pour les pages, en particulier pour couvrir la partie en question. Et en utilisant l'API pour les interactions après le chargement des pages. Puisque notre framework est MVC, toutes les fonctions du contrôleur sont dupliquées en sortie json et en sortie html. Les modèles sont propres et ne reçoivent qu'un objet. Cela peut être transformé en modèles js en quelques secondes. Nous maintenons toujours les modèles côté serveur et reconvertissons simplement en js sur demande.

xatzistnr
la source
1

Rendu isomorphe et amélioration progressive. C'est à cela que je pense que vous vous dirigiez dans l'option trois.

le rendu isomorphe signifie utiliser le même modèle pour générer du balisage côté serveur que vous utilisez dans le code côté client. Choisissez un langage de modèles avec de bonnes implémentations côté serveur et côté client. Créez du code HTML entièrement cuit pour vos utilisateurs et envoyez-le sur le fil. Utilisez également la mise en cache.

L'amélioration progressive signifie commencer à faire l'exécution côté client et le rendu et l'écoute des événements une fois que toutes les ressources ont été téléchargées et que vous pouvez déterminer les capacités d'un client. Revenir à la fonctionnalité fonctionnelle sans script client dans la mesure du possible pour l'accessibilité et la compatibilité descendante.

Oui, bien sûr, écrivez une API json autonome pour cette fonctionnalité d'application. Mais n'allez pas si loin que vous écrivez une api json pour les choses qui fonctionnent bien en tant que documents html statiques.

sirtimbly
la source
1

Serveur REST + client lourd en JavaScript était le principe que j'ai suivi dans mes récents travaux.

Le serveur REST a été implémenté dans node.js + Express + MongoDB (très bonnes performances d'écriture) + Mongoose ODM (idéal pour la modélisation des données, validations incluses) + CoffeeScript (j'irais maintenant ES2015 à la place) qui a bien fonctionné pour moi. Node.js était peut-être relativement jeune par rapport à d'autres technologies côté serveur possibles, mais cela m'a permis d'écrire une API solide avec des paiements intégrés.

J'ai utilisé Ember.js comme framework JavaScript et la plupart de la logique d'application a été exécutée dans le navigateur. J'ai utilisé SASS (SCSS spécifiquement) pour le pré-traitement CSS.

Ember est un cadre mature soutenu par une communauté forte. Il s'agit d'un framework très puissant avec beaucoup de travail effectué récemment axé sur les performances, comme le tout nouveau moteur de rendu Glimmer (inspiré de React).

Ember Core Team est en train de développer FastBoot , qui vous permet d'exécuter votre logique JavaScript Ember côté serveur (node.js en particulier) et d'envoyer du HTML pré-rendu de votre application (qui serait normalement exécuté dans le navigateur) à l'utilisateur. C'est génial pour le référencement et l'expérience utilisateur car il n'attend pas si longtemps pour que la page soit affichée.

Ember CLI est un excellent outil qui vous aide à organiser votre code et il a bien fonctionné pour évoluer avec une base de code croissante. Ember a également son propre écosystème d'addons et vous pouvez choisir parmi une variété d' addons Ember . Vous pouvez facilement récupérer Bootstrap (dans mon cas) ou Foundation et l'ajouter à votre application.

Pour ne pas tout servir via Express, j'ai choisi d'utiliser nginx pour servir des images et un client JavaScript lourd. L'utilisation du proxy nginx a été utile dans mon cas:

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: J'aime la séparation de l'API et du client. Les gens intelligents disent que c'est la voie à suivre. Génial en théorie. Semble de pointe et passionnant.

Je peux dire que c'est aussi très bien dans la pratique. Un autre avantage de la séparation de l'API REST est que vous pouvez la réutiliser ultérieurement pour d'autres applications. Dans un monde parfait, vous devriez pouvoir utiliser la même API REST non seulement pour la page Web, mais aussi pour les applications mobiles si vous décidez d'en écrire une.

Con: Pas beaucoup de précédents. Pas beaucoup d'exemples de cela bien fait. Les exemples publics (twitter.com) se sentent lents et s'éloignent même de cette approche.

Les choses semblent différentes maintenant. Il existe de nombreux exemples d'utilisation de l'API REST + de nombreux clients qui la consomment.

Daniel Kmak
la source
1

J'ai décidé d'opter pour l'architecture de l'option n ° 2 pour Infiniforms , car elle offrait un excellent moyen de séparer l'interface utilisateur de la logique métier.

Un avantage de ceci est que les serveurs API peuvent évoluer indépendamment des serveurs Web. Si vous avez plusieurs clients, les sites Web n'auront pas besoin d'évoluer dans la même mesure que les serveurs Web, car certains clients seront basés sur un téléphone / une tablette ou un ordinateur.

Cette approche vous donne également une bonne base pour ouvrir votre API à vos utilisateurs, surtout si vous utilisez votre propre API pour fournir toutes les fonctionnalités de votre site Web.

Karl Gjertsen
la source
1

Une très belle question et je suis surpris car je pensais que c'est une tâche très courante de nos jours, de sorte que j'aurai beaucoup de ressources pour ce problème, mais il s'est avéré que ce n'était pas vrai.

Mes pensées sont les suivantes: - Créez un module qui a la logique commune entre les contrôleurs API et les contrôleurs HTML sans retourner json ou rendre le HTML, et inclure ce module dans le contrôleur HTML et le contrôleur API, puis faites ce que vous voulez, donc par exemple :

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

la source
0

J'ai opté pour une approche hybride où nous utilisons Sinatra comme base, ActiveRecord / Postgress, etc. pour proposer des itinéraires de page (modèles minces) exposant une API REST que l'application Web peut utiliser. Dans les premiers stades de développement, comme le remplissage des options de sélection, cela se fait via le rendu des aides dans le modèle mince, mais à l'approche de la production, cela est remplacé par un appel AJAX vers une API REST alors que nous commençons à nous soucier davantage des vitesses de chargement des pages, etc.

Les choses faciles à afficher dans Slim sont traitées de cette façon, et tout (le remplissage des formulaires, la réception de données POST de formulaire de jQuery.Validation, submitHandleretc., est évidemment AJAX)

Les tests sont un problème. En ce moment, je suis perplexe en essayant de passer des données JSON à un test Rack :: Test POST .

Dave Sag
la source
0

Personnellement, je préfère l'option (3) comme solution. Il est utilisé dans à peu près tous les sites qu'un ancien employeur (nom du ménage) a. Cela signifie que vous pouvez obtenir des développeurs front-end qui savent tout sur Javascript, les bizarreries du navigateur et tout le reste pour coder votre front-end. Ils ont seulement besoin de savoir "curl xyz et vous obtiendrez du json" et c'est parti.

Pendant ce temps, vos gars lourds peuvent coder les fournisseurs Json. Ces gars-là n'ont pas du tout besoin de penser à la présentation, et s'inquiètent plutôt des backends floconneux, des délais d'expiration, de la gestion des erreurs gracieuse, des pools de connexions à la base de données, du filetage et de la mise à l'échelle, etc.

L'option 3 vous offre une bonne architecture solide à trois niveaux. Cela signifie que les éléments que vous crachez par l'avant sont compatibles avec le référencement, peuvent fonctionner avec les anciens ou les nouveaux navigateurs (et ceux avec JS désactivé), et peuvent toujours être des modèles Javascript côté client si vous le souhaitez (vous pouvez donc faire des choses comme gérer les anciens navigateurs / googlebot avec du HTML statique, mais envoyer des expériences dynamiques construites par JS aux personnes utilisant le dernier navigateur Chrome ou autre).

Dans tous les cas, j'ai vu l'option 3, il s'agit d'une implémentation personnalisée de PHP qui n'est pas particulièrement transférable entre les projets, sans parler de la terre Open Source. Je suppose que plus récemment, PHP a peut-être été remplacé par Ruby / Rails, mais le même genre de chose est toujours vrai.

FWIW, $ current_employer pourrait faire avec l'option 3 dans quelques endroits importants. Je cherche un bon framework Ruby pour construire quelque chose. Je suis sûr que je peux coller un tas de gemmes, mais je préférerais un seul produit qui fournit largement une solution de mise en cache connectée memcache / nosql en option. Là, je ne trouve rien de cohérent :-(

Ralph Bolton
la source
0

Construire une API JSON dans Rails est de première classe, le joyau JSONAPI :: Resources fait le gros du travail pour une API spécifiée http://jsonapi.org .

pixelhandler
la source