Saltar para o conteúdo
Comece grátis
Voltar ao blogue

Restrições da arquitetura da API REST: Um guia de conceção

Sorin-Gabriel MaricaÚltima atualização em 15 min read
Restrições da arquitetura da API REST: Um guia de conceção
TL;DR: REST é um estilo arquitetónico definido por restrições nas interações entre componentes. Utilize as suas seis restrições para analisar a independência do cliente, o contexto do pedido, o armazenamento em cache, as interfaces uniformes, as camadas e o código opcional descarregado; uma resposta JSON, por si só, não comprova nenhuma delas.

Um ponto de extremidade que devolve uma encomenda em formato JSON pode, ainda assim, obrigar todos os clientes a compreender o fluxo de trabalho privado do servidor. As restrições da arquitetura da API REST são as regras que determinam se essas interações seguem a Transferência de Estado Representacional (REST), em vez de se limitarem a utilizar o HTTP. Dizem respeito ao que os participantes devem saber uns sobre os outros, à forma como trocam representações e ao grau de independência com que podem sofrer alterações.

Considere um coletor a ler um catálogo de produtos. Este precisa de recuperar registos, descobrir outra página, reconhecer um resultado inalterado e retomar o processo após a falha de um trabalhador. Esses requisitos revelam imediatamente as escolhas arquitetónicas. A próxima solicitação contém o seu próprio contexto? O servidor pode anunciar a próxima página? Uma resposta guardada é reutilizável? O trabalhador substituto deve recuperar uma conversa invisível antes de continuar?

Este guia utiliza essas questões como uma revisão de projeto. Os exemplos descrevem um serviço de catálogo hipotético, não a API executável de um fornecedor. Mostram como inspecionar o comportamento sem reduzir o REST a nomes de endpoints no plural ou a uma lista de verbos HTTP. Pode aplicar a mesma revisão a uma API que publique, a uma integração que mantenha ou a um pipeline de recolha de dados que consuma o serviço de outra entidade.

Leia «Restrições da arquitetura da API REST como testes de conceção»

As seis restrições são: separação cliente-servidor, interações sem estado, capacidade de armazenamento em cache, uma interface uniforme, um sistema em camadas e código sob demanda opcional. As cinco primeiras definem características obrigatórias; o comportamento executável descarregado é opcional. Roy Fielding desenvolve este conjunto no Capítulo 5 da sua tese de doutoramento.

Utilize esta tabela para transformar os nomes em evidências que pode solicitar durante uma revisão. Os exemplos são questões de conceção, não um conjunto de testes de conformidade nem uma promessa de que um único cabeçalho torne todo o sistema RESTful.

Restrição

Evidência a inspecionar

Questão hipotética do catálogo

Cliente-servidor

Uma fronteira entre as responsabilidades de apresentação e de serviço

Pode um coletor de linha de comandos utilizar o catálogo sem a interface do utilizador do site?

Sem estado

Contexto completo para cada interação

Pode outro trabalhador emitir o próximo pedido de forma independente?

Cacheável

Condições definidas para a reutilização da resposta

Uma resposta de produto guardada ainda é utilizável para este pedido?

Interface uniforme

Identificação de recursos, representações, semântica das mensagens e hipermédia

A resposta explica os seus dados e as transições disponíveis?

Sistema em camadas

Uma interface que funciona através de intermediários

A adição de um gateway exige que os clientes conheçam a topologia interna?

Código a pedido, opcional

Execução de ficheiros descarregados explicitamente suportada

É realmente necessário executar um script fornecido?

As restrições da arquitetura da API REST descrevem um sistema de interações. Uma captura de ecrã de uma resposta não permite determinar todas elas. Recolha um pequeno registo que contenha uma leitura, uma transição, um erro e um pedido repetido e, em seguida, analise os pressupostos que ligam esses eventos.

Separe também a arquitetura da seleção da tecnologia. O HTTP é um ambiente natural para interfaces orientadas para recursos, mas um estilo arquitetónico não é uma especificação de formato de transmissão. Se a sua equipa ainda estiver a comparar famílias de design, o guia «API REST versus API SOAP» explica por que razão um estilo arquitetónico e um protocolo de mensagens requerem critérios de avaliação diferentes.

