Entendendo e usando APIs RESTful

Yi Sun

December 2, 2022

Technology

Na era da Internet de Todas as Coisas, existem muitas APIs diferentes, e é importante padronizá-las. A API RESTful é um dos estilos de arquitetura de API mais populares, que pode ajudá-lo a separar as preocupações do lado do cliente e do servidor, permitindo que o front-end e o back-end iterem separadamente, melhorando assim a eficiência. Sua característica sem estado pode tornar o aplicativo mais escalável e facilitar a implementação de políticas de cache para melhorar a experiência do usuário e o desempenho. Neste artigo, vamos apresentar o que é uma API RESTful e como podemos usá-la.

O que é uma API

Deixando de lado o que é uma API por um momento, vamos falar sobre como entregamos informações em nossas vidas.

Quando você leva seu dinheiro ao dono da loja e diz a ele que precisa comprar pilhas, o dono recebe o dinheiro, encontra as pilhas na prateleira e as entrega para você. Uma transação para comprar uma pilha é concluída com sucesso.

O software de computador, por outro lado, completa isso por meio de APIs. Vamos começar com a definição da Wikipedia:

Uma interface de programação de aplicativos (API) é uma maneira de dois ou mais programas de computador se comunicarem entre si. É um tipo de interface de software, oferecendo um serviço para outras partes do software.

O Software A faz uma solicitação ao Software B por meio da API, e o Software B retorna a resposta para o A por meio da API após consultar seus recursos.

O Software A fazendo uma solicitação ao Software B por meio da API é como você dizendo ao seu chefe que precisa de uma pilha, e o Software B retornando os dados para o Software A é como seu chefe encontrando a pilha e entregando-a para você.

Esse processo não exige que o Software B saiba por que o Software A quer os dados, assim como o dono da loja não perguntaria por que você comprou a pilha. O Software A também não precisa saber como o Software B encontrou os dados, assim como você não perguntaria ao dono onde as pilhas foram compradas quando as comprou. Cada software passa informações entre si por meio de APIs, e cada um faz sua própria coisa, tornando o mundo da programação ordenado e confiável.

O que é uma API RESTful

Roy Fielding definiu REST (Transferência de Estado Representacional) em sua dissertação de doutorado de 2000, "Estilos Arquiteturais e Design de Arquitetura de Software Baseado na Web", e o estilo arquitetônico REST define seis restrições orientadoras. Um sistema que se conforma a algumas ou todas essas restrições é chamado de RESTful.


image (Fonte: Seobility)

Restrições das APIs RESTful

RestriçõesDetalhesBenefícios
Arquitetura cliente-servidorMelhora a portabilidade da interface do usuário em várias plataformas, separando as questões da interface do usuário das questões de armazenamento de dados, e melhora a escalabilidade simplificando os componentes do servidor.1. Desacoplamento do lado do cliente e do servidor.
2. Melhora a portabilidade das plataformas do usuário entre plataformas.
3. Melhora a escalabilidade do lado do servidor.
Sem estadoCada solicitação do cliente para o servidor deve conter todas as informações necessárias para a solicitação e não deve fazer uso de qualquer contexto armazenado no servidor, e o estado da sessão é armazenado inteiramente no cliente.1. Fácil de escalar, sem dependências de sessão e qualquer servidor pode lidar com qualquer solicitação.
2. Fácil para cache melhorar o desempenho do programa.
CacheabilidadeExige que os dados em uma solicitação ou resposta sejam implicitamente ou explicitamente marcados como armazenáveis em cache ou não armazenáveis em cache. Se uma resposta for armazenável em cache, então o cache do cliente tem o direito de reutilizar esses dados de resposta para solicitações equivalentes subsequentes.1. Reduz a largura de banda.
2. Reduz a latência.
3. Reduz a carga do servidor.
4. Oculta o status da rede.
Sistema em camadasO comportamento restrito dos componentes permite que a arquitetura seja composta por camadas, de modo que cada componente não possa "ver" além da camada imediata com a qual interage. Ao limitar o conhecimento do sistema a uma única camada, a complexidade de todo o sistema é reduzida e a independência subjacente é promovida.1. Reduz a complexidade do sistema geral.
2. Promove a independência na base.
3. O balanceamento de carga pode ser facilmente implementado.
4. A lógica de negócios e as políticas de segurança podem ser desacopladas.
Código sob demanda (opcional)Permite que a funcionalidade do cliente seja estendida baixando e executando código na forma de applets ou scripts.1. Melhora a escalabilidade do sistema.
Interface uniformeContém quatro pontos principais:
1. Identificação de recursos em solicitações.
Os clientes podem identificar um recurso pelo URI contido na solicitação, desacoplando o recurso do lado do servidor do recurso solicitado pelo cliente.
2. Manipulação de recursos por meio de representações.
Quando um cliente tem a representação de um recurso, como um URI, então há informações suficientes para modificar ou excluir o recurso.
3. Mensagens auto-descritivas.
Cada mensagem inclui informações suficientes para informar ao cliente o que fazer com a mensagem.
4. Hipermídia como o motor do estado da aplicação (HATEOAS).
O cliente não precisa de nenhuma codificação adicional para disponibilizar todos os recursos ao usuário por meio dos links de recursos retornados pelo servidor.
1. Simplifica a arquitetura geral do sistema.
2. Melhora a visibilidade das interações.

