web-dev-qa-db-fra.com

Séparer REST serveur et client d'API JSON?

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 puissent être accessibles à partir de nombreux clients différents: sites Web frontaux, applications pour smartphones, services Web dorsaux, etc. Donc, je veux vraiment une API JSON REST pour chaque.

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

S'il vous plaît, aidez-moi à choisir l'approche à adopter:

ENSEMBLE DANS Rails

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

Pro: Beaucoup de précédents. Grands standards et de nombreux exemples de faire les choses de cette façon.

Con: Ne voulez pas nécessairement que l'API soit identique à l'application Web. Vous n'aimez pas si/alors répondez avec l'approche du commutateur. Mélanger deux choses très différentes (UI + API).

REST SERVER + CLIENT LOURD JAVASCRIPT

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

Pro: J'aime la séparation entre API et client. Les gens intelligents disent que c'est la voie à suivre. Super en théorie. Semble à la fine pointe et excitant.

Con: Pas beaucoup de précédent. Pas beaucoup d'exemples de cela bien fait. Les exemples publics (Twitter.com) semblent lents et abandonnent même cette approche.

REST SERVER + 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 à l'API REST uniquement. Moins de JavaScript côté client.

Pro: J'aime la séparation entre API et client. Mais servir du HTML5 pur est assez infaillible et n’exige pas de client intensif.

Con: Pas beaucoup de précédent. Pas beaucoup d'exemples de cela bien fait. Les cadres ne supportent pas cela aussi. Je ne sais pas comment l'aborder.

Particulièrement à la recherche de conseils d'expérience, pas seulement théoriques.

370
sivers

À Boundless , nous avons opté pour l'option n ° 2 et l'avons étendue à des milliers d'étudiants. Notre serveur est une API JSON REST (Scala + MongoDB), et tout notre code client est servi directement à partir de CloudFront (c'est-à-dire: www.boundless.com n'est qu'un alias pour CloudFront).

Avantages:

  • À la fine pointe/passionnant
  • Beaucoup pour votre argent: L'API vous donne la base de votre propre client Web, clients mobiles, accès tiers, etc.
  • excessivement chargement rapide du site/transitions de page

Les inconvénients:

  • Pas convivial SEO/prêt sans beaucoup plus de travail.
  • Requiert des personnes de premier plan sur le Web qui sont prêtes à faire face à la réalité d’une expérience de site javascript à 70% et ce que cela signifie.

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

Quelques réflexions pour les utilisateurs du Web frontal (qui attribuent cette architecture à toute la nouveauté/défi):

  • CoffeeScript. Beaucoup plus facile de produire un 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 créé un harnais pour notre développement frontal appelé "Spar" (application à page unique Rocketship) qui constitue en réalité le pipeline d'actifs de Rails adapté au développement d'applications à page unique. Notre page github sera ouverte à l’approvisionnement dans les prochaines semaines, 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'ils sont surestimés. Backbone est bien plus un principe d’organisation qu’un cadre profond. Le site Twitter lui-même est une énorme bête de code Javascript couvrant tous les cas d'école de millions d'utilisateurs et de navigateurs traditionnels, tout en chargeant des tweets en temps réel, des collectes de mémoire, des contenus multimédias, etc. De tous les sites "purs" j Vu, Twitter est l'intrus. De nombreuses applications incroyablement complexes livrées via JS se vendent 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 frontaux, investir dans une API autonome est une excellente solution.

135
Aaron

Très bien demandé. +1 C’est certain que c’est pour moi une référence utile pour l’avenir. @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. Le premier pour de nombreuses applications et le second pour mon projet open source Cowoop

Option 1

Celui-ci est sans doute le plus populaire. Mais je trouve que les implémentations sont vraiment http-ish. Le code initial de chaque API traite les objets de requête. Le code de l'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 ainsi que l’option 2 diffère de l’option 3. Mais sont générés en tant que 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 avis, les experts du backend implémentent des API, les testent facilement comme un code de langue habituel sans se soucier du code de requête framework/http.

  • Ce n'est vraiment pas aussi difficile que ça en a l'air. 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 coûteux.

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

Il y a des inconvénients.

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

  • i18n/l10n est difficile. Étant donné que HTML est essentiellement généré, le temps de génération est statique, il faut donc créer plusieurs versions par langage pris en charge (ce qui n’est pas nécessairement une mauvaise chose). Mais même avec cela, il se peut que vous ayez des casses d’angle aux alentours de 10n/11s et que vous deviez faire attention.

Option 3