Mantenha as responsabilidades do cliente separadas do contexto da solicitação

Imagine que um serviço de catálogo publica descrições de produtos e a disponibilidade de stock. Um navegador escolhe o layout visual, enquanto um coletor escolhe um formato de armazenamento. Nenhum dos consumidores precisa de saber se o serviço lê uma base de dados ou combina vários sistemas. Essa separação é o ponto de partida útil para o design cliente-servidor.

Não interprete isto como um requisito para criar um novo microsserviço para cada recurso. Uma única aplicação pode expor um limite claro. Por outro lado, muitos microsserviços podem expor uma interface profundamente acoplada se os chamadores tiverem de compreender nomes internos de bases de dados, a ordem de implementação ou etapas de fluxo de trabalho não documentadas.

A análise seguinte diz respeito ao estado da conversa. Suponha que um serviço exija que um cliente selecione primeiro um armazém e, em seguida, leia um pedido de produto não qualificado de acordo com essa seleção memorizada. Um trabalhador substituto não consegue compreender o pedido apenas ao analisá-lo. Num design sem estado, o pedido identifica o armazém relevante ou, de outra forma, contém informação suficiente para interpretar a operação solicitada.

Isto não significa que o serviço esqueça produtos, encomendas ou permissões após cada resposta. Os dados empresariais persistentes constituem o estado do recurso. A questão reside no contexto oculto da conversa com o cliente, necessário para compreender um pedido posterior. As restrições da arquitetura da API REST tornam-se mais fáceis de aplicar quando se nomeiam explicitamente esses dois tipos de estado no documento de conceção.

A autenticação requer o mesmo cuidado. Um token de portador não é prova de que todas as interações sejam sem estado, e uma consulta à base de dados durante a autorização não é automaticamente prova do contrário. Verifique se a solicitação pode ser compreendida sem reconstruir interações anteriores do cliente. Em seguida, analise a autorização separadamente: o serviço deve decidir se este solicitante pode aceder a este armazém e produto específicos.

Para os coletores, documente quais as entradas da solicitação que pertencem a uma conta, a uma localização ou a uma execução de recolha. Mantenha essas entradas associadas aos itens de trabalho ao transferi-los entre os trabalhadores. Se a integração também depender de sessões do navegador, compreenda como os cookies HTTP preservam o contexto da sessão antes de assumir que a cópia de um URL reproduz a resposta.

Torne o comportamento da cache um contrato de dados explícito

Suponha que a descrição do produto mude com pouca frequência, enquanto a disponibilidade muda ao longo do dia. Atribuir a ambas as respostas o mesmo período prolongado de reutilização é conveniente para a infraestrutura, mas potencialmente errado para o consumidor. O desenho do cache começa com a validade aceitável da informação, não com o desejo de reduzir o volume de pedidos.

Para APIs HTTP, a RFC 9111 define a reutilização do cache e as diretivas. Uma resposta pode proibir o armazenamento, exigir validação antes da reutilização ou permitir a reutilização sob condições especificadas. no-cache não significa o mesmo que no-store: o primeiro permite o armazenamento, mas exige que a validação seja bem-sucedida antes da reutilização; o segundo instrui os caches a não armazenarem a resposta.

Uma etiqueta de entidade fornece ao consumidor um validador para uma representação selecionada. O coletor pode enviar posteriormente If-None-Match; quando as condições aplicáveis forem cumpridas para um GET, uma 304 Not Modified resposta permite-lhe reutilizar a representação guardada. Essa resposta não tem nenhum novo corpo de representação para analisar. Tratá-la como um catálogo vazio corromperia uma execução de recolha que, de outra forma, estaria a funcionar corretamente.

As restrições da arquitetura da API REST exigem um comportamento de reutilização definido, não um armazenamento em cache universal. Um relatório específico de uma conta pode necessitar de um tratamento restritivo, enquanto uma descrição de categoria pública pode tolerar um período de atualização mais longo. Uma revisão do projeto deve identificar ambos os casos, em vez de exigir um acerto no cache para cada ponto final.

