Servidor e cliente API REST JSON separados? [fechadas]


371

Estou prestes a criar um monte de aplicativos da web a partir do zero. (Veja http://50pop.com/code para obter uma visão geral.) Gostaria que eles pudessem ser acessados ​​de muitos clientes diferentes: sites front-end, aplicativos para smartphones, serviços da web de back-end, etc. Então, eu realmente quero um API JSON REST para cada um.

Além disso, eu prefiro trabalhar no back-end, então sonho em manter meu foco exclusivamente na API e contratar outra pessoa para criar a interface do usuário front-end, seja um site, iPhone, Android ou outro aplicativo.

Por favor, ajude-me a decidir qual abordagem devo adotar:

JUNTOS NOS TRILHOS

Crie um aplicativo da web Rails muito padrão. No controlador, faça a opção respond_with, para servir JSON ou HTML. A resposta JSON é então minha API.

Pro: Muitos precedentes. Grandes padrões e muitos exemplos de como fazer as coisas dessa maneira.

Contras: não necessariamente quer que a API seja igual ao aplicativo da web. Não goste se / então respon_with alternar abordagem. Misturando duas coisas muito diferentes (UI + API).

SERVIDOR DE DESCANSO + CLIENTE JAVASCRIPT-PESADO

Crie um servidor API REST somente JSON. Use Backbone ou Ember.js para JavaScript do cliente para acessar a API diretamente, exibindo modelos no navegador.

Pro: Adoro a separação entre API e cliente. Pessoas inteligentes dizem que este é o caminho a percorrer. Ótimo em teoria. Parece de ponta e emocionante.

Con: Não há muito precedente. Não há muitos exemplos disso bem-sucedidos. Os exemplos públicos (twitter.com) parecem lentos e até estão se afastando dessa abordagem.

SERVIDOR REST + CLIENTE HTML DO LADO DO SERVIDOR

Crie um servidor API REST somente JSON. Crie um cliente de site HTML básico, que acesse apenas a API REST. Menos JavaScript do lado do cliente.

Pro: Adoro a separação entre API e cliente. Mas servir HTML5 simples é bastante infalível e não exige muito cliente.

Con: Não há muito precedente. Não há muitos exemplos disso bem-sucedidos. Estruturas também não suportam isso. Não tenho certeza de como abordá-lo.

Especialmente procurando conselhos da experiência, não apenas na teoria.


50
geralmente preferimos que perguntas especulativas e conceituais do quadro branco sejam enviadas para programmers.stackexchange.com, enquanto as perguntas aqui no Stack Overflow devem conter o código-fonte real em 99% das vezes. Mas, é uma pergunta bem feita e eu amo o seu trabalho, então isso pode ficar na área cinzenta por enquanto.
Jeff Atwood

2
Alguém tem alguns exemplos / fontes (para entender suas razões) para aqueles que estão se afastando da opção 2?
Víctor López García

12
@frntk O motivo original pelo qual muitas empresas (como o Twitter) faziam clientes Javascript era porque pensavam que seria mais rápido. Agora, eles estão percebendo que é realmente mais lento. Veja engineering.twitter.com/2012/05/... e openmymind.net/2012/5/30/Client-Side-vs-Server-Side-Rendering
Moshe Katz

11
Leia os comentários nos links acima. Muitas das suposições do artigo são refutadas com lógica e experiência.
Ricalsin

11
Estes dias que você gostaria de fazer um backend API JSON seguinte jsonapi.org especificações ... :)
Askar

Respostas:


136

Na Boundless , aprofundamos a opção 2 e a lançamos para milhares de estudantes. Nosso servidor é uma API JSON REST (Scala + MongoDB) e todo o nosso código de cliente é veiculado diretamente do CloudFront (ou seja: www.boundless.com é apenas um alias para o CloudFront).

Prós:

  • De ponta / emocionante
  • Muito dinheiro para você: a API fornece a base para seu próprio cliente da Web, clientes móveis, acesso de terceiros etc.
  • transições de página / carregamento de site extremamente rápidas