Dans ce cas, le codage de l’arrière-plan doit être identique à la deuxième option. La plupart des points de l'option 2 sont également applicables ici.

Les pages Web sont rendues à l'exécution à l'aide de modèles côté serveur. Cela facilite beaucoup la manipulation avec des techniques mieux établies/acceptées. Peut être un appel http de moins pour un contexte essentiel nécessaire pour le rendu de la page, tel que l'utilisateur, la langue, la devise, etc. Le traitement côté serveur est augmenté avec le rendu, mais éventuellement compensé par moins d'appels http au serveur API.

Maintenant que les pages sont rendues sur le serveur, l'interface est maintenant davantage liée à l'environnement de programmation. Cela pourrait ne même pas être une considération pour de nombreuses applications.

Cas Twitter

Si je comprends bien, Twitter effectue peut-être leur rendu de page initial sur le serveur, mais pour les mises à jour de page, il existe encore des appels d'API et des modèles côté client permettant de manipuler DOM. Ainsi, dans ce cas, vous devez maintenir des modèles doubles, ce qui ajoute un peu de charge et de complexité. Tout le monde ne peut se permettre cette option, contrairement à Twitter.

Notre projet pile

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

  • Serveur d’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 recommandation

Option 3 !.

Cela dit, j’ai utilisé l’option 2 avec succès, mais j’ai maintenant opté pour l’option 3 pour plus de simplicité. Générer des pages HTML statiques avec un script de compilation et les servir avec un serveur ultra rapide spécialisé dans le traitement de pages statiques est très tentant (option 2).

47
Shekhar

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 l'interface front-end (client javascript).

Avantages:

  1. Se déplacer 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 très facilement simuler l'API et construire 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 la base, 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 est peut-être un site Web, mais il vous permet de créer facilement d’autres clients (iPhone, Android).

Les inconvénients:

  1. Rétrocompatibilité. Ceci est davantage lié à une API qu'à votre question directe, mais une fois que votre API est disponible, vous ne pouvez plus la casser ou casser tous vos clients deux. Cela ne signifie pas que vous devez vous déplacer plus lentement, mais que vous devez souvent faire en sorte que deux choses fonctionnent en même temps. L'ajout à l'API ou à de nouveaux champs est acceptable, mais la modification/suppression ne doit pas être effectuée sans contrôle de version.

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

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

P.S. 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é

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

28
John Nunemaker

Je préfère aller sur la route des n ° 2 et n ° 3. Principalement parce que le n ° 1 viole la séparation des préoccupations et mêle toutes sortes de choses. Vous finirez par avoir besoin d'un point de terminaison API ne comportant pas de page HTML correspondante, etc., et vous serez dans une creek avec des points de terminaison HTML et JSON entremêlés dans la même base de code. Il se transforme en un fouillis monstrueux, même si son MVP, vous devrez le réécrire éventuellement parce que c'est tellement désordonné qu'il ne vaut même pas la peine de le sauver.

Aller avec # 2 ou # 3 vous permet d'avoir complètement une API qui agit de la même manière (dans la plupart des cas) peu importe. Cela offre une grande flexibilité. Je ne suis pas encore vendu à 100% sur Backbone/ember/what/etc.js. Je pense que c'est génial, mais comme nous le voyons avec Twitter, ce n'est pas optimal. MAIS ... Twitter est également une énorme bête d'une entreprise et compte des centaines de millions d'utilisateurs. Toute amélioration peut donc avoir un impact considérable sur le résultat net dans divers domaines de différentes unités fonctionnelles. Je pense que la décision ne se limite pas à la rapidité et qu’ils ne nous laissent pas au courant. Mais c'est juste mon opinion. Cependant, je ne néglige pas Backbone et ses concurrents. Ces applications sont géniales à utiliser, très propres et très réactives (pour la plupart).

La troisième option a aussi un attrait valable. C’est là que je suivrais le principe de Pareto (règle des 80/20) et que 20% de votre balisage principal (ou inversement) seraient restitués sur le serveur, puis un client Nice JS (backbone/etc) exécutera le reste. . Vous ne communiquez peut-être pas à 100% avec l'API REST via le client JS, mais vous travaillerez si nécessaire pour améliorer l'expérience du client.

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 la personne que vous servez et du type d’expérience que vous souhaitez qu’ils acquièrent. Étant donné que je pense que vous pouvez choisir entre 2 ou 3 ou un hybride d'entre eux.

10
Donn Felker

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