Mantenha as variantes distintas. Se o idioma, as credenciais, a localização ou outra entrada afetarem a resposta, determine como essa entrada participa na seleção e na política de cache. Não presuma que uma chave de cache baseada apenas no URL seja suficiente para dados personalizados. Os caches partilhados também têm restrições específicas em relação a pedidos autenticados; por isso, verifique o comportamento implementado em vez de confiar na presença de uma única diretiva.

No seu armazenamento de coleções, mantenha a hora de recuperação separada da hora de modificação fornecida pela fonte. Estas respondem a questões diferentes: quando observou a representação e quando o editor afirma que esta foi alterada. Trata-se de uma recomendação de implementação para fins de auditabilidade, não de uma sétima restrição REST.

Analise as quatro partes da interface uniforme

A interface uniforme é a parte mais fácil de subestimar nas restrições da arquitetura da API REST. Ela inclui quatro requisitos: identificar recursos, manipulá-los por meio de representações, tornar as mensagens autodescritivas e usar hipermídia para controlar o estado da aplicação. Avalie cada um deles, em vez de considerar que «usa GET e POST» seja a análise completa.

Identificar recursos e trocar representações

Um identificador de produto refere-se ao recurso conceptual do produto; o seu documento JSON é uma representação desse recurso num determinado momento. Uma página renderizada, uma imagem ou um documento XML também podem ser uma representação. Conceber em torno desta distinção ajuda a evitar expor o layout de uma linha da base de dados como se fosse o contrato público permanente.

Para o catálogo hipotético, especifique qual o identificador que permanece estável quando o nome de um produto muda. Decida se as variantes têm identidades separadas e se os produtos descontinuados continuam a ser acessíveis. Essas são escolhas do domínio. O teste prático consiste em verificar se os clientes conseguem referir-se ao objeto pretendido sem terem de adivinhar como o servidor o armazena.

A manipulação através de representações significa que o cliente opera através da interface publicada, em vez de modificar diretamente as estruturas privadas do servidor. Uma representação enviada continua a requerer validação por parte do servidor. Um preço, um identificador de proprietário ou um campo de permissão fornecido pelo cliente não se torna autoritário apenas porque o pedido utiliza um tipo de mídia adequado.

Faça com que as mensagens expliquem como devem ser interpretadas

A autodescrição requer mais do que nomes de campos legíveis. A semântica dos métodos, o estado da resposta, o tipo de mídia e os metadados relevantes indicam aos destinatários como lidar com a mensagem. O mesmo texto JSON pode ter significados diferentes quando devolvido como uma representação bem-sucedida ou incluído numa resposta de erro.

Ao utilizar HTTP, aplique a semântica real dos seus métodos. GET é um método de recuperação seguro; PUT e DELETE são idempotentes no efeito pretendido definido. Idempotência não implica que cada repetição deva devolver um estado idêntico nem proíbe o registo. Estas distinções provêm da Semântica HTTP (RFC 9110) e são relevantes quando uma integração considera repetir uma operação interrompida.

Um coletor deve inspecionar o estado e o tipo de mídia antes de analisar os registos esperados. Uma ligação de rede bem-sucedida seguida de um erro de gateway HTML não constitui um catálogo JSON válido. Da mesma forma, um objeto JSON sintaticamente válido com um esquema de erro não é uma página que contenha zero produtos.

Deixar que as representações exponham as transições disponíveis

A hipermídia como motor do estado da aplicação, frequentemente abreviada para HATEOAS, significa que os clientes selecionam transições disponíveis a partir de controlos fornecidos pela interação. Uma representação de catálogo pode expor um link para a página seguinte cuja relação tem um significado definido. O coletor segue esse controlo em vez de calcular todas as URLs futuras a partir de uma suposição privada sobre deslocamentos.

O esclarecimento de Fielding sobre as APIs orientadas por hipertexto torna isto um requisito definidor, e não um adorno opcional. Os clientes continuam a precisar de compreender o tipo de mídia e a semântica das relações. A hipermídia não torna compreensível todo o fluxo de trabalho empresarial desconhecido sem um contrato.

Para uma análise prática, altere o URL hipotético da página seguinte de um deslocamento para um cursor opaco. Um cliente que siga o controlo fornecido pode permanecer inalterado. Um cliente que o descarte e incremente um número fica acoplado a uma regra de construção. A RFC 8288 define os tipos de ligações e relações na Web, fornecendo um vocabulário para ligações cujo significado é mais preciso do que um campo de URL arbitrário.