Contras:

  • Não é amigável / pronto para SEO sem muito mais trabalho.
  • Requer um front-end de alto nível na Web que esteja pronto para lidar com a realidade de uma experiência no site que é 70% javascript e o que isso significa.

Eu acho que esse é o futuro de todos os aplicativos da web.

Algumas reflexões para o pessoal do front-end da Web (que é onde todo o novo / desafio é dado a essa arquitetura):

  • CoffeeScript. Muito mais fácil produzir código de alta qualidade.
  • Espinha dorsal. Ótima maneira de organizar sua lógica e comunidade ativa.
  • HAMLC. Modelos Haml + CoffeeScript => JS.
  • SASS

Criamos um equipamento para o nosso desenvolvimento front-end chamado 'Spar' (Single Page App Rocketship), que é efetivamente o canal de ativos do Rails ajustado para o desenvolvimento de aplicativos de página única. Estaremos de código aberto nas próximas semanas em nossa página do github , juntamente com uma postagem no blog explicando como usá-lo e a arquitetura geral em mais detalhes.

ATUALIZAR:

Com relação às preocupações das pessoas com o Backbone, acho que elas são supervalorizadas. A espinha dorsal é muito mais um princípio organizacional do que uma estrutura profunda. O site do Twitter em si é um monstro gigante de Javascript, cobrindo todos os cantos de milhões de usuários e navegadores herdados, enquanto carrega tweets em tempo real, coleta de lixo, exibe muita multimídia, etc. De todos os sites js 'puros' que já visto, o Twitter é o mais estranho. Houve muitos aplicativos impressionantemente complicados entregues via JS que se saem muito bem.

E sua escolha de arquitetura depende inteiramente de seus objetivos. Se você está procurando a maneira mais rápida de oferecer suporte a vários clientes e ter acesso a bons talentos de front-end, investir em uma API autônoma é um ótimo caminho a percorrer.


11
Um pequeno ponto a acrescentar: Embora eu tenha criado apenas a opção 1, conheço vários desenvolvedores de aplicativos para dispositivos móveis que estão começando a usar o parse.com como back-end, a fim de permitir um caminho rápido para a segunda posição.
precisa saber é o seguinte

Coisas como Parse e Kinvey são muito interessantes, não posso dizer que tive a chance de jogar com elas ainda. Depende se o seu valor está na frente ou atrás da pilha suponho
Aaron

Eu uso a mesma abordagem com spinejs para o frontend.
Nicolas Goy

Como você lida com um único domínio executando dois aplicativos separados? Por exemplo. Eu tenho www.mysite.com e quero expor uma API pública e servir um front-end nesse URL. De acordo com os princípios REST, mysite.com/product/24 acessado a partir de um navegador da Web deve retornar uma página HTML observando o cabeçalho HTTP Accept, e um GET com JSON no cabeçalho Accept em mysite.com/product/24 deve retornar JSON .
11113 Erich

Como o AngularJS se destacaria nisso?
Ankan-Zerob

48

Muito bem perguntado. +1. Com certeza, esta é uma referência útil futura para mim. Também @Aaron e outros agregaram valor à discussão. Como Ruby, essa pergunta é igualmente aplicável a outros ambientes de programação.

Eu usei as duas primeiras opções. Primeiro para inúmeras aplicações e segundo para o meu projeto de código aberto Cowoop

Opção 1

Este é sem dúvida o mais popular. Mas acho que a implementação é muito http-ish. O código inicial de cada API trata do objeto de solicitação. Portanto, o código da API é mais do que puro código de ruby ​​/ python / outro idioma.

opção 2

Eu sempre amei isso.

