Estou precisando de alguns esclarecimentos. Eu tenho lido sobre o REST e construindo aplicativos RESTful. De acordo com a wikipedia, o próprio REST é definido como Representational State Transfer . Portanto, não entendo todo esse livro apático sem estado que todo mundo continua vomitando.
Da wikipedia:
A qualquer momento específico, um cliente pode estar em transição entre os estados do aplicativo ou "em repouso". Um cliente em um estado de repouso pode interagir com seu usuário, mas não cria carga e não consome armazenamento por cliente no conjunto de servidores ou na rede.
Eles estão dizendo que não usam armazenamento de dados no nível da sessão / aplicativo ???
Entendo que um dos objetivos do REST é tornar o acesso ao URI consistente e disponível, por exemplo, em vez de ocultar solicitações de paginação nas postagens, tornando o número da página de uma solicitação parte do GET URI. Faz sentido para mim. Mas parece que está exagerando dizendo que nenhum dado por cliente (sessão) deve ser armazenado no servidor.
E se eu tivesse uma fila de mensagens e meu usuário quisesse ler as mensagens, mas, ao lê-las, quisesse bloquear certas mensagens de remetentes que chegassem durante a sessão? Não faria sentido armazenar isso em um local no lado do servidor e fazer com que o servidor envie apenas mensagens (ou IDs) que não foram bloqueadas pelo usuário?
Preciso realmente enviar a lista inteira de remetentes para bloquear cada vez que solicitar a nova lista de mensagens? A lista de mensagens pertinente para mim nem deveria ser um recurso disponível ao público em primeiro lugar.
Mais uma vez, apenas tentando entender isso. Alguém por favor, esclareça.
Atualizar:
Eu encontrei uma pergunta de estouro de pilha que tem uma resposta que não me leva a todo o caminho: Como gerenciar o estado no REST, que diz que o estado do cliente que é importante deve ser transferido a cada solicitação ... Ugg .. parece muita sobrecarga ... Isso está certo ??
fonte
Respostas:
Apatridia significa que toda solicitação HTTP acontece em isolamento completo. Quando o cliente faz uma solicitação HTTP, inclui todas as informações necessárias para o servidor atender a essa solicitação. O servidor nunca conta com informações de solicitações anteriores. Se essas informações fossem importantes, o cliente teria que enviá-las novamente em uma solicitação subsequente. A apatridia também traz novos recursos. É mais fácil distribuir um aplicativo sem estado entre servidores com balanceamento de carga. Um aplicativo sem estado também é fácil de armazenar em cache.
Na verdade, existem dois tipos de estado. Estado do Aplicativo que fica no cliente e Estado do Recurso que fica no servidor.
Um serviço da web precisa se preocupar apenas com o estado do seu aplicativo quando você está realmente fazendo uma solicitação. O resto do tempo, nem sabe que você existe. Isso significa que sempre que um cliente faz uma solicitação, ele deve incluir todos os estados do aplicativo que o servidor precisará para processá-la.
O estado do recurso é o mesmo para todos os clientes e seu local apropriado está no servidor. Ao carregar uma imagem em um servidor, você cria um novo recurso: a nova imagem possui seu próprio URI e pode ser o destino de solicitações futuras. Você pode buscar, modificar e excluir este recurso por meio de HTTP.
Espero que isso ajude a diferenciar o que significa apatridia e vários estados.
fonte
A explicação fundamental é:
Por sem estado, significa que o servidor não armazena nenhum estado sobre a sessão do cliente no lado do servidor.
A sessão do cliente é armazenada no cliente. O servidor é sem estado, significa que todo servidor pode atender a qualquer cliente a qualquer momento, não há afinidade de sessão ou sessões permanentes . As informações relevantes da sessão são armazenadas no cliente e transmitidas ao servidor conforme necessário.
Isso não impede que outros serviços com os quais o servidor da Web converse mantenham o estado sobre objetos de negócios, como carrinhos de compras, mas não sobre o estado atual do aplicativo / sessão do cliente.
O estado do aplicativo do cliente nunca deve ser armazenado no servidor, mas passado do cliente para todos os locais que precisam dele.
É daí que o ST no REST vem, Transferência de Estado . Você transfere o estado ao redor, em vez de o servidor armazená-lo. Essa é a única maneira de expandir para milhões de usuários simultâneos. Se não por outro motivo, porque milhões de sessões são milhões de sessões.
A carga do gerenciamento de sessões é amortizada em todos os clientes, os clientes armazenam seu estado de sessão e os servidores podem atender a muitas ordens de magnitude ou mais clientes de maneira apátrida.
Mesmo para um serviço que você acha que precisará apenas nos 10 dos milhares de usuários simultâneos, você ainda deve tornar seu serviço sem estado. Dezenas de milhares ainda são dezenas de milhares e haverá tempo e espaço associados a ele.
Sem estado de estado é como o protocolo HTTP e a Web em geral foram projetados para operar e é uma implementação geral mais simples e você tem um único caminho de código em vez de um monte de lógica do lado do servidor para manter vários estados de sessão.
Existem alguns princípios de implementação muito básicos:
Estes são princípios, não implementações. A forma como você cumpre esses princípios pode variar.
Em resumo, os cinco princípios principais são:
Não há nada sobre autenticação ou autorização na dissertação REST .
Porque não há nada diferente de autenticar uma solicitação que é RESTful de uma que não é. A autenticação é irrelevante para a discussão RESTful.
Explicar como criar um aplicativo sem estado para seus requisitos específicos é muito amplo para o StackOverflow.
A implementação da autenticação e autorização no que diz respeito ao REST é ainda mais abrangente e várias abordagens para implementações são explicadas em detalhes na Internet em geral.
fonte
Não. Eles não estão dizendo isso de uma maneira trivial.
Eles estão dizendo que não definem uma "sessão". Não faça login. Não efetue logout. Forneça credenciais com a solicitação. Cada solicitação fica sozinha.
Você ainda tem repositórios de dados. Você ainda tem autenticação e autorização. Você simplesmente não perde tempo estabelecendo sessões e mantendo o estado da sessão.
O ponto é que cada solicitação (a) fica completamente sozinha e (b) pode ser trivialmente gerida em um farm de servidores paralelos gigante sem nenhum trabalho real. O Apache ou o Squid podem transmitir solicitações RESTful cegamente e com êxito.
Se o usuário desejar um filtro, simplesmente forneça o filtro em cada solicitação.
Sim. Forneça o filtro na solicitação de URI RESTful.
Sim. Qual o tamanho dessa "lista de remetentes de mensagens a serem bloqueadas"? Uma pequena lista de PK's?
Uma solicitação GET pode ser muito grande. Se necessário, você pode tentar uma solicitação POST, mesmo que pareça um tipo de consulta.
fonte
Você está absolutamente certo, oferecer suporte a interações completamente sem estado de estado com o servidor gera um ônus adicional para o cliente. No entanto, se você considerar dimensionar um aplicativo, o poder de computação dos clientes é diretamente proporcional ao número de clientes. Portanto, escalar para um grande número de clientes é muito mais viável.
Assim que você coloca uma pequena responsabilidade no servidor para gerenciar algumas informações relacionadas às interações de um cliente específico, esse ônus pode aumentar rapidamente para consumir o servidor.
É uma troca.
fonte
Visualização histórica do gerenciamento de estado do aplicativo do usuário
As sessões no sentido tradicional mantêm o estado do usuário no aplicativo dentro do servidor. Pode ser a página atual em um fluxo ou o que foi inserido anteriormente, mas ainda não persistiu no banco de dados principal.
O motivo dessa necessidade foi a falta de padrões no lado do cliente para manter efetivamente o estado sem criar aplicativos ou plug-ins específicos do cliente (ou seja, específicos do navegador).
Com o passar do tempo, a solicitação de cabeçalho HTML5 e XML padronizou a noção de armazenamento de dados complexos, incluindo o estado do aplicativo de maneira padrão no lado do cliente (por exemplo, navegador), sem recorrer à alternância entre o servidor.
Uso geral de serviços REST
Os serviços REST são geralmente chamados quando há uma transação que precisa ser executada ou se precisa recuperar dados.
Os serviços REST devem ser chamados pelo aplicativo do lado do cliente e não diretamente pelo usuário final.
Autenticando
Para qualquer solicitação ao servidor, parte da solicitação deve conter o token de autorização. Como é implementado é específico da aplicação, mas em geral é um
BASIC
ouCERTIFICATE
forma de autenticação.A autenticação baseada em formulário não é usada pelos serviços REST. No entanto, conforme observado acima, os serviços REST não devem ser chamados pelo usuário, mas pelo aplicativo. O aplicativo precisa gerenciar a obtenção do token de autenticação. No meu caso, usei cookies com JASPIC com OAuth 2.0 para conectar-me ao Google para autenticação e autenticação HTTP simples para testes automatizados. Também usei autenticação de cabeçalho HTTP via JASPIC para testes locais (embora a mesma abordagem possa ser realizada no SiteMinder)
De acordo com esses exemplos, a autenticação é gerenciada no lado do cliente (embora o SiteMinder ou o Google armazenem a sessão de autenticação), não há nada que possa ser feito sobre esse estado, mas não faz parte do aplicativo de serviço REST.
Solicitações de recuperação
Solicitações de recuperação no REST são
GET
operações nas quais um recurso específico é solicitado e é armazenável em cache. Não há necessidade de sessões do servidor porque a solicitação tem tudo o que seria necessário para recuperar os dados: autenticação e o URI.Scripts de transação
Conforme observado acima, o próprio aplicativo do lado do cliente chama os serviços REST junto com a autenticação que ele gerencia no lado do cliente.
O que isso significa para os serviços REST [se feito corretamente] é levar uma única solicitação ao servidor REST conterá tudo o que é necessário para uma operação de usuário único que faz tudo o que é necessário em uma única transação, um Script de Transação é o padrão é chamado.
Isso é feito através de uma
POST
solicitação normalmente, mas outrasPUT
também podem ser usadas.Muitos exemplos inventados de REST (eu mesmo fiz isso) tentaram seguir o que foi definido no protocolo HTTP, depois de passar por isso, decidi ser mais pragmático e o deixei apenas para GET e POST . O
POST
método nem precisa implementar o padrão POST-REDIRECT-GET.Independentemente disso, como observei acima, o aplicativo do lado do cliente será
POST
o responsável pela chamada do serviço e somente chamará a solicitação com todos os dados quando necessário (nem sempre). Isso evita solicitações constantes para o servidor.Polling
Embora o REST também possa ser usado para pesquisas, não o recomendo, a menos que você precise usá-lo devido à compatibilidade do navegador. Para isso, eu usaria WebSockets para os quais também havia criado um contrato de API . Outra alternativa para navegadores mais antigos é o CometD.
fonte
O REST é muito abstrato. Ajuda a ter alguns exemplos bons, simples e do mundo real.
Tomemos, por exemplo, todos os principais aplicativos de mídia social - Tumblr, Instagram, Facebook e Twitter. Todos eles têm uma visão de rolagem permanente, onde quanto mais você rola para baixo, mais conteúdo você vê, mais e mais no tempo. No entanto, todos experimentamos aquele momento em que você perde para onde foi rolado e o aplicativo redefine você de volta ao topo. Por exemplo, se você sair do aplicativo, ao reabri-lo, estará novamente no topo.
O motivo é que o servidor não armazenou o estado da sua sessão. Infelizmente, sua posição de rolagem acabou de ser armazenada na RAM do cliente.
Felizmente, você não precisa fazer login novamente ao se reconectar, mas isso ocorre apenas porque o certificado de login armazenado do lado do cliente também não expirou. Exclua e reinstale o aplicativo, e você precisará fazer login novamente, porque o servidor não associou seu endereço IP à sua sessão.
Você não tem uma sessão de logon no servidor, porque eles seguem o REST.
Agora, os exemplos acima não envolvem um navegador da Web, mas, no back-end, os aplicativos estão se comunicando via HTTPS com seus servidores host. O que quero dizer é que o REST não precisa envolver cookies e navegadores etc. Existem vários meios de armazenar o estado da sessão no lado do cliente.
Mas vamos falar sobre navegadores da Web por um segundo, porque isso traz outra grande vantagem do REST da qual ninguém está falando aqui.
Se o servidor tentou armazenar o estado da sessão, como ele deve identificar cada cliente individual?
Não foi possível usar o endereço IP, porque muitas pessoas poderiam estar usando o mesmo endereço em um roteador compartilhado. Então como?
Ele não pode usar o endereço MAC por vários motivos, pelo menos porque você pode estar conectado a várias contas diferentes do Facebook simultaneamente em diferentes navegadores e no aplicativo. Um navegador pode facilmente fingir ser outro, e os endereços MAC são igualmente fáceis de falsificar.
Se o servidor precisar armazenar algum estado do lado do cliente para identificá-lo, precisará armazená-lo na RAM por mais tempo do que o tempo necessário para processar suas solicitações, ou então, deverá armazenar em cache esses dados. Os servidores possuem quantidades limitadas de RAM e cache, sem mencionar a velocidade do processador. O estado do lado do servidor é adicionado aos três, exponencialmente. Além disso, se o servidor armazenar qualquer estado sobre suas sessões, será necessário armazená-lo separadamente para cada navegador e aplicativo com o qual você está conectado no momento e também para cada dispositivo diferente usado.
Então ... espero que você veja agora porque o REST é tão importante para a escalabilidade. Espero que você possa começar a ver por que o estado da sessão no servidor é a escalabilidade do servidor, o que são as bigornas soldadas para a aceleração do carro.
As pessoas ficam confusas pensando que "estado" se refere a informações armazenadas em um banco de dados. Não, refere-se a qualquer informação que precise estar na RAM do servidor quando você a estiver usando.
fonte
Vejo que a questão básica aqui é misturar Sessão com Estado . E enquanto o REST especifica que você NÃO deve armazenar o Estado no servidor, nada impede que você armazene uma Sessão do usuário .
Gerenciar o estado no servidor significa que o servidor sabe exatamente o que o cliente está fazendo (em que página está visualizando em qual seção do aplicativo). E é isso que você não precisa fazer.
Concordo com as outras pessoas dizendo que você deve manter o armazenamento da sessão em um tamanho mínimo; e, embora isso seja bom senso, na verdade também depende da aplicação. Portanto, em resumo, você ainda pode manter uma sessão com dados em cache para lidar com as solicitações com menos carga no servidor e gerenciar a autenticação fornecendo um token de autenticação / acesso temporário para o cliente usar. Sempre que a sessão / token expirar, gere um novo e peça ao cliente para usá-lo.
Alguém pode argumentar que o cliente deve gerar melhor o token. Eu digo que funciona nos dois sentidos, e dependeria do aplicativo, e quem trabalhará com a API.
Manter alguns dados confidenciais da sessão no servidor também deve ser o caminho certo. Você não pode confiar no cliente para manter o carrinho de compras que (por exemplo) contém um campo chamado "isFreeGift". Essas informações devem ser mantidas no servidor.
O link do vídeo fornecido por Santanu Dey em sua resposta é útil. Assista se você não tiver.
Apenas uma observação: Parece que todas as respostas já dadas parecem desconsiderar o fato de que algumas operações podem causar uma carga pesada no servidor. Isso é relevante em termos de consumo de energia, consumo de hardware e custo (para servidores alugados pelo ciclo da CPU). Um bom desenvolvedor não deve ter preguiça de otimizar seu aplicativo, mesmo que a operação possa ser feita muito rapidamente em uma CPU moderna em algum servidor alugado pelo qual eles não pagam sua conta de energia e manutenção.
Embora a pergunta tenha alguns anos, espero que minha resposta ainda seja útil.
fonte
Retirado de http://gopaldas.org/webservices/soap/webservice-is-stateful-or-stateless-rest-soap
fonte
Não tem colher.
Não pense em apatridia como "enviar todas as suas coisas para o servidor várias vezes". De jeito nenhum. Sempre haverá estado - o banco de dados em si é um tipo de estado, afinal, você é um usuário registrado, portanto, qualquer conjunto de informações do lado do cliente não será válido sem o lado do servidor. Tecnicamente, você nunca é verdadeiramente apátrida.
Uma palavra no debate de login sempre
O que significa mesmo não manter uma sessão e fazer login sempre? Alguns significam "enviar a senha de cada vez", isso é estúpido. Alguns dizem "nah, claro que não, envie um token " - e eis que a sessão do PHP está fazendo quase exatamente isso. Ele envia um ID de sessão que é um tipo de token e ajuda você a acessar suas coisas pessoais sem reenviar o u / pw todas as vezes. Também é bastante confiável e bem testado. E sim, conveniente, que pode se transformar em uma desvantagem, veja o próximo parágrafo.
Reduzir pegada
Em vez disso, o que você deve fazer e o que faz realmente sentido é reduzir ao mínimo o espaço ocupado pelo servidor da web. Idiomas como o PHP tornam muito fácil colocar tudo no armazenamento da sessão - mas as sessões têm um preço. Se você possui vários servidores da Web, eles precisam compartilhar informações da sessão, porque também compartilham a carga - qualquer um deles pode precisar atender à próxima solicitação.
Um armazenamento compartilhado é uma obrigação. O servidor precisa saber pelo menos se alguém está logado ou não. (E se você incomodar o banco de dados toda vez que precisar decidir isso, estará praticamente condenado.) Os armazenamentos compartilhados precisam ser muito mais rápidos que o banco de dados. Isso traz a tentação: ok, eu tenho um armazenamento muito rápido, por que não fazer tudo lá? - e é aí que as coisas ficam desagradáveis do outro lado.
Então você está dizendo, mantenha o armazenamento da sessão no mínimo?
Novamente, a decisão é sua. Você pode armazenar coisas por motivos de desempenho (o banco de dados quase sempre é mais lento que o Redis), você pode armazenar informações de forma redundante, implementar seu próprio cache, o que for - lembre-se de que os servidores da Web terão uma carga maior se você armazenar muito lixo neles. Além disso, se eles quebrarem sob cargas pesadas (e ocorrerão), você perde informações valiosas; com a maneira de pensar REST, tudo o que acontece nesse caso é que o cliente envia a mesma solicitação (!) novamente e é atendida dessa vez.
Como fazer isso certo então?
Não existe uma solução única para todos. Eu diria que escolha um nível de apátrida e vá com isso. As sessões podem ser amadas por alguns e odiadas por outros, mas não vão a lugar algum. A cada solicitação, envie tantas informações quanto faça sentido, um pouco mais, talvez; mas não interprete a apatridia como não tendo uma sessão, nem como se logando sempre. De alguma forma, o servidor deve saber que é você ; Os IDs de sessão do PHP são uma boa maneira, os tokens gerados manualmente são outra.
Pense e decida, não deixe as tendências de design pensarem em você.
fonte
Dê uma olhada nesta apresentação.
http://youtu.be/MRxTP-rQ-S8
De acordo com esse padrão - crie recursos repousantes transitórios para gerenciar o estado, se e quando realmente necessário. Evite sessões explícitas.
fonte
A principal diferença entre sem estado e sem estado é que os dados são sempre transmitidos ao servidor. No caso de apátrida, o cliente precisa fornecer todas as informações para que muitos parâmetros precisem ser passados em cada solicitação. Em Stateful, o cliet passa esses parâmetros uma vez e eles são mantidos pelo servidor até serem modificados pelo cliente novamente.
OMI, API deve ser apátrida, o que permite escalar rapidamente.
fonte
Você precisa gerenciar a sessão do cliente no lado do cliente. Isso significa que você deve enviar dados de autenticação a cada solicitação e, provavelmente, mas não necessário, possui um cache na memória do servidor, que emparelha os dados de autenticação com as informações do usuário, como identidade, permissões, etc.
Essa restrição de apatridia REST é muito importante. Sem aplicar essa restrição, o aplicativo do lado do servidor não será dimensionado bem, pois manter todas as sessões do cliente será o ponto principal de Aquiles .
fonte
Ao desenvolver um serviço RESTful, para fazer login, você precisará que seu usuário seja autenticado. Uma opção possível seria enviar o nome de usuário e a senha sempre que você pretende executar uma ação do usuário. Nesse caso, o servidor não armazenará os dados da sessão.
Outra opção é gerar um ID da sessão no servidor e enviá-lo ao cliente, para que o cliente possa enviar o ID da sessão ao servidor e se autenticar com isso. Isso é muito mais seguro do que enviar nome de usuário e senha toda vez, pois se alguém colocar a mão nesses dados, ele poderá se passar pelo usuário até que o nome de usuário e a senha sejam alterados. Você pode dizer que mesmo o ID da sessão pode ser roubado e o usuário será representado nesse caso e você está certo. No entanto, nesse caso, a representação do usuário só será possível enquanto o ID da sessão for válido.
Se a API RESTful espera nome de usuário e senha para alterar o nome de usuário e a senha, mesmo se alguém se passar por usuário usando o ID da sessão, o hacker não poderá bloquear o usuário real.
Uma identificação de sessão pode ser gerada pelo bloqueio unidirecional (criptografia) de algo que identifica o usuário e adiciona a hora à identificação da sessão, dessa maneira o tempo de expiração da sessão pode ser definido.
O servidor pode ou não armazenar IDs de sessão. Obviamente, se o servidor armazena o ID da sessão, ele violaria os critérios definidos na pergunta. No entanto, é importante garantir que o ID da sessão possa ser validado para o usuário especificado, o que não requer o armazenamento do ID da sessão. Imagine uma maneira de você ter uma criptografia unidirecional de email, ID do usuário e alguns dados particulares específicos do usuário, como cor favorita, esse seria o primeiro nível e, de alguma forma, adicionar a data do nome de usuário à string criptografada e aplicar uma criptografia de maneira. Como resultado, quando um ID de sessão é recebido, o segundo nível pode ser descriptografado para poder determinar qual nome de usuário o usuário afirma ser e se a hora da sessão é certa. Se isso for válido, então o primeiro nível de criptografia pode ser validado fazendo-o novamente e verificando se ele corresponde à string. Você não precisa armazenar dados da sessão para conseguir isso.
fonte
O conceito todo é diferente ... Você não precisa gerenciar sessões se estiver tentando implementar o protocolo RESTFul. Nesse caso, é melhor executar o procedimento de autenticação em cada solicitação (considerando que há um custo extra em termos de desempenho - a senha de hash seria um bom exemplo. Não é grande coisa ...). Se você usa sessões - como você pode distribuir a carga em vários servidores? Aposto que o protocolo RESTFul tem como objetivo eliminar as sessões - você realmente não precisa delas ... É por isso que é chamado de "sem estado". As sessões são necessárias apenas quando você não pode armazenar nada além de Cookie no lado do cliente após a solicitação de solicitação (use um navegador antigo, que não suporta Javascript / HTML5 como exemplo). No caso de um cliente RESTFul "com todos os recursos", geralmente é seguro armazenar
base64(login:password)
no lado do cliente (na memória) até que o aplicativo ainda esteja carregado - o aplicativo é usado para acessar o único host e o cookie não pode ser comprometido pelos scripts de terceiros ...Eu recomendaria estritamente desabilitar a autenticação de cookies para serviços RESTFul ... consulte Autenticação Básica / Digest - isso deve ser suficiente para serviços baseados em RESTFul.
fonte
a client side (in memory)
e como é seguro salvarbase64(login:password)
no lado do cliente?O REST é sem estado e não mantém nenhum estado entre os pedidos. Os cookies / cabeçalhos do cliente são definidos para manter o estado do usuário como autenticação. Digamos que o nome de usuário / senha do cliente seja validado pelo mecanismo de autenticação de terceiros - gerneação de OTP de segundo nível, etc. Depois que o usuário for autenticado - os cabeçalhos / cookies pararão o ponto final do serviço exposto e podemos assumir o usuário como autenticação, pois o usuário vem com cabeçalhos / cookies válidos . Agora, certas informações do usuário como IP são mantidas no cache e, depois disso, se a solicitação vier do mesmo IP (endereço mac) para os recursos listados, o usuário é permitido. E o cache é mantido por um período específico que é invalidado quando o tempo passa. Portanto, o cache pode ser usado ou as entradas do banco de dados podem ser usadas para manter as informações entre as solicitações.
fonte
Sem estado aqui significa que o estado ou os metadados da solicitação não são mantidos no lado do servidor. Ao manter cada solicitação ou estado do usuário no servidor, isso levaria a gargalos de desempenho. O servidor é solicitado apenas com os atributos necessários para executar operações específicas.
Para gerenciar sessões ou fornecer experiência personalizada aos usuários, é necessário manter alguns metadados ou estado das preferências do usuário provável, histórico de solicitações anteriores. Isso pode ser feito mantendo cookies, atributos ocultos ou no objeto de sessão.
Isso pode manter ou acompanhar o estado do usuário no aplicativo.
Espero que isto ajude!
fonte