As restrições da arquitetura da API REST levantam, portanto, uma questão mais profunda do que a mera existência de ligações: as transições suportadas orientam efetivamente o cliente? Adicionar uma self ligação a um procedimento que, de outra forma, estaria codificado de forma rígida não demonstra a interface uniforme completa.

Preservar a semântica entre camadas e código descarregado

Um coletor pode chegar a um gateway que encaminha para uma cache e, em seguida, para uma aplicação. Deve utilizar a interface publicada sem depender de qual instância da aplicação recebe um pedido. Internamente, o operador pode alterar o encaminhamento ou substituir um serviço, preservando esse limite.

As camadas são também locais onde as suposições falham. Um proxy pode remover um cabeçalho, um gateway pode substituir uma página de erro ou um cache pode combinar respostas que deveriam permanecer separadas. Analise o comportamento de ponta a ponta, bem como a configuração de cada componente. As restrições da arquitetura da API REST não garantem que um intermediário esteja configurado corretamente.

Utilize uma pequena matriz de rastreio para o catálogo hipotético: resposta direta da aplicação, resposta do gateway, revalidação do cache e tempo limite a montante. Compare o estado observável, os metadados de representação e o contrato de erro. Preserve um identificador de correlação que ajude os operadores a rastrear falhas, mas evite exigir que os clientes compreendam nomes de anfitriões internos ou a topologia de implementação.

O «código sob demanda» aborda uma questão diferente: um servidor pode ampliar o comportamento de um cliente fornecendo código executável. Um navegador a carregar um script ilustra esse mecanismo. O seu estado opcional é importante porque muitos consumidores de API aceitam intencionalmente apenas dados. Um servidor não precisa de enviar JavaScript para um coletor sem interface gráfica para satisfazer as restrições obrigatórias.

Para o trabalho de recolha, torne o limite de execução explícito. Se uma página necessitar de execução no navegador para revelar dados, isso constitui um requisito operacional do alvo. Não é prova de que todos os clientes REST devam executar respostas arbitrárias. Da mesma forma, receber HTML não significa que o código sob demanda esteja a ser utilizado; o conteúdo HTML e o comportamento executável são questões distintas.

Considere a execução descarregada como uma capacidade própria, com os seus próprios controlos. Mantenha as credenciais da API fora de contextos de execução de páginas não relacionados e decida a que anfitriões e destinos de navegação um coletor baseado no navegador está autorizado a aceder. Estas são precauções práticas de implementação relacionadas com o exemplo, não novas adições à definição arquitetónica.

Transforme as restrições numa revisão de integração

Comece por uma jornada real do utilizador, em vez de pelo inventário de pontos finais. Para o exemplo do catálogo, recupere uma categoria, siga uma transição de página, volte a visitar um produto inalterado, depare-se com um recurso indisponível e retome a execução após o reinício de um worker. Registe pedidos e respostas sanitizados para cada etapa.

Para cada observação, separe uma propriedade comprovada de uma suposição. O facto de o reinício de um processo ter sido bem-sucedido uma vez sugere portabilidade do contexto, mas não prova que não exista uma dependência de sessão oculta noutro local. Um controlo de «próxima página» demonstra uma transição anunciada, mas não estabelece que toda a aplicação seja orientada por hipermédia.

As restrições da arquitetura da API REST funcionam melhor como vocabulário de revisão. Registe «requer uma seleção prévia não documentada do armazém» em vez de «REST incorreta». Registe «o cliente constrói URLs de paginação apesar de uma relação fornecida» em vez de «não é moderna». Conclusões concretas apontam para alterações que um programador pode implementar e que um revisor pode verificar.

Em seguida, priorize as falhas de acordo com as suas consequências. Uma autorização incorreta ou o armazenamento em cache entre contas requerem atenção antes de uma preferência de nomenclatura. Uma nova tentativa que duplique o trabalho merece uma estratégia de recuperação documentada. A ausência de uma funcionalidade opcional de «código a pedido» não necessita de correção apenas para obter o rótulo REST.