J'utilise node.js pour le back-end du client et quelques modules pour m'aider. Je suis un peu tôt dans le processus, mais les bases sont bien établies et il suffit d'examiner les données pour s'assurer que tout est bien rendu. Voici ce que j'utilise:

  • Express pour la fondation de l'application.
    (https://github.com/visionmedia/express)
  • Demande pour récupérer les données.
    (https://github.com/mikeal/request)
  • Soulignez les modèles 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 les modèles et vous permet de choisir ceux qui seront envoyés au client.
    (https://github.com/mrDarcyMurphy/upfront)
  • Express Expose transmet les données extraites, certains modules et les modèles au serveur 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 noyau 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 me penche sur grunt (https // github.com/cowboy/grunt)
  • trace de la console (//github.com/LearnBoost/console-trace).

Non, je n'utilise pas coffeescript.

Cette option fonctionne vraiment 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 présentation dans lequel j'ajoute un seul attribut qui rend le rendu plus intelligent et plus léger. Je n’ai utilisé aucune bibliothèque de modèles sophistiqués à cette fin, mais juste une fonction qui ajoute ce dont j’ai besoin lors de l’initialisation et s’est retournée.

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

7
Darcy Murphy

Nous utilisons la variante suivante de # 3: Créer un serveur API REST JSON uniquement. Faire un serveur de site Web HTML. Le serveur Web HTML n'est pas, comme dans votre variante, un client du serveur d'API REST. Au lieu de cela, les deux sont des pairs. Pas très loin de la surface, une API interne 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'ici (sur le point de passer en version bêta), cela a plutôt bien fonctionné.

7
Thomas Becker

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

J'ai fait une présentation sur cette approche à la dernière 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 deuxième option, vous pouvez essayer pajax comme le fait Github.

7
Matteo Collina

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

Nous avons choisi cette approche pour différentes raisons, mais nous sommes conscients que c'est un peu risqué, car elle n'a pas encore été prouvée à grande échelle. Tout est pareil, tout se passe plutôt bien jusqu'à présent.

Jusqu'à présent, nous travaillons avec une seule API, mais lors de la prochaine phase du projet, nous utiliserons une deuxième API. Le premier concerne de grandes quantités de données et le second se comporte plutôt comme un CMS via une API.

Le fait que ces deux éléments du projet soient totalement indépendants l'un de l'autre était un facteur clé dans le choix de cette infrastructure. Si vous recherchez une architecture pour mashuper 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 Ruby, je ne peux donc pas commenter les autres approches. Parfois, il n'y a pas de mal à prendre des risques. D'autres fois, il vaut mieux jouer la sécurité. Vous allez vous connaître en fonction du type de projet.

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

6
Iarfhlaith Kelly

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

Je préfère sinatra et vais simplement diviser l'application en plusieurs applications en 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 en rack utilisateur qui présentera ma page Web. Parfois, cette version interrogera l'API si nécessaire, mais généralement, elle ne concerne que le site HTML.

Je ne m'inquiète pas pour cela 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 objectifs différents.

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

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

4
Dusty

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

Un avantage de cela est que les serveurs API peuvent évoluer indépendamment des serveurs Web. Si vous avez plusieurs clients, les sites Web n'auront pas besoin de s'adapter à la même étendue que les serveurs Web, car certains clients peuvent être basés sur un téléphone, une tablette ou un ordinateur de bureau.

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.

1
Karl Gjertsen

Une très belle question et je suis étonné car j’ai pensé que c’était une tâche très courante aujourd’hui, de sorte que j’aurais beaucoup de ressources pour faire face à ce problème, même s’il n’est pas vrai.

Mes pensées sont les suivantes: - Créer un module ayant la logique commune entre les contrôleurs API et les contrôleurs HTML sans renvoyer json ou rendre html, et inclure ce module dans le contrôleur HTML et le contrôleur API, puis faites ce que vous voulez, ainsi 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
1
Loai Ghoraba

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

1
xatzistnr

Quelques bonnes réponses ici déjà - je recommanderais certainement les n ° 2 ou 3 - la séparation est bonne sur le plan conceptuel mais aussi dans la pratique.

Il peut être difficile de prévoir 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 de manière indépendante ont plus de facilité à mettre en service et à mettre à l'échelle. Si vous devez faire cela avec de nombreux modèles d'accès Web, c'est moins facile. De plus, l'utilisation de votre API pourrait devenir beaucoup plus rapide que votre client Web et vous pourrez alors voir où diriger vos efforts.

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

1
steve

Rendu isomorphe et amélioration progressive. C'est ce à quoi je pense que vous vous dirigiez dans la troisième option.

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

amélioration progressive signifie commencer à exécuter l’exécution côté client et à rendre le rendu et à écouter les événements une fois que vous avez téléchargé toutes les ressources et que vous pouvez déterminer les capacités du client. Retour à la fonctionnalité fonctionnelle sans script client chaque fois que possible pour l'accessibilité et la compatibilité ascendante.

Oui, bien sûr, écrivez une API json autonome pour cette fonctionnalité de l'application. Mais n'allez pas si loin que vous écrivez une API json pour des choses qui fonctionnent bien comme des documents HTML statiques.

1
sirtimbly

Le serveur REST + client lourd en JavaScript est le principe que j'ai suivi dans mon travail récent.

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 (je choisirais maintenant l'ES2015), ce qui a bien fonctionné pour moi. Node.js est peut-être relativement récent comparé à d’autres technologies côté serveur, mais il m’a permis d’écrire des API solides avec des paiements intégrés.

J'ai utilisé Ember.js comme framework JavaScript et la majeure partie de la logique de l'application a été exécutée dans le navigateur. J'ai utilisé SASS (SCSS en particulier) pour le pré-traitement CSS.

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

Ember Core Team est en train de développer FastBoot , ce qui vous permet d'exécuter votre logique JavaScript Ember sur le côté serveur (node.js en particulier) et d'envoyer le code HTML prédéfini de votre fichier. application (qui devrait normalement s'exécuter dans le navigateur) à l'utilisateur. C'est formidable pour le référencement et l'expérience utilisateur, car il n'attend pas si longtemps que la page s'affiche.

Ember CLI est un excellent outil qui vous aide à organiser votre code et qui a bien réussi à s’adapter à l’évolution de la base de code. Ember possède également son propre écosystème d'addon et vous pouvez choisir parmi une variété de Ember Addons . 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 le service des images et le 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 entre API et client. Les gens intelligents disent que c'est la voie à suivre. Super en théorie. Semble à la fine pointe et excitant.

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

Con: Pas beaucoup de précédent. Pas beaucoup d'exemples de cela bien fait. Les exemples publics (Twitter.com) semblent lents et abandonnent même cette approche.

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

1
Daniel Kmak

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

Pendant ce temps, vos utilisateurs très lourds peuvent coder les fournisseurs Json. Ces gars-là n'ont pas besoin de penser à la présentation, mais plutôt de se soucier des backends irréguliers, des délais d'attente, de la gestion des erreurs, des pools de connexion à la base de données, des threads 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 dès le départ sont compatibles avec le référencement, peuvent fonctionner avec les anciens ou les nouveaux navigateurs (et ceux avec JS désactivé), et pourraient toujours être des modèles JavaScript côté client si vous le souhaitez (pour que vous puissiez faire des choses comme gérer les anciens navigateurs/googlebot avec du HTML statique, mais envoyer des expériences dynamiques construites avec JS aux personnes utilisant le dernier navigateur Chrome ou autre).

Dans tous les cas où j'ai vu l'option 3, cela a été une implémentation personnalisée de PHP qui n'est pas particulièrement transférable entre projets, et encore moins sur des terres Open Source. Je suppose que plus récemment PHP a peut-être été remplacé par Ruby/Rails, mais le même type de chose est toujours vrai.

FWIW, $ current_employer pourrait faire avec l’option 3 dans quelques endroits importants. Je cherche un bon Ruby cadre dans lequel construire quelque chose. Je suis sûr que je peux coller un tas de gemmes, mais je préférerais un seul produit qui propose globalement une solution de mise en cache avec modèles, "curling", authentification facultative, memcache/nosql en option. Là je ne trouve rien de cohérent :-(

0
Ralph Bolton

J'ai opté pour une approche hybride dans laquelle nous utilisons Sinatra comme base, ActiveRecord/Postgress, etc. pour servir des routes de page (modèles minces), exposant une API REST utilisable par l'application Web. Au tout début du développement, le remplissage des options de sélection s'effectue via des aides générées dans le modèle réduit, mais à l'approche de la production, il est échangé pour un appel AJAX à une API REST au démarrage. se soucier davantage de la vitesse de chargement des pages, etc.

Ainsi, les éléments faciles à restituer dans Slim sont traités de cette manière (le remplissage des formulaires, la réception du formulaire POST à partir du fichier submitHandler de jQuery.Validation correspond à AJAX).

Le test est un problème. En ce moment, je suis perplexe essayant de transmettre des données JSON à un Rack :: Test POST test .

0
Dave Sag

Construire une API JSON dans Rails est de première classe. La gemme JSONAPI :: Resources fait le gros du travail pour une API http://jsonapi.org spec'd.

0
pixelhandler