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.
Respostas:
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:
Contras:
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):
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.
fonte
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
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.
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).
fonte
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:
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.
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.
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:
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/
fonte
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.
fonte
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:
(https://github.com/visionmedia/express)
(https://github.com/mikeal/request)
(https://github.com/documentcloud/underscore)
(https://github.com/mikefrey/utml)
(https://github.com/mrDarcyMurphy/upfront)
(https://github.com/visionmedia/express-expose)
(https://github.com/documentcloud/backbone)
Esse é o núcleo da pilha. Alguns outros módulos que achei úteis:
… embora eu esteja olhando para o grunhido (https // github.com / cowboy / grunt)
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)
fonte
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.
fonte
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.
fonte
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.
fonte
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
fonte
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!
fonte
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.
fonte
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.
fonte
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:
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.
As coisas parecem diferentes agora. Existem muitos exemplos de API REST + muitos clientes consumindo-a.
fonte
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.
fonte
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 :
fonte
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,
submitHandler
etc, é obviamente AJAX)Testar é um problema. No momento, estou confuso ao tentar passar dados JSON para um teste Rack :: Test POST .
fonte
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 :-(
fonte
Construir uma API JSON no Rails é de primeira classe. A jóia JSONAPI :: Resources faz o trabalho pesado para uma API especificada em http://jsonapi.org .
fonte