詳細検索

API RESTful 101

Avatar
por Chen Ziyu

API RESTful 101
Traduzido do English • Ver original

É quase impossível para um engenheiro backend não ter conhecimento de APIs RESTful no século XXI, pois é um dos tipos de API mais populares. Podemos atribuir sua popularidade principalmente à sua escalabilidade, flexibilidade e simplicidade, qualidades muito procuradas nas APIs modernas. Se você também achar essas qualidades desejáveis, deve considerar construir APIs seguindo os princípios RESTful. Neste artigo, explicarei o que conta como uma API RESTful e demonstrarei como projetá-la do zero.

O que é a API RESTful?

Vamos começar com a sigla "REST" em RESTful API. "REST" significa REpresentational State Transfer. É um estilo arquitetônico de software com cinco restrições:

  1. Interface Uniforme
  2. Apátrida
  3. Cacheável
  4. Separação Cliente-Servidor
  5. Sistema em Camadas.

APIs RESTful são essencialmente APIs que não violam nenhuma das restrições acima. Vamos analisá-las uma por uma.

Interface Uniforme

Essa restrição é provavelmente a mais relevante para engenheiros backend, pois diz respeito ao design da API. Ela estipula que deve haver apenas uma maneira uniforme de interagir com um determinado servidor, independentemente do tipo de dispositivo ou aplicação do cliente. A seguir, algumas diretrizes para construir uma interface tão uniforme. Uma interface uniforme garante consistência e simplifica o desenvolvimento e uso da API.

  1. Baseado em Recursos: O cliente precisa especificar no URI qual recurso (objeto, dado ou serviço) deseja acessar em cada requisição.
  2. Manipulação de Recursos por Meio de Representações: Para permitir que o cliente manipule (edite ou delete) recursos, o cliente deve manter representações de recursos que contenham informações necessárias para modificação ou exclusão de recursos.
  3. Mensagens Autodescritivas: Cada mensagem (solicitação ou resposta) deve conter informações suficientes para que o destinatário precise entender a mensagem. Essa restrição se aplica tanto ao cliente quanto ao servidor. O cliente deve incluir o método HTTP em sua solicitação para indicar ao servidor qual ação deseja realizar com sua solicitação. A resposta enviada pelo servidor deve conter o tipo de conteúdo e o código de status da resposta para que o cliente saiba como interpretar as informações da resposta. O cliente e o servidor também podem incluir outras informações em suas mensagens, se necessário.
  4. Hipermídia como Motor do Estado da Aplicação (HATEOAS): Cada resposta deve incluir hipermídia. Hipermídia é informação sobre as solicitações adicionais que o cliente pode fazer após receber a resposta atual. O servidor a utiliza para informar o cliente sobre o que pode fazer a seguir.

Apátridas

Essa restrição proíbe o servidor de acompanhar os estados do cliente. Como resultado, o cliente não pode confiar no servidor para acompanhamento de estado e precisa incluir todas as informações necessárias para cumprir uma solicitação. O servidor trata cada requisição como independente. Essa falta de estado libera o servidor das tarefas de manter estados, melhorando assim a disponibilidade.

Armazenável no arquivo

Essa restrição exige que o servidor especifique em cada resposta se a resposta é cacheável e a duração que o cliente pode armazená-la em cache. Fazer isso nos ajuda a construir um sistema de cache eficiente que pode eliminar a comunicação desnecessária entre cliente e servidor, melhorando assim o desempenho e a disponibilidade geral.

Separação Cliente-Servidor

Essa restrição ilustra a separação de funções entre o cliente e o servidor em uma arquitetura de API RESTful. O cliente é responsável apenas por fazer requisições para criar, acessar ou manipular recursos. O servidor é responsável apenas por fornecer e gerenciar recursos em resposta às solicitações do cliente. A Separação Cliente-Servidor permite que o frontend e o backend evoluam de forma independente.

Sistema em Camadas

Podem existir múltiplas camadas na arquitetura de uma aplicação entre o cliente e o servidor. Essas camadas intermediárias geralmente desempenham um papel complementar às funcionalidades centrais da aplicação. Alguns exemplos incluem proxies (para balanceamento de carga) e gateways (para tradução de protocolos). A restrição do "Sistema em Camadas" restringe cada camada de interagir com camadas diferentes das próximas. Ela garante a simplicidade estrutural da aplicação e nos impede de introduzir complexidade desnecessária nas interações entre camadas.

Como Construir APIs RESTful (Exemplo)

Em seguida, vou ilustrar como construir APIs RESTful com um exemplo concreto. Farei referências às restrições e diretrizes mencionadas na seção anterior. Por favor, volte à seção anterior se tiver dificuldade para lembrar delas. Digamos que você queira construir um site de blog. Na primeira fase, você precisa desenvolver endpoints para realizar as seguintes ações:

  1. Criação de uma nova postagem
  2. Recuperar todas as postagens
  3. Recuperar uma postagem pelo seu ID
  4. Atualização de uma postagem
  5. Remoção de um poste

Você consegue adivinhar quantos URIs você precisa? Muitos de vocês podem ser tentados a responder cinco porque, intuitivamente, você precisa de um URI para uma ação. No entanto, só precisamos de dois URIs se cumprirmos totalmente a diretriz "Baseada em Recursos". Os URIs devem representar recursos em vez de ações realizadas sobre recursos. Os dois tipos de recursos que temos aqui são uma lista de posts e um único post. Podemos criar os seguintes dois URIs para representá-los, respectivamente:

  1. Lista de postagens: '/api/v1/posts'
  2. Um único post: '/api/v1/posts/'

