O que é uma API REST?

O projeto das APIs REST ou RESTful (Representational State Transfer) foi elaborado para aproveitar os protocolos existentes. Embora a REST possa ser usada em praticamente qualquer protocolo, ela geralmente emprega o HTTP quando é utilizada em APIs da Web. Isso significa que os desenvolvedores não precisam instalar bibliotecas ou software adicional para tirar proveito de um projeto de API REST. O projeto da API REST foi definido pelo Dr. Roy Fielding em sua dissertação de doutorado em 2000. Ele é notável por sua incrível camada de flexibilidade. Como os dados não estão vinculados a métodos e recursos, a REST tem a capacidade de lidar com vários tipos de chamadas, retornar diferentes formatos de dados e até mesmo mudar estruturalmente com a implementação correta da hipermídia.

Essa liberdade e flexibilidade inerentes ao projeto da API REST permitem que você crie uma API que atenda às suas necessidades e, ao mesmo tempo, atenda às necessidades dos mais diversos clientes. Ao contrário do SOAP, a REST não é restrita ao XML, mas pode retornar XML, JSON, YAML ou qualquer outro formato dependendo daquilo que o cliente solicitar. E, ao contrário do RPC, os usuários não são obrigados a conhecer nomes de procedimentos ou parâmetros específicos em uma ordem específica.

No entanto, existem desvantagens no projeto da API REST. Você pode perder a capacidade de manter o estado na REST, como dentro de sessões, e pode ser mais difícil para desenvolvedores mais novos utilizarem. Também é importante entender o que faz uma API REST RESTful e porque essas restrições existem antes de criar sua API. Afinal, por não entender por que algo é projetado da maneira que é, você pode dificultar seus esforços sem sequer perceber.

Entender o projeto da API REST

Enquanto a maioria das APIs afirmam ser RESTful, elas ficam aquém dos requisitos e restrições afirmados pelo Dr. Fielding. Existem seis restrições importantes no projeto da API REST que devem ser conhecidos ao decidir se esse é o tipo de API certo para o seu projeto.

Servidor do cliente

A restrição do servidor do cliente funciona no conceito de que o cliente e o servidor devem ser separados uns dos outros e autorizados a evoluir individualmente e de forma independente. Em outras palavras, devo ser capaz de fazer alterações no meu aplicativo móvel sem afetar a estrutura de dados ou o projeto do banco de dados no servidor. Ao mesmo tempo, devo ser capaz de modificar o banco de dados ou fazer alterações no meu aplicativo de servidor sem afetar o cliente móvel. Isso cria uma separação de preocupações, permitindo que cada aplicativo cresça e escale independentemente do outro e permitindo que sua organização cresça de forma rápida e eficiente.

Ausência de estado

As APIs REST não têm estado, o que significa que as chamadas podem ser feitas de maneira independente, e cada chamada contém todos os dados necessários para se completar com sucesso. Uma API REST não deve confiar nos dados que estão sendo armazenados no servidor ou nas sessões para determinar o que fazer com uma chamada, mas confiar apenas nos dados fornecidos nessa chamada em si. A identificação de informações não está sendo armazenada no servidor ao fazer chamadas. Em vez disso, cada chamada tem os dados necessários em si, como a chave de API, o token de acesso, o ID de usuário etc. Isso também ajuda a aumentar a confiabilidade da API, tendo todos os dados necessários para fazer a chamada, em vez de confiar em uma série de chamadas com o estado do servidor para criar um objeto, o que pode resultar em falhas parciais. Em vez disso, para reduzir os requisitos de memória e manter seu aplicativo o mais dimensionável possível, uma API RESTful exige que qualquer estado seja armazenado no cliente, e não no servidor.

Cache