Melhores Práticas para APIs RESTful

A ênfase em interfaces unificadas entre os componentes é uma característica central que diferencia o estilo arquitetônico REST de outros estilos baseados na web, e com base nessa característica, as melhores práticas são organizadas aqui para ajudá-lo a projetar melhor sua API.

Evite Verbos no Nome do Caminho

Use métodos HTTP para expressar o comportamento de manipulação de recursos, em vez de definir verbos de comportamento nos caminhos.

// Bom
curl -X GET http://httpbin.org/orders

// Ruim
curl -X GET "http://httpbin.org/getOrders"

  • Obtenha as informações do recurso para o URI especificado usando GET
// Representa obter todas as informações de pedido do sistema atual
curl -X GET http://httpbin.org/orders

// Representa obter as informações detalhadas do pedido para o número de pedido 1
curl -X GET http://httpbin.org/orders/1

  • Crie um recurso a partir do URI especificado usando POST
 // Representa a criação de um recurso com o nome order
curl -X POST http://httpbin.org/orders \
  -d '{"name": "awesome", region: "A"}' \

  • Crie ou substitua totalmente recursos no URI especificado usando PUT
 // Representa a substituição de dados para um pedido com id 1
curl -X PUT http://httpbin.org/orders/1 \
  -d '{"name": "new awesome", region: "B"}' \

  • PATCH realiza uma atualização parcial de um recurso
 // Representa alterar o campo region do pedido com id 1, mantendo o restante dos dados inalterados
curl -X PATCH http://httpbin.org/orders/1 \
  -d '{region: "B"}' \

  • Remova um recurso especificando um URI usando DELETE
 // Representa a exclusão do pedido com id 1
curl -X DELETE http://httpbin.org/orders/1

URIs Usam a Forma Plural

Se você quiser usar a forma singular para indicar o acesso a um tipo específico de recurso:

curl -X GET "http://httpbin.org/order"

Usar a forma singular pode confundir o usuário, fazendo-o pensar que há apenas um pedido no sistema, mas usar a forma plural torna a compreensão muito mais suave.

curl -X GET "http://httpbin.org/orders"

Usando Bem os Códigos de Status HTTP

O padrão HTTP define códigos de status, que podem ser amplamente classificados nas seguintes categorias:

Códigos de StatusSignificado
2xxSucesso, a operação foi recebida e processada com sucesso
3xxRedirecionamento, é necessária uma ação adicional para concluir a solicitação
4xxErro do cliente, a solicitação continha um erro de sintaxe ou não pôde ser concluída
5xxErro do servidor, ocorreu um erro enquanto o servidor processava a solicitação

Usar códigos de status padrão permite que os desenvolvedores identifiquem problemas imediatamente e pode reduzir o tempo necessário para encontrar diferentes tipos de erros.

Controle de Versão

À medida que os requisitos de negócios mudam, as APIs que já estão online provavelmente terão que ser ajustadas de acordo. Se nossas APIs forem usadas por terceiros, é obviamente impossível fazer com que cada cliente mude de acordo com as mudanças de nossas APIs, então é hora de introduzir o conceito de gerenciamento de versão de API, que pode garantir o uso normal das APIs históricas e iterar novas APIs para atender a novos requisitos de negócios.

Os meios comuns de controle de versão são:

  • Controle de Versão por Caminhos nas Solicitações
// Solicitar API v1
curl  http://httpbin.org/v1/orders

// Solicitar API v2
curl  http://httpbin.org/v2/orders

  • Controle de Versão por Parâmetros de Consulta
// Solicitar API v1
curl  http://httpbin.org/orders?version=v1

// Solicitar API v2
curl  http://httpbin.org/v2/orders?version=v2

  • Controle de Versão por Cabeçalho