Você pode querer perguntar: Como podemos representar cinco ações diferentes com apenas dois URIs? A resposta é simples: podemos usar os métodos HTTP para representar as ações, e ações realizadas nos mesmos recursos podem compartilhar os mesmos URIs. Aqui estão os métodos HTTP que precisamos:

  1. GET: recuperação de recursos
  2. POST: criação de recursos
  3. PUT: atualização de recursos
  4. DELETAÇÃO: remoção de recursos

Agora vamos analisar como devemos projetar nossos endpoints para suportar as cinco operações acima.

  1. Criando uma nova postagem: '[POST] /api/v1/posts'
  2. Recuperando todas as postagens: '[GET] /api/v1/posts'
  3. Recuperar uma postagem pelo seu ID: '[GET] /api/v1/posts/'
  4. Atualizando um post: '[PUT] /api/v1/posts/'
  5. Remover um post: '[DELETE] /api/v1/posts/'

Em seguida, vamos passar a projetar como devem ser as requisições e respostas de cada endpoint. Ainda precisamos ter em mente as diretrizes da restrição da Interface Uniforme. Para este artigo, vamos focar na terceira ação.

Recuperando uma postagem pelo seu ID: '[GET] /api/v1/posts/'

Para seguir a diretriz "Manipulação de Recursos por Representação", precisamos garantir que o cliente tenha todas as informações necessárias para manipular (editar ou excluir) uma determinada publicação. Para editar ou excluir uma publicação, o cliente precisa especificar o ID da postagem para que o servidor possa identificar qual postagem manipular. Para editar uma postagem, o cliente também precisa saber quais campos pode editar e o ID da postagem. Digamos que o cliente possa editar os seguintes campos:

  1. Título
  2. Corpo

Então os dados de resposta de '[GET] /api/v1/posts/' devem ser assim: Resposta:

{ 
   "id":1, 
   "título":"API RESTful 101", 
   "corpo": "Este é um artigo sobre a API RESTful." 
}

Também precisamos que o cliente e o servidor enviem mensagens Auto-Descritivas um para o outro. Com a diretriz "Mensagem Auto-Descritiva" em mente, podemos projetar a solicitação e a resposta para '[GET] /api/v1/posts/' da seguinte forma: Solicitação:

Método HTTP: GET
URI: /api/v1/posts/ 
Protocolo: HTTP/1.1
Cabeçalhos: Aceitar: application/json

Nessa solicitação, o cliente especificou a ação através do método HTTP (GET). O cliente também identificou o recurso alvo da ação incluindo o URI ('/api/v1/posts/'). Além disso, o cliente incluiu o protocolo que utiliza (HTTP/1.1) e o tipo de dados que aceita (application/json). Resposta:

Protocolo: HTTP/1.1
Código de Status da Resposta: 200 OK
Cabeçalhos: Tipo-Conteúdo: application/json
{ 
   "id":1, 
   "título":"API RESTful 101", 
   "corpo": "Este é um artigo sobre a API RESTful." 
}

Nessa resposta, o servidor informou ao cliente que a solicitação foi processada com sucesso via código de status de resposta 200. Também adicionou o tipo de conteúdo para que o cliente saiba como interpretar os dados da resposta.

Ainda precisamos seguir mais uma diretriz para construir uma Interface Uniforme: "Hipermídia como Motor do Estado da Aplicação." Essa diretriz exige que o servidor inclua outras ações que o cliente pode tomar. Após receber a resposta contendo detalhes da publicação, o cliente pode escolher editar ou excluir a publicação. Portanto, o servidor pode adicionar os pedidos de edição ou exclusão da publicação nos dados da resposta. Resposta:

Protocolo: HTTP/1.1
Código de Status da Resposta: 200 OK
Cabeçalhos: Tipo-Conteúdo: application/json
{ 
   "id":1, 
   "título":"API RESTful 101", 
   "corpo": "Este é um artigo sobre a API RESTful.", 
   "links":[ 
      { 
         "método":"PUT", 
         "uri":"/api/v1/posts/" 
      }, 
      { 
         "método":"DELETAÇÃO", 
         "uri":"/api/v1/posts/" 
      }
   ]
}

Agora que construímos uma interface uniforme, vamos garantir que nosso sistema cumpra a restrição "Cacheable". Podemos fazer isso com o cabeçalho Cache-Control. Suponha que o servidor permita que o cliente armazene posts em cache por até 10 minutos (600 segundos). Então nossa resposta final deve ser a seguinte: Resposta:

Protocolo: HTTP/1.1
Código de Status da Resposta: 200 OK
Cabeçalhos: 
Tipo-Conteúdo: application/json
Controle de Cache: max-idade=600
{ 
   "id":1, 
   "título":"API RESTful 101", 
   "corpo": "Este é um artigo sobre a API RESTful.", 
   "links":[ 
      { 
         "método":"PUT", 
         "uri":"/api/v1/posts/" 
      }, 
      { 
         "método":"DELETAÇÃO", 
         "uri":"/api/v1/posts/" 
      }
   ]
}

'Controle de Cache: max-idade=600' significa que o cliente pode armazenar os dados em cache por no máximo 600 segundos.

Até agora, passamos pelas restrições "Interface Uniforme" e "Cacheável". É difícil ilustrar as outras restrições neste exemplo, pois elas dizem respeito ao design do sistema, mas por favor, tenham em mente ao construir APIs RESTful.

Resumo

Neste artigo, abordei a definição de API RESTful e as cinco restrições que APIs RESTful não podem violar. Também mostrei como construir APIs RESTful com um exemplo. Espero que este artigo tenha ajudado você a entender melhor as APIs RESTful.

Leia mais:

https://www.geeksforgeeks.org/rest-api-architectural-constraints/ https://learn.microsoft.com/en-us/azure/architecture/best-practices/api-design https://restfulapi.net/hateoas/

Related Articles