Essa opção também implica que o HTML não é gerado em tempo de execução no servidor. É assim que a opção 2 é diferente da opção 3. Mas são construídas como html estático usando um script de construção. Quando carregado no lado do cliente, esse HTML chamaria o servidor API como cliente da API JS.

  • A separação de preocupações é uma grande vantagem. E muito para o seu gosto (e o meu) especialistas em back-end implementam APIs de back-end, teste-as facilmente como o código de linguagem usual sem se preocupar com o código de solicitação de estrutura / http.

  • Isso realmente não é tão difícil quanto parece no lado da interface. As chamadas de API e os dados resultantes (principalmente json) estão disponíveis para o modelo do lado do cliente ou MVC.

  • Menos processamento no lado do servidor. Isso significa que você pode optar por hardware comum / servidor mais barato.

  • Mais fácil para testar camadas de forma independente, mais fácil para gerar documentos da API.

Tem algumas desvantagens.

  • Muitos desenvolvedores consideram isso mais complexo e difícil de entender. Portanto, é provável que a arquitetura seja criticada.

  • i18n / l10n é difícil. Como o HTML é essencialmente gerado, o tempo de construção é estático, é necessário vários builds por idioma suportado (o que não é necessariamente uma coisa ruim). Mas mesmo com isso, você pode ter caixas de esquina em torno de l10n / i18n e precisa ter cuidado.

Opção 3

A codificação de back-end nesse caso deve ser igual à segunda opção. A maioria dos pontos da opção 2 também é aplicável aqui.

As páginas da Web são renderizadas em tempo de execução usando modelos do lado do servidor. Isso torna o i18n / l10n muito mais fácil com técnicas mais estabelecidas / aceitas. Pode ser uma chamada http a menos para algum contexto essencial necessário para a renderização da página, como usuário, idioma, moeda etc. Portanto, o processamento no servidor é aumentado com a renderização, mas possivelmente compensado por menos chamadas http para o servidor API.

Agora que as páginas são renderizadas no servidor, o frontend agora está mais vinculado ao ambiente de programação. Isso pode não ser uma consideração para muitos aplicativos.

Caso do twitter

Pelo que entendi, o Twitter pode renderizar sua página inicial no servidor, mas, para atualizações de página, ainda possui algumas chamadas de API e modelos do lado do cliente para manipular o DOM. Portanto, nesse caso, você tem modelos duplos para manter, o que adiciona alguma sobrecarga e complexidade. Nem todos podem pagar essa opção, ao contrário do Twitter.

Nosso projeto Stack

Eu uso Python. Eu uso o JsonRPC 2.0 em vez do REST. Sugiro o REST, embora goste da ideia do JsonRPC por vários motivos. Eu uso abaixo das bibliotecas. Alguém considerando a opção 2/3 pode achar útil.

  • Servidor de API: Python Uma micro estrutura da Web rápida - Flask
  • Servidor front-end: Nginx
  • MVC do lado do cliente: Knockout.js
  • Outras ferramentas / bibliotecas relevantes:

Minha conclusão e recomendação

Opção 3 !.

No entanto, usei a opção 2 com sucesso, mas agora me inclino para a opção 3 por alguma simplicidade. Gerar páginas HTML estáticas com script de construção e servi-las com um servidor ultrarrápido especializado em servir páginas estáticas é muito tentador (Opção 2).


Também gosto da opção 2, mas a opção 3 tem muitas vantagens das quais não podemos nos livrar. Estou tentando encontrar alguma solução hidrídica combinando opt2 + opt3, mas isso causará dor de cabeça como o Twitter.
Blue Smith

Adoro a opção 3 e pretendo usá-la para um projeto atual. Algum repositório eg ou git para o qual você pode pedir ajuda?
AmaChefe

@AmaChefe eu desejo. Para o projeto atual em que o SEO é crucial, usamos a opção 3. Mas o código não é de código aberto. Usamos flask + jinja2 e knockout / react.js.
Shekhar

28

Optamos por # 2 ao criar gaug.es. Eu trabalhei na API (ruby, sinatra etc.) e meu parceiro de negócios, Steve Smith, trabalhou no front-end (cliente javascript).