// Solicitar API v1
curl  http://httpbin.org/orders -H "custom-version: v1"

// Solicitar API v2
curl  http://httpbin.org/orders -H "custom-version: v2"

Como o APISIX Capacita APIs RESTful

Apache APISIX é um gateway de API dinâmico, em tempo real e de alto desempenho. Ele pode ser executado na frente de qualquer serviço de API RESTful e usar plugins para adicionar novos serviços e estender sua funcionalidade, o que está em conformidade com a definição RESTful de Sistema em Camadas. Além disso, para alguns serviços históricos que não seguem a definição de API RESTful, o APISIX também pode ajudá-lo a converter sua interface sem alterar o código de negócios original para que sua interface cumpra a restrição REST de Interface Uniforme, fazendo com que sua API esteja mais em conformidade com a especificação de API RESTful.

Sistema em Camadas: Suporta a Separação da Lógica de Negócios e da Lógica de Segurança

Você pode se concentrar apenas na implementação da lógica de negócios, a lógica de segurança da interface pode ser deixada para os plugins de autenticação do APISIX, por exemplo, key-auth. O APISIX suporta uma grande quantidade de plugins de autenticação, vamos pegar openid-connect como exemplo, como mostrado na figura a seguir:

image Podemos ver que usar o APISIX (Gateway de API) para adicionar uma camada de lógica de autenticação na frente do nosso servidor de negócios pode servir para proteger os serviços upstream, e esse padrão arquitetônico pode ser uma boa maneira de desacoplar sua lógica de negócios da lógica de segurança.

Sistema em Camadas: Suporte a Múltiplos Protocolos de Balanceamento de Carga

O APISIX, como um gateway de API, pode ser configurado entre o lado do cliente e o lado do servidor para atender a diferentes requisitos de carga. Você pode até personalizar a lógica de balanceamento de carga.

Os algoritmos de balanceamento de carga suportados são:

  • roundrobin: Balanceamento round robin com pesos.
  • chash: Hash consistente.
  • ewma: Escolhe o nó com a menor latência. Veja Gráfico EWMA para mais detalhes.
  • least_conn: Escolhe o nó com o menor valor de (active_conn + 1) / weight. Aqui, uma conexão ativa é uma conexão sendo usada pela solicitação e é semelhante ao conceito no Nginx.
  • Balanceador de carga personalizado carregado via require("apisix.balancer.your_balancer")

Interface Uniforme: Tornar APIs Históricas Mais RESTful

Para APIs históricas que existem há muito tempo e não seguem bem as diretrizes de API RESTful, você pode reencapsular a nova API por meio do APISIX para atender a diferentes cenários de negócios sem modificar a lógica original da API.

Como mencionado acima, não devemos ter verbos em nosso caminho.

Por exemplo, se a API histórica tiver a interface /getOrder, podemos fazer o proxy da solicitação da API para a API histórica por meio do plugin proxy-rewrite.

curl http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "methods": ["GET"],
    "uri": "/orders",
    "plugins": {
        "proxy-rewrite": {
            "uri": "/getOrder",
            "scheme": "http",
        }
    },
    "upstream": {
        "type": "roundrobin",
        "nodes": {
            "127.0.0.1:80": 1
        }
    }
}'

Você também pode usar o plugin para operações de versionamento de API.

Quando nossa API histórica tem códigos de status de resposta não padronizados, podemos usar o response-rewrite para fazer o proxy da resposta e modificar o código de status da resposta.

curl http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "methods": ["GET"],
    "uri": "/orders",
    "plugins": {
        "response-rewrite": {
            "status_code": 201,
            "body": "{\"code\":\"ok\",\"message\":\"new json body\"}",
            "vars":[
                [ "status","==",200 ]
            ]
        }
    },
    "upstream": {
        "type": "roundrobin",
        "nodes": {
            "127.0.0.1:80": 1
        }
    }
}'

O exemplo acima representa uma solicitação para modificar o status de 200 para 201 na API solicitando o caminho /orders.

Como o APISIX suporta plugins muito ricos, estou ansioso para que você explore mais maneiras de usá-lo.

Resumo

Este artigo introduz o que é uma API, o que é uma API RESTful e suas melhores práticas. Além disso, este artigo também apresenta como separar a lógica de negócios e a lógica de segurança por meio do APISIX, e como usar o APISIX para tornar os serviços de API históricos mais RESTful sem alterar o código de negócios original. Espero que este artigo ajude você a entender as APIs RESTful.

Share article link