Como uma API sem estado pode aumentar a sobrecarga de solicitações ao lidar com grandes cargas de chamadas recebidas e enviadas, uma API REST deve ser projetada para incentivar o armazenamento de dados armazenáveis em cache. Isso significa que, quando os dados podem ser armazenados em cache, a resposta deve indicar que os dados podem ser armazenados até um determinado tempo (expires-at) ou, nos casos em que os dados precisam estar em tempo real, que a resposta não deve ser armazenada em cache pelo cliente. Ao habilitar essa restrição crítica, você não só reduzirá muito o número de interações com a API, reduzindo o uso interno do servidor, mas também disponibilizará aos usuários da API as ferramentas necessárias para fornecer os apps mais rápidos e eficientes possíveis. Tenha em mente que o armazenamento em cache é feito no lado do cliente. Embora você consiga armazenar em cache alguns dados dentro da sua arquitetura para executar o desempenho geral, a intenção é instruir o cliente sobre como ele deve proceder e se o cliente pode ou não armazenar os dados temporariamente.

Interface uniforme

O segredo para dissociar o cliente do servidor é ter uma interface uniforme que permita a evolução independente do aplicativo sem ter os serviços, modelos ou ações do aplicativo firmemente acoplados à própria camada de API. A interface uniforme permite que o cliente fale com o servidor em uma única linguagem, independente do back-end arquitetônico de qualquer um. Essa interface deve fornecer um meio padronizado e imutável de comunicação entre o cliente e o servidor, como o uso de HTTP com recursos URI, CRUD (Create, Read, Update, Delete) e JSON.

Sistema em camadas

Como o nome indica, um sistema em camadas é um sistema composto por camadas, sendo que cada uma tem uma funcionalidade e responsabilidade específicas. Se pensarmos em um framework Model View Controller, cada camada tem suas próprias responsabilidades, com os modelos informando como os dados devem ser formados, o controlador focando as ações recebidas e uma visão focada na saída. Cada camada é independente, mas também interage com a outra. No projeto da API REST, esse mesmo princípio é válido, com diferentes camadas da arquitetura trabalhando juntas para criar uma hierarquia que ajude a criar um aplicativo mais escalável e modular.

Um sistema em camadas também permite encapsular sistemas legados e mover a funcionalidade menos comumente acessada para um intermediário compartilhado, além de proteger os componentes mais modernos e usados. Além disso, o sistema em camadas oferece a liberdade de incluir e retirar sistemas da sua arquitetura à medida que as tecnologias e serviços evoluem, aumentando a flexibilidade e a longevidade, desde que você mantenha os diferentes módulos com o acoplamento mais simples possível. Existem benefícios substanciais de segurança em se ter um sistema em camadas, pois permite que você interrompa os ataques na camada do proxy ou dentro de outras camadas, impedindo-os de chegar à arquitetura de servidor em si. Ao utilizar um sistema em camadas com um proxy ou criar um único ponto de acesso, é possível manter os aspectos essenciais e mais vulneráveis da sua arquitetura atrás de um firewall, impedindo a interação direta com eles pelo cliente. Lembre-se de que a segurança não é baseada em uma única solução de “stop all”, mas sim em ter várias camadas com o entendimento de que certas verificações de segurança podem falhar ou ser ignoradas. Como tal, quanto mais segurança você for capaz de implementar no seu sistema, maior a probabilidade de evitar ataques prejudiciais.

Code on Demand

Talvez a menos conhecida das seis restrições e a única restrição opcional, o Code on Demand permite que o código ou os applets sejam transmitidos por meio da API para uso dentro do aplicativo. Basicamente, ele cria um aplicativo inteligente que não depende mais da própria estrutura de código. No entanto, talvez porque ele esteja à frente de seu tempo, o Code on Demand não tem sido muito adotado, enquanto as APIs da Web são consumidas em diversas linguagens e a transmissão de código gera questões e preocupações de segurança. Por exemplo, o diretório teria que ser gravável, e o firewall teria que permitir o que normalmente pode ser conteúdo restrito.

Juntas, essas restrições compõem a teoria da Representational State Transfer, ou REST. Ao olhar para trás, você pode ver como cada restrição sucessiva se baseia na anterior, eventualmente criando uma interface de programa de aplicativos bastante complexa, mas eficaz e flexível. O mais importante, no entanto, é que essas restrições compõem um projeto que opera de forma semelhante à forma como acessamos páginas nos nossos navegadores na World Wide Web. Elas criam uma API que não é ditada pela arquitetura, mas pelas representações que ela retorna e uma API que, embora seja arquitetonicamente sem estado, depende da representação para ditar o estado do aplicativo.