No caso de um serviço externo, poderá não ter a possibilidade de alterar a interface. Adapte o coletor ao contrato documentado, preserve o contexto necessário e descreva a limitação com honestidade. Utilizar uma API HTTP útil que não cumpra critérios REST rigorosos pode, ainda assim, ser uma escolha de engenharia sensata. O erro está em assumir propriedades que a interface nunca prometeu.

Pontos-chave

  • Analise as restrições da arquitetura da API REST em relação aos registos de pedidos e às dependências dos clientes, e não à presença de JSON ou de nomes de pontos finais apelativos.
  • Separe os dados de recursos persistentes do estado oculto da conversa e teste se o trabalho pode transitar entre consumidores sem reconstruir interações anteriores.
  • Trate a atualização, a validação, as variantes de representação e o tratamento de erros como partes do contrato de dados antes de ativar o armazenamento em cache agressivo ou novas tentativas.
  • Inspecione todos os quatro requisitos de interface uniforme, incluindo transições significativas; uma lista de métodos HTTP abrange apenas parte do projeto.
  • Registe as limitações concretas de integração e as suas consequências, para que as correções abordem a fiabilidade e a independência, em vez de se limitarem apenas à terminologia.

Perguntas frequentes

O REST prescreve um número de versão da API no URL?

Não. As restrições não determinam uma localização universal para o número de versão. Uma política de versionamento é uma decisão contratual que deve explicar como os clientes detetam as alterações e como a compatibilidade é mantida. Antes de adotar qualquer convenção de nomenclatura, identifique quais as alterações que iriam efetivamente afetar os utilizadores existentes e como irá comunicá-las ou implementá-las gradualmente.

Uma transação de base de dados é incompatível com o REST?

Não. Um serviço pode utilizar transações de base de dados internamente, ao mesmo tempo que expõe uma interface moldada pelo REST. O cliente deve basear-se no comportamento publicado, em vez de na implementação da base de dados. Decida que tipo de consistência a operação promete, o que significa uma resposta completa e como um chamador pode investigar um resultado incerto após uma falha de ligação.

As restrições da arquitetura da API REST especificam limites de taxa?

Não. Não estabelecem quotas de pedidos, limites de simultaneidade nem um intervalo de espera universal. Esses aspetos pertencem ao contrato operacional do serviço. Os consumidores devem consultar os limites documentados pelo fornecedor, manter a simultaneidade dentro dos limites e conservar informação de diagnóstico suficiente para distinguir a limitação de tráfego de erros de validação ou de infraestrutura indisponível.

Analise o comportamento antes de escolher a classificação

A análise REST mais produtiva termina com conclusões observáveis. Deve saber qual o contexto que uma solicitação transporta, quando uma resposta pode ser reutilizada, como o cliente a interpreta e de onde provém a próxima ação suportada. Deve também saber quais as suposições que permanecem por testar por trás de gateways ou após uma interação falhada.

Utilize essas conclusões para melhorar a próxima integração. Inclua uma entrada em falta no contrato explícito, corrija um limite de cache ou ensine o cliente a seguir uma transição fornecida. Mantenha visível a distinção entre requisitos arquitetónicos e recomendações operacionais, para que a equipa possa fazer compromissos deliberados.

Se o seu pipeline de dados também necessitar de informações disponíveis apenas através de páginas web, avalie a API Scraper da WebScrapingAPI como uma entrada de recolha separada. Aplique a mesma disciplina a esse limite: valide a resposta, preserve o contexto da recolha e documente o que os consumidores a jusante podem presumir sobre os dados devolvidos.

Sobre o autor

Sorin-Gabriel Marica, Desenvolvedor Full-Stack @ WebScrapingAPI

Sorin-Gabriel Marica

Desenvolvedor Full-Stack

Sorin Marica é engenheiro Full Stack e DevOps na WebScrapingAPI, onde desenvolve funcionalidades do produto e mantém a infraestrutura que garante o bom funcionamento da plataforma.

Comece a construir

Pronto para expandir a sua recolha de dados?

Junte-se a mais de 2.000 empresas que utilizam a WebScrapingAPI para extrair dados da Web à escala empresarial, sem quaisquer custos de infraestrutura.