Prós:

  1. Mova-se rapidamente em paralelo. Se eu trabalhasse à frente de Steve, poderia continuar criando APIs para novos recursos. Se ele trabalhasse à minha frente, ele poderia falsificar a API com muita facilidade e criar a interface do usuário.

  2. API de graça. Ter acesso aberto aos dados no seu aplicativo está rapidamente se tornando um recurso padrão. Se você começar com uma API desde o início, poderá obtê-lo gratuitamente.

  3. Separação limpa. É melhor pensar no seu aplicativo como uma API com os clientes. Certamente, o primeiro e mais importante cliente pode ser um usuário da Web, mas o configura para criar facilmente outros clientes (iPhone, Android).

Contras:

  1. Compatibilidade com versões anteriores. Isso está mais relacionado a uma API do que à sua pergunta direta, mas uma vez que sua API está disponível, você não pode simplesmente quebrá-la ou quebrar todos os seus clientes. Isso não significa que você precise se mover mais devagar, mas significa que você deve fazer duas coisas funcionarem ao mesmo tempo. Adicionar à API ou novos campos é bom, mas a alteração / remoção não deve ser feita sem o controle de versão.

Não consigo mais pensar em contras agora.

Conclusão: o cliente API + JS é o caminho a seguir, se você planeja liberar uma API.

PS: Eu recomendaria também documentar completamente sua API antes de liberá-la. O processo de documentação da API do Gaug.es realmente nos ajudou

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


13
Posso perguntar como você autentica o front-end da web com a API REST? Vi que você precisa de uma chave de API para se comunicar com a API obtida através do login no seu perfil de usuário. Mas como o cliente da Web obtém sua chave de API, se é que você me entende?
Sebastian Wramba

@SebastianWramba Está atrasado, mas desde que seu comentário recebeu 12 votos positivos ... eu consideraria algo como a autorização de senha do OAuth2 . Se você é o criador do aplicativo que está chamando a API, esta é a abordagem que você provavelmente deseja, pois ela não usa a chave da API diretamente. Se for um aplicativo de terceiros, você tem o login do usuário no seu site para obter a chave da API e, em seguida, o usuário usa essa chave (e quaisquer outras credenciais necessárias) para acessar a API pelo aplicativo, site etc.
GreeKatrina

10

Eu prefiro seguir a rota dos nºs 2 e 3. Principalmente porque o nº 1 viola a separação de preocupações e mistura todos os tipos de coisas. Eventualmente, você encontrará a necessidade de ter um ponto de extremidade da API que não tenha uma página HTML correspondente / etc e estará em um riacho com pontos de extremidade HTML e JSON misturados na mesma base de código. Ele se transforma em uma bagunça, mesmo que seja seu MVP, você terá que reescrevê-lo eventualmente, porque é tão bagunçado que nem vale a pena salvar.

Seguir com os nºs 2 e 3 permite que você tenha completamente uma API que age da mesma maneira (na maior parte), independentemente. Isso fornece grande flexibilidade. Ainda não estou 100% vendido no Backbone / ember / Whatever / etc.js. Eu acho ótimo, mas como vemos no twitter, isso não é o ideal. MAS ... O Twitter também é um grande animal de uma empresa e tem centenas de milhões de usuários. Portanto, qualquer melhoria pode ter um enorme impacto nos resultados em várias áreas de várias unidades de negócios. Eu acho que há mais na decisão do que velocidade sozinha e eles não estão nos deixando entrar nisso. Mas isso é apenas a minha opinião. No entanto, não desisto do backbone e de seus concorrentes. Esses aplicativos são ótimos de usar e são muito limpos e muito responsivos (na maior parte).

A terceira opção também tem algum fascínio válido. É aqui que eu sigo o princípio de Pareto (regra 80/20) e tenho 20% da sua marcação principal (ou vice-versa) processada no servidor e depois tenho um bom cliente JS (backbone / etc) executando o resto . Você pode não estar se comunicando 100% com a API REST por meio do cliente JS, mas estará realizando algum trabalho, se necessário, para melhorar a experiência do usuário.

Acho que esse é um desses tipos de problemas "depende" e a resposta é "depende" do que você está fazendo, a quem está servindo e que tipo de experiência deseja que eles recebam. Dado que acho que você pode decidir entre 2 ou 3 ou um híbrido deles.


+1 ao híbrido de 2 e 3
Ujjwal Ojha

7

Atualmente, estou trabalhando na conversão de um enorme CMS da opção 1 para a opção 3, e está indo bem. Optamos por renderizar a marcação no lado do servidor, porque o SEO é muito importante para nós e queremos que os sites tenham um bom desempenho em telefones celulares.

Estou usando o node.js para o back-end do cliente e alguns módulos para me ajudar. Estou um pouco adiantado no processo, mas a base está definida e é uma questão de revisar os dados para garantir que tudo fique correto. Aqui está o que estou usando:

  • Expresse para a fundação do aplicativo.
    (https://github.com/visionmedia/express)
  • Pedido para buscar os dados.
    (https://github.com/mikeal/request)
  • Sublinhe os modelos que são renderizados no lado do servidor. Eu os reutilizo no cliente.
    (https://github.com/documentcloud/underscore)
  • O UTML agrupa os modelos de sublinhado para fazê-los funcionar com o Express.
    (https://github.com/mikefrey/utml)
  • O Upfront coleta modelos e permite que você escolha quais serão enviados ao cliente.
    (https://github.com/mrDarcyMurphy/upfront)
  • O Express Expose passa os dados buscados, alguns módulos e modelos para o front-end.
    (https://github.com/visionmedia/express-expose)
  • O backbone cria modelos e visualizações no front-end após engolir os dados que foram repassados.
    (https://github.com/documentcloud/backbone)

Esse é o núcleo da pilha. Alguns outros módulos que achei úteis:

  • fleck (https // github.com / trek / fleck)
  • moment (https // github.com / timrwood / moment)
  • caneta (https // github.com / LearnBoost / caneta)
  • smoosh (https // github.com / fat / smoosh)
    … embora eu esteja olhando para o grunhido (https // github.com / cowboy / grunt)
  • rastreio do console (//github.com/LearnBoost/console-trace).

Não, não estou usando o coffeescript.

Esta opção está funcionando muito bem para mim. Os modelos no back-end são inexistentes porque os dados que obtemos da API são bem estruturados e estou transmitindo-os literalmente para o front-end. A única exceção é o nosso modelo de layout, onde adiciono um único atributo que torna a renderização mais inteligente e mais leve. Eu não usei nenhuma biblioteca de modelos sofisticada para isso, apenas uma função que adiciona o que eu preciso na inicialização e retorna ela mesma.

(desculpe pelos links estranhos, eu sou muito n00b para o estouro de pilha para permitir que eu publique tantos)


11
Então você está processando a marcação no servidor, mas ainda está dando modelos ao cliente e usando o Backbone?
21712 Shannon

7

Usamos a seguinte variante do n.º 3: Crie um servidor de API REST somente em JSON. Faça um servidor de site HTML. O servidor da Web HTML não é, como na sua variante, um cliente para o servidor da API REST. Em vez disso, os dois são colegas. Não muito abaixo da superfície, há uma API interna que fornece a funcionalidade que os dois servidores precisam.

Não temos conhecimento de nenhum precedente, por isso é meio experimental. Até agora (prestes a entrar na versão beta), funcionou muito bem.


Estou pensando nessa opção para evitar alguns problemas relacionados a ser um cliente de API adequado, como autenticação. Gostaria de saber mais sobre como você estruturou tudo e como gerencia a separação e a comunicação entre as três partes diferentes. Existe algo que eu possa ler? Obrigado!
11789

2
@MartinodF Hospedamos no Google App Engine, que limita a Java ou Python. Queria usar o Python, mas fomos forçados a Java porque processamos números (não é possível estender o Py com C / C ++ no GAE). Escolhemos Stripes (Stripes, não Struts, não Spring) para a estrutura da apresentação. Muito feliz com isso. A coisa toda é um aplicativo Java no GAE. A funcionalidade principal é implementada em vários pacotes Java e exposta em uma API interna. Há um servlet que fornece o serviço JSON REST e outro configurado como um aplicativo da Web Stripes. Como é um aplicativo GAE Java, a comunicação é trivial.
Thomas Becker

Obrigado pela compreensão, é muito útil!
precisa

7

Normalmente, estou optando pela segunda opção, usando o Rails para criar a API e o backbone para o material JS. Você pode até obter um painel de administração gratuitamente usando o ActiveAdmin . Enviei dezenas de aplicativos móveis com esse tipo de back-end. No entanto, depende muito se o seu aplicativo é interativo ou não.

Fiz uma apresentação sobre essa abordagem no último RubyDay.it : http://www.slideshare.net/matteocollina/enter-the-app-era-with-ruby-on-rails-rubyday

Para a terceira opção, para obter a capacidade de resposta da segunda, convém experimentar o pijama como o Github.


6

Estou com cerca de 2 meses em um projeto de 3 meses que adota a segunda abordagem que você descreveu aqui. Usamos um servidor RESTful API com backbone.js na frente. O Handlebars.js gerencia os modelos e o jQuery manipula a manipulação de AJAX e DOM. Para navegadores mais antigos e aranhas de busca, voltamos à renderização no servidor, mas estamos usando os mesmos modelos HTML do front-end do Handlebars usando o Mozilla Rhino.

Escolhemos essa abordagem por diversos motivos, mas sabemos que é um pouco arriscado, pois ainda não foi comprovado em larga escala. Mesmo assim, tudo está indo muito bem até agora.

Até agora, estamos trabalhando com uma API, mas na próxima fase do projeto, trabalharemos com uma segunda API. O primeiro é para grandes quantidades de dados e o segundo atua mais como um CMS por meio de uma API.

Ter essas duas partes do projeto completamente independentes uma da outra foi uma consideração importante na seleção dessa infraestrutura. Se você está procurando uma arquitetura para mascarar diferentes recursos independentes sem nenhuma dependência, vale a pena dar uma olhada nessa abordagem.

Receio não ser um cara Ruby, então não posso comentar sobre outras abordagens. Às vezes, não há problema em correr um risco. Outras vezes, é melhor jogar pelo seguro. Você vai se conhecer, dependendo do tipo de projeto.

Boa sorte com sua escolha aqui. Ansioso para ver o que os outros compartilham também.


11
Então, você detecta se a solicitação é proveniente de um bot de pesquisa e exibe HTML pré-renderizado, se for, e modelos JS +, se não for?
Shannon

4

Gosto de # 3 quando meu site não será uma implementação 100% CRUD dos meus dados. O que ainda está para acontecer.

Eu prefiro o sinatra e apenas dividirei o aplicativo em alguns aplicativos diferentes de rack com propósitos diferentes. Vou fazer um aplicativo de rack específico da API que cubra o que eu preciso para a API. Talvez um aplicativo de rack de usuário que apresente minha página da web. Às vezes, essa versão consulta a API, se necessário, mas geralmente se preocupa apenas com o site html.

Não me preocupo com isso e apenas faço uma consulta da camada de persistência do lado do usuário, se eu precisar. Não estou muito preocupado em criar uma separação completa, pois eles geralmente acabam servindo a propósitos diferentes.

Aqui está um exemplo muito simples do uso de vários aplicativos de rack. Adicionei um exemplo rápido de jquery para você ver o aplicativo API. Você pode ver como pode ser simples com o sinatra e montar vários aplicativos de rack com diferentes propósitos.

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


1

Algumas ótimas respostas aqui já - eu recomendaria definitivamente o número 2 ou o número 3 - a separação é boa conceitualmente, mas também na prática.

Pode ser difícil prever coisas como padrões de carga e tráfego em uma API e os clientes que vemos que servem a API independentemente têm um tempo mais fácil de provisionamento e dimensionamento. Se você precisar fazer isso com padrões de acesso à Web humanos, é menos fácil. Além disso, o uso da API pode acabar aumentando muito mais rapidamente que o seu cliente da Web e você pode ver para onde direcionar seus esforços.

Entre o # 2 # 3, realmente depende dos seus objetivos - eu concordo que o # 2 é provavelmente o futuro dos webapps - mas talvez você queira algo mais direto se esse canal for apenas um dentre muitos!


1

Para atyourservice.com.cy, estamos usando modelos renderizados no servidor para páginas especialmente para cobrir a parte em si. E usando a API para interações após o carregamento da página. Como nossa estrutura é MVC, todas as funções do controlador são duplicadas nas saídas json e html. Os modelos são limpos e recebem apenas um objeto. Isso pode ser transformado em modelos js em segundos. Sempre mantemos os modelos do lado do servidor e apenas reconvertemos para js, mediante solicitação.


1

Renderização isomórfica e aprimoramento progressivo. É para isso que acho que você estava indo na opção três.

renderização isomórfica significa usar o mesmo modelo para gerar marcação do lado do servidor usado no código do cliente. Escolha um idioma de modelo com boas implementações do lado do servidor e do cliente. Crie um html totalmente pronto para seus usuários e envie-o pelo ar. Use o cache também.

aprimoramento progressivo significa começar a executar o lado do cliente e renderizar e escutar eventos depois de obter todos os recursos baixados e determinar os recursos de um cliente. Voltando à funcionalidade funcional sem script de cliente sempre que possível para acessibilidade e compatibilidade com versões anteriores.

Sim, é claro, escreva uma API json autônoma para esta funcionalidade do aplicativo. Mas não vá tão longe que você escreve um json api para coisas que funcionam bem como documentos estáticos em html.


1

Servidor REST + cliente pesado em JavaScript foi o princípio que segui em meu trabalho recente.

O servidor REST foi implementado no node.js + Express + MongoDB (desempenho de gravação muito bom) + Mongoose ODM (ótimo para modelagem de dados, validações incluídas) + CoffeeScript (eu usaria o ES2015 agora) que funcionou bem para mim. O Node.js pode ser relativamente jovem em comparação com outras possíveis tecnologias do lado do servidor, mas possibilitou a criação de uma API sólida com pagamentos integrados.

Eu usei o Ember.js como estrutura JavaScript e a maior parte da lógica do aplicativo foi executada no navegador. Eu usei o SASS (especificamente o SCSS) para pré-processamento de CSS.

O Ember é uma estrutura madura apoiada por uma comunidade forte. É uma estrutura muito poderosa, com muito trabalho sendo feito recentemente focado no desempenho, como o novíssimo mecanismo de renderização Glimmer (inspirado no React).

A equipe do Ember Core está desenvolvendo o FastBoot , que permite executar a lógica do JavaScript Ember no lado do servidor (especificamente node.js) e enviar HTML pré-renderizado do seu aplicativo (que normalmente seria executado no navegador) ao usuário. É ótimo para SEO e experiência do usuário, pois ele não espera muito tempo para que a página seja exibida.

O Ember CLI é uma ótima ferramenta que ajuda você a organizar seu código e foi bem dimensionada com o crescimento da base de código. Ember tem também seu próprio ecossistema addon e você pode escolher entre uma variedade de Ember Complementos . Você pode facilmente pegar o Bootstrap (no meu caso) ou o Foundation e adicioná-lo ao seu aplicativo.

Para não servir tudo via Express, eu escolhi usar o nginx para servir imagens e clientes pesados ​​em JavaScript. Usar o proxy nginx foi útil no meu caso:

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: Adoro a separação entre API e cliente. Pessoas inteligentes dizem que este é o caminho a percorrer. Ótimo em teoria. Parece de ponta e emocionante.

Eu posso dizer que também é ótimo na prática. Outra vantagem da separação da API REST é que você pode reutilizá-la posteriormente para outros aplicativos. No mundo perfeito, você deve poder usar a mesma API REST não apenas para páginas da Web, mas também para aplicativos móveis, se decidir escrever uma.

Con: Não há muito precedente. Não há muitos exemplos disso bem-sucedidos. Os exemplos públicos (twitter.com) parecem lentos e até estão se afastando dessa abordagem.

As coisas parecem diferentes agora. Existem muitos exemplos de API REST + muitos clientes consumindo-a.


1

Decidi optar pela arquitetura da opção 2 para o Infiniforms , pois fornecia uma ótima maneira de separar a interface do usuário da lógica de negócios.

Uma vantagem disso é que os servidores de API podem ser dimensionados independentemente dos servidores da web. Se você tiver vários clientes, os sites não precisarão ser escalados na mesma extensão que os servidores da Web, pois alguns clientes serão baseados em telefone / tablet ou desktop.

Essa abordagem também fornece uma boa base para abrir sua API para seus usuários, especialmente se você usar sua própria API para fornecer toda a funcionalidade do seu site.


1

Uma pergunta muito boa e estou surpreso, pois considerava que hoje em dia é uma tarefa muito comum, de modo que terei muitos recursos para esse problema, mas, no entanto, não foi verdade.

Meus pensamentos são os seguintes: - Crie um módulo que tenha a lógica comum entre os controladores de API e HTML sem retornar json ou renderizar html e inclua esse módulo no controlador de HTML e no controlador de API e faça o que quiser, por exemplo, por exemplo :

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

Eu optei por uma abordagem híbrida, na qual usamos o Sinatra como base, ActiveRecord / Postgress etc. para exibir rotas de página (modelos finos), expondo uma API REST que o aplicativo da web pode usar. No início do desenvolvimento, coisas como preencher opções de seleção são feitas através da ajuda dos renderizadores no modelo slim, mas à medida que nos aproximamos da produção, isso é trocado por uma chamada AJAX para uma API REST quando começamos a nos preocupar mais com a velocidade de carregamento da página e assim por diante.

Coisas fáceis de renderizar no Slim são tratadas dessa maneira e outras coisas (preencher formulários, receber dados POST de formulários do jQuery.Validation, submitHandleretc, é obviamente AJAX)

Testar é um problema. No momento, estou confuso ao tentar passar dados JSON para um teste Rack :: Test POST .


0

Pessoalmente, prefiro a opção (3) como solução. É usado em praticamente todos os sites que um antigo empregador (nome da família) possui. Isso significa que você pode obter alguns desenvolvedores de front-end que sabem tudo sobre Javascript, peculiaridades do navegador e outros enfeites para codificar seu front-end. Eles só precisam saber "curl xyz e você terá um pouco de json" e lá vão eles.

Enquanto isso, seu pessoal pesado de back-end pode codificar os provedores Json. Esses caras não precisam pensar em apresentação e, em vez disso, se preocupam com back-ends esquisitos, tempos limites, tratamento de erros gracioso, pools de conexão com o banco de dados, encadeamento e dimensionamento etc.

A opção 3 fornece uma arquitetura boa e sólida de três camadas. Isso significa que as coisas que você cuspiu no front-end são amigáveis ​​com o SEO, podem funcionar com navegadores antigos ou novos (e aqueles com o JS desativado) e ainda podem ser modelos de Javascript do lado do cliente, se você quiser (para que você possa faça coisas como manipular navegadores antigos / googlebot com HTML estático, mas envie experiências dinâmicas criadas por JS para pessoas que usam o navegador Chrome mais recente ou o que for).

Em todos os casos que vi a Opção 3, tem sido uma implementação personalizada de algum PHP que não é especialmente transferível entre projetos, muito menos em terras de código aberto. Acho que, mais recentemente, o PHP pode ter sido substituído pelo Ruby / Rails, mas o mesmo tipo de coisa ainda é verdade.

FWIW, $ current_employer poderia fazer com a opção 3 em alguns lugares importantes. Estou procurando uma boa estrutura Ruby para construir algo. Tenho certeza de que posso colar uma grande quantidade de gemas, mas preferiria um único produto que ofereça amplamente uma solução de cache conectada ao modelo, 'curling', autenticação opcional e cache memcache / nosql opcional. Não estou conseguindo encontrar algo coerente :-(


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.