ti-enxame.com

REST vs JSON-RPC?

Estou tentando escolher entre REST e JSON-RPC para desenvolver uma API para um aplicativo da web. Qual deles é mais fácil de usar para clientes de API?

Atualização 2015: Eu achei o RESTmais fácil de desenvolver e usar para uma API que é veiculada na Web/HTTP, porque o protocolo HTTP existente e maduro que é compreendido pelo cliente e pelo servidor pode ser aproveitado pela API . Por exemplo, códigos de resposta, cabeçalhos, consultas, corpos de postagem, armazenamento em cache e muitos outros recursos podem ser usados ​​pela API sem nenhum esforço ou configuração adicional.

235
Ali Shakiba

O problema fundamental com o RPC é o acoplamento. Os clientes RPC tornam-se fortemente ligados à implementação de serviços de várias maneiras e torna-se muito difícil alterar a implementação do serviço sem prejudicar os clientes:

  • Os clientes são obrigados a saber nomes de procedimentos;
  • Ordem dos parâmetros de procedimento, tipos e questões de contagem. Não é tão fácil alterar assinaturas de procedimentos (número de argumentos, ordem de argumentos, tipos de argumentos, etc ...) no lado do servidor sem quebrar as implementações do cliente;
  • O estilo RPC não expõe nada além de pontos de extremidade de procedimento + argumentos de procedimento. É impossível para o cliente determinar o que pode ser feito a seguir.

Por outro lado, no estilo REST é muito fácil orientar os clientes incluindo informações de controle em representações (cabeçalhos HTTP + representação). Por exemplo:

  • É possível (e realmente obrigatório) incorporar links anotados com tipos de relação de links que transmitem significados desses URIs;
  • As implementações do cliente não precisam depender de nomes e argumentos de procedimento específicos. Em vez disso, os clientes dependem dos formatos de mensagens. Isso cria a possibilidade de usar bibliotecas já implementadas para determinados formatos de mídia (por exemplo, Atom, HTML, Collection + JSON, HAL etc ...)
  • É possível alterar facilmente os URIs sem interromper os clientes, desde que eles dependam apenas de relações de link registradas (ou de domínio específico);
  • É possível incorporar estruturas semelhantes a formulários nas representações, dando aos clientes a possibilidade de expor essas descrições como recursos da interface do usuário se o usuário final for humano;
  • Suporte para armazenamento em cache é uma vantagem adicional;
  • Códigos de status padronizados;

Existem muito mais diferenças e vantagens no lado REST.

207
ioseb

Eu explorei o problema com algum detalhe e decidi que o REST puro é muito limitante, e o RPC é o melhor, embora a maioria dos meus aplicativos sejam de aplicativos CRUD. Se você se ater ao REST, você eventualmente estará coçando a cabeça imaginando como pode facilmente adicionar outro método necessário à sua API para algum propósito especial. Em muitos casos, a única maneira de fazer isso com REST é criar outro controlador para ele, o que pode complicar o seu programa.

Se você decidir pelo RPC, a única diferença é que você está explicitamente especificando o verbo como parte do URI, que é claro, consistente, com menos bugs e realmente sem problemas. Especialmente se você criar um aplicativo que vá além do simples CRUD, o RPC é o único caminho a ser seguido. Eu tenho outro problema com os puristas RESTful: HTTP POST, GET, PUT, DELETE têm significados definidos em HTTP que foram subvertidos por REST em outras coisas, simplesmente porque se encaixam na maior parte do tempo - mas nem todos do tempo.

Na programação, há muito descobri que tentar usar uma coisa para significar duas coisas vai acontecer em algum momento e te morder. Eu gosto de ter a capacidade de usar POST para quase todas as ações, porque ele fornece a liberdade de enviar e receber dados conforme seu método precisa fazer. Você não pode encaixar o mundo inteiro no CRUD.

156
Bruce Patin

Primeiro, HTTP-REST é uma arquitetura de "transferência de estado representacional". Isso implica muitas coisas interessantes:

  • Sua API será stateless e, portanto, muito mais fácil de projetar (é realmente fácil esquecer uma transição em um autômato complexo) e integrar-se a partes de software independentes.
  • Você será levado a projetar métodos de leitura como seguros , que serão fáceis de armazenar em cache e integrar.
  • Você será levado a criar métodos de escrita como idempotentes , que irão lidar muito melhor com os tempos limite.

Segundo, o HTTP-REST é totalmente compatível com HTTP (veja "seguro" e "idempotente" na parte anterior), portanto você poderá reutilizar bibliotecas HTTP (existentes para cada idioma existente) e proxies reversos HTTP, o que lhe dará a capacidade de implementar recursos avançados (cache, autenticação, compactação, redirecionamento, reescrita, criação de log, etc.) com linha zero de código.

Por último, mas não menos importante, usar HTTP como um protocolo RPC é um grande erro, de acordo com o criador do HTTP 1.1 (e inventor do REST): http://www.ics.uci.edu/~fielding/pubs/ dissertação/avaliação.htm # sec_6_5_2

28
Aurélien

Grandes respostas - só queria esclarecer alguns dos comentários. JSON-RPC é rápido e fácil de consumir, mas como os recursos e parâmetros mencionados são fortemente acoplados e ele tende a depender de verbos (api/deleteUser, api/addUser) usando GET/POST onde-as REST fornece recursos fracamente acoplados (api/users) que em uma API HTTP REST depende de vários métodos HTTP (GET, POST, PUT, PATCH, DELETE). REST é um pouco mais difícil para desenvolvedores inexperientes implementarem, mas o estilo se tornou bastante comum agora e oferece muito mais flexibilidade a longo prazo (dando à API uma vida mais longa).

Além de não ter recursos fortemente acoplados, REST também permite que você evite se comprometer com um único tipo de conteúdo - isso significa que seu cliente precisa receber os dados em XML, JSON ou YAML - se embutido em seu sistema, você poderia retornar qualquer um usando os cabeçalhos de tipo de conteúdo/aceitação.

Isso permite que você mantenha sua API flexível o suficiente para suportar novos tipos de conteúdo OR requisitos do cliente.

Mas o que realmente separa REST do JSON-RPC é que ele segue uma série de restrições cuidadosamente pensadas - assegurando flexibilidade arquitetural. Essas restrições incluem garantir que o cliente e o servidor possam evoluir independentemente um do outro (você pode fazer alterações sem atrapalhar o aplicativo do cliente), as chamadas são sem estado (o estado é representado por hipermídia), uma interface uniforme é fornecida para interações, a API é desenvolvida em um sistema em camadas e a resposta pode ser armazenada em cache pelo cliente. Há também uma restrição opcional para fornecer código sob demanda.

No entanto, com tudo isso dito - a maioria das APIs não são RESTful (de acordo com Fielding), pois não incorporam hipermídia (links de hipertexto incorporados na resposta que ajudam a navegar na API). A maioria das APIs que você descobrirá são semelhantes a REST, pois seguem a maioria dos conceitos de REST, mas ignoram essa restrição. No entanto, mais e mais APIs estão implementando isso e está se tornando mais uma prática de fluxo principal.

Isso também lhe dá alguma flexibilidade, pois APIs orientadas por hipermídia (como o Stormpath) direcionam o cliente para os URIs (ou seja, se algo mudar, em determinados casos que você puder modifique o URI sem impacto negativo), em que as URIs de RPC precisam ser estáticas. Com o RPC, você também precisará documentar extensivamente esses diferentes URIs e explicar como eles funcionam em relação uns aos outros.

Em geral, eu diria que REST é o caminho a percorrer se você deseja construir uma API extensível e flexível que será de longa duração. Por essa razão, eu diria que é o caminho para percorrer 99% do tempo.

Boa sorte, Mike

24
Mike Stowe

Se o seu serviço funcionar bem apenas com modelos e com o padrão GET/POST/PUT/DELETE, use o REST puro.

Eu concordo que o HTTP é originalmente projetado para aplicativos sem estado.

Mas, para aplicações modernas, mais complexas (!) Em tempo real (web), onde você desejará usar Websockets (que geralmente implicam em estado), por que não usar os dois? JSON-RPC sobre Websockets é muito leve, então você tem os seguintes benefícios:

  • Atualizações instantâneas em cada cliente (defina sua própria chamada RPC de servidor para cliente para atualizar os modelos)
  • Fácil de adicionar complexidade (tente fazer um clone do Etherpad com apenas REST)
  • Se você fizer isso certo (adicionar RPC apenas como um extra para tempo real), a maioria ainda pode ser usada com apenas REST (exceto se o recurso principal for um chat ou algo assim)

Como você está projetando apenas a API do lado do servidor, comece definindo os modelos REST e depois adicione suporte JSON-RPC conforme necessário, mantendo o número de chamadas RPC no mínimo.

(e desculpe pelo uso excessivo de parênteses)

17
flo

IMO, o ponto chave é a orientação de ação versus recurso. REST é orientada a recursos e se encaixa bem com operações CRUD e, dada sua semântica conhecida, fornece alguma previsibilidade a um primeiro usuário, mas quando implementada a partir de métodos ou procedimentos, você fornece uma tradução artificial para o mundo centralizado em recursos. Por outro lado, o RPC se adapta perfeitamente às APIs orientadas à ação, nas quais você expõe serviços, e não conjuntos de recursos compatíveis com CRUD.

Sem dúvida REST é mais popular, isso definitivamente adiciona alguns pontos se você quiser expor a API a terceiros.

Se não (por exemplo, no caso de criar um front-end AJAX em um SPA), minha escolha é RPC. Em particular, o JSON-RPC, combinado com o esquema JSON como linguagem de descrição, e transportado por HTTP ou Websockets, dependendo do caso de uso.

JSON-RPC é uma especificação simples e elegante que define payloads JSON de solicitação e resposta a serem usados ​​em RPCs síncronas ou assíncronas.

Esquema JSON é a especificação de rascunho que define um formato baseado em JSON para descrever os dados JSON. Ao descrever suas mensagens de entrada e saída de serviço usando o esquema JSON, você pode ter uma complexidade arbitrária na estrutura da mensagem sem comprometer a usabilidade, e a integração de serviços pode ser automatizada.

A escolha do protocolo de transporte (HTTP vs websockets) depende de diferentes fatores, sendo o mais importante se você precisa de recursos HTTP (cache, revalidação, segurança, idempotência, tipo de conteúdo, multipartes, ...) ou se o aplicativo precisa ser trocado mensagens em altas frequências.

Até agora, é muito minha opinião pessoal sobre o assunto, mas agora algo que pode ser realmente útil para os desenvolvedores Java que leem essas linhas, o framework no qual tenho trabalhado durante o ano passado, nascido da mesma pergunta que você está pensando agora :

http://rpc.brutusin.org

Você pode ver uma demonstração ao vivo aqui, mostrando o navegador de repositório interno para testes funcionais (graças ao JSON Schema) e uma série de exemplos de serviços:

http://demo.rpc.brutusin.org

Espero que ajude mate!

Nacho

16
idelvall

Eu tenho sido um grande fã de REST no passado e tem muitas vantagens sobre o RPC no papel. Você pode apresentar o cliente com diferentes tipos de conteúdo, armazenamento em cache, reutilização de códigos de status HTTP, orientar o cliente por meio da API e incorporar a documentação na API, se ela não for, em sua maioria, autoexplicativa.

Mas a minha experiência tem sido que, na prática, isso não se sustenta e, em vez disso, você faz um monte de trabalho desnecessário para acertar tudo. Além disso, os códigos de status HTTP geralmente não mapeiam a lógica do seu domínio exatamente e usá-los em seu contexto muitas vezes parece um pouco forçado. Mas a pior coisa sobre REST na minha opinião é que você gasta muito tempo para projetar seus recursos e as interações que eles permitem. E sempre que você fizer algumas adições importantes à sua API, você espera encontrar uma boa solução para adicionar a nova funcionalidade e você não se projeta em um canto já.

Isso geralmente parece uma perda de tempo para mim, porque na maioria das vezes eu já tenho uma idéia perfeitamente boa e óbvia sobre como modelar uma API como um conjunto de chamadas de procedimento remoto. E se eu tiver passado por todo esse esforço para modelar meu problema dentro das restrições de REST o próximo problema é como chamá-lo do cliente? Nossos programas são baseados em procedimentos de chamada, portanto construir uma boa biblioteca cliente RPC é fácil, construir uma boa biblioteca cliente REST não muito e na maioria dos casos você irá mapear de volta de REST API no servidor para um conjunto de procedimentos na sua biblioteca de clientes.

Por causa disso, o RPC parece muito mais simples e natural para mim hoje. O que eu realmente sinto falta é uma estrutura consistente que facilita escrever serviços RPC que são auto-descritivos e interoperáveis. Por isso, criei meu próprio projeto para experimentar novas maneiras de tornar o RPC mais fácil para mim e talvez outra pessoa também ache útil: https://github.com/aheck/reflectrpc

15
ahe

De acordo com o modelo de maturidade de Richardson , a questão não é REST vs. RPC , mas quanto REST

Nessa visão, a conformidade com o padrãoREST pode ser classificada em 4 níveis.

  • nível 0: pense em termos de ações e parâmetros. Como o artigo explica, isso é essencialmente equivalente a JSON-RPC (o artigo explica isso para XML-RPC, mas os mesmos argumentos valem para ambos).
  • nível 1: pense em termos de recursos. Tudo o que é relevante para um recurso pertence ao mesmo URL
  • nível 2: use verbos HTTP
  • nível 3: HATEOAS

De acordo com o criador do padrão REST, somente os serviços de nível 3 podem ser chamados de RESTful. No entanto, esta é uma métrica de conformidade , não de qualidade. Se você quiser apenas chamar uma função remota que faz um cálculo, provavelmente não faz sentido ter links hipermídia relevantes na resposta, nem diferenciação de comportamento com base no verbo HTTP usado. Então, uma tal chamada inerentemente tende a ser mais parecida com RPC. No entanto, um nível de conformidade menor não significa necessariamente estado ou acoplamento superior. Provavelmente, em vez de pensar REST vs. RPC , você deve usar tanto REST quanto possível, mas não mais. Não torça seu aplicativo apenas para se adequar aos padrões de conformidade RESTful.

11
blue_note

Por JSON RPC:

No caso de REST apis, temos que definir um controlador para cada funcionalidade/método que possamos precisar. Como resultado, se tivermos 10 métodos que desejamos acessíveis a um cliente, precisamos escrever 10 controladores para fazer a interface da solicitação do cliente com um método específico.

Outro fator é que, apesar de termos controladores diferentes para cada método/funcionalidade, o cliente tem que lembrar de usar POST ou GET. Isso complica ainda mais as coisas. Além disso, para enviar dados, é preciso definir o tipo de conteúdo da solicitação se POST for usado.

No caso do JSON RPC, as coisas são muito simplificadas porque a maioria dos servidores JSONRPC opera nos métodos POST HTTP e o tipo de conteúdo é sempre application/json. Isso elimina a carga de lembrar-se de usar o método HTTP e as configurações de conteúdo adequadas no lado do cliente.

Não é preciso criar controladores separados para diferentes métodos/funcionalidades que o servidor deseja expor a um cliente.

Por que REST:

Você tem URLs separados para diferentes funcionalidades que o servidor deseja expor ao lado do cliente. Como resultado, você pode incorporar essas URLs.

A maioria desses pontos é discutível e depende completamente da necessidade de uma pessoa.

7
Umer Farooq

Eu acho que, como sempre, depende ...

O REST tem a enorme vantagem de amplo suporte público e isso significa muitas ferramentas e livros. Se você precisa criar uma API que seja usada por um grande número de consumidores de organizações diferentes, essa é a maneira de usar apenas um motivo: ela é popular. Como um protocolo, é claro que é uma falha total, pois há muitas maneiras completamente diferentes de mapear um comando para uma URL/verbo/resposta.

Portanto, quando você escreve um aplicativo da web de página única que precisa falar com um backend, acho que o REST é muito complexo. Nessa situação, você não precisa se preocupar com a compatibilidade a longo prazo, pois o aplicativo e a API podem evoluir juntos.

Uma vez eu comecei com REST para um aplicativo da web de página única, mas os comandos refinados entre o aplicativo da web e o servidor rapidamente me deixaram louco. Devo codificá-lo como um parâmetro de caminho? No corpo? Um parâmetro de consulta? Um cabeçalho? Após o design de URL/Verbo/Resposta, eu tive que codificar essa bagunça em Javascript, o decodificador em Java e, em seguida, chamar o método real. Embora existam muitas ferramentas para isso, é realmente complicado não obter nenhuma semântica HTTP em seu código de domínio, o que é uma prática muito ruim. (Coesão)

Tente criar um arquivo Swagger/OpenAPI para um site complexo médio e compare-o a uma única interface Java que descreve os procedimentos remotos nesse arquivo. O aumento da complexidade é impressionante.

Portanto, mudei de REST para JSON-RPC para o aplicativo da Web de página única. aI desenvolveu uma pequena biblioteca que codificava uma interface Java no servidor e a enviava para o navegador. No navegador, isso criou um proxy para o código do aplicativo que retornou uma promessa para cada função.

Novamente, REST tem seu lugar apenas porque é famoso e, portanto, bem suportado. Também é importante reconhecer a filosofia subjacente dos recursos sem estado e o modelo hierárquico. No entanto, esses princípios podem ser facilmente usados ​​em um modelo RPC. O JSON RPC funciona sobre HTTP, portanto, tem as mesmas vantagens de REST nessa área. A diferença é que quando você inevitavelmente se depara com essas funções que não mapeiam bem esses princípios, você não é forçado a fazer um monte de trabalho desnecessário.

2
Peter Kriens

Pergunta errada: impõe um maniqueísta que não existe!

Você pode usar JSON-RPC com "menos verbo" (no método ) e preservar a mínima padronização necessária para ser id, parâmetros, erro códigos e aviso mensagens. O padrão JSON-RPC não diz "você não pode ser REST", apenas informa como compactar informações básicas.

"REST JSON-RPC" existe ! é REST com "melhores práticas", para o mínimo de informações, com contratos simples e sólidos.


Exemplo

(de esta resposta e contexto didático)

Ao lidar com o REST, geralmente ajuda começar pensando em termos de recursos. Nesse caso, o recurso não é apenas "conta bancária", mas é uma transação dessa conta bancária ... Mas o JSON-RPC não obriga o parâmetro "método", todos são codificados pelo "caminho" do terminal.

  • REST Depósito com POST /Bank/Account/John/Transaction com solicitação JSON {"jsonrpc": "2.0", "id": 12, "params": {"currency":"USD","amount":10}}.
    A resposta JSON pode ser algo como {"jsonrpc": "2.0", "result": "sucess", "id": 12}

  • REST Retirar com POST /Bank/Account/John/Transaction ... similar.

  • ... GET /Bank/Account/John/Transaction/[email protected] ... Isso pode retornar um registro JSON dessa transação exata (por exemplo, seus usuários geralmente querem um registro de débitos e créditos em sua conta). Algo como {"jsonrpc": "2.0", "result": {"debits":[...],"credits":[...]}, "id": 13}. A convenção sobre a solicitação GET (REST) ​​pode incluir o código de identificação por "@id", portanto, não é necessário enviar nenhum JSON, mas ainda usar JSON-RPC no pacote de resposta.

2
Peter Krauss

O REST é fortemente acoplado ao HTTP, portanto, se você apenas expor sua API sobre HTTP, o REST é mais apropriado para a maioria das situações (mas não todas). No entanto, se você precisar expor sua API sobre outros transportes, como mensagens ou sockets da Web, REST não será aplicável.

2
dtoux

Se você solicitar recursos, a API RESTful será melhor por design. Se você solicitar alguns dados complicados com muitos parâmetros e métodos complicados que não sejam simples CRUD, o RPC é o caminho certo a seguir.

1
Adrian Liu

Seria melhor escolher JSON-RPC entre REST e JSON-RPC para desenvolver uma API para um aplicativo da Web que seja mais fácil de entender. O JSON-RPC é preferido porque seu mapeamento para chamadas de método e comunicações pode ser facilmente entendido.

A escolha da abordagem mais adequada depende das restrições ou do objetivo principal. Por exemplo, na medida em que o desempenho é uma característica importante, é aconselhável ir para JSON-RPC (por exemplo, High Performance Computing). No entanto, se o objetivo principal é ser agnóstico, a fim de oferecer uma interface genérica a ser inferida por outros, é aconselhável ir para REST. Se os dois objetivos são necessários para serem alcançados, é aconselhável incluir os dois protocolos.

O fato que realmente divide REST do JSON-RPC é que ele segue uma série de restrições cuidadosamente pensadas - confirmando a flexibilidade arquitetural. As restrições consistem em garantir que o cliente e o servidor possam crescer independentemente um do outro (as alterações podem ser feitas sem interferir na aplicação do cliente), as chamadas são sem estado (o estado é considerado hipermídia), um uniforme interface é oferecida para interações, a API é avançada em um sistema em camadas (Hall, 2010). O JSON-RPC é rápido e fácil de consumir, no entanto, como os recursos mencionados e os parâmetros são fortemente acoplados e é provável que dependa de verbos (api/addUser, api/deleteUser) usando GET/POST enquanto REST fornece recursos pouco acoplados (api/users) em um HTTP. REST A API depende de vários métodos HTTP, como GET, PUT, POST, DELETE, PATCH. REST é um pouco mais difícil para desenvolvedores inexperientes implementarem.

JSON (denotado como JavaScript Object Notation), sendo um formato leve de troca de dados, é fácil para os humanos lerem e escreverem. É livre de problemas para máquinas analisar e gerar. JSON é um formato de texto totalmente independente de linguagem, mas pratica convenções que estão familiarizadas com programadores da família de linguagens, consistindo em C #, C, C++, Java, Perl, JavaScript, Python e muitos outros. Essas propriedades tornam o JSON uma linguagem perfeita de intercâmbio de dados e uma melhor opção para optar por.

1
SinghKunal

Eu uso vdata para o protocolo RPC: http://vdata.dekuan.org/

1, PHP e JavaScript estão ambos bem. 2, a chamada de compartilhamento de recursos entre origens (CORS) ainda está bem.

0
Liu Qixing

Eu acho que há um ponto que as pessoas esqueceram de mencionar. Se você já tem um aplicativo da web, REST é desejável, pois precisará do servidor de aplicativos de qualquer forma e poderá proteger ambos usando https ... mas, se não tiver um aplicativo da Web, um aplicativo), o RPC é desejável, pois você não precisa mais configurar um servidor de aplicativos e configurá-lo, o que é um hastle. Fora isso, não vejo nenhuma vantagem fundamental em nenhum dos dois.

0
max