Como criar a melhor API RESTful: Checklist completo do desenvolvedor

Existem diferentes tipos de serviços móveis e web atualmente. Aplicativos de viagem, transporte, redes sociais, aplicativos de saúde e fitness e vários outros.
Mesmo que possam ser diferentes em termos de recursos que fornecem, esses aplicativos têm uma coisa em comum – todos eles têm uma arquitetura cliente-servidor, o que significa que eles se comunicam constantemente com os servidores através da Internet.
APIs RESTful se tornaram o principal padrão para permitir a comunicação entre a parte do servidor de um produto e seus clientes, tanto web quanto móvel. É por isso que projetar APIs RESTful claras e suaves é um tópico quente.
Reconhecemos a importância de APIs abrangentes e bem projetadas. Idealmente, sua API RESTful deve oferecer suporte a diferentes tipos de clientes e deve ser facilmente compreensível por qualquer desenvolvedor. A qualidade do seu projeto depende disso.
Então, o que você deve ter em mente ao projetar uma API? Preparamos um artigo com as melhores práticas que o ajudarão a evitar os principais erros associados ao design de API, como documentação mal escrita, arquitetura não estruturada, inconsistência, falta de segurança e rigidez.

Documentação da API RESTful

A documentação é uma introdução à API que ajuda os desenvolvedores a entender sua API RESTful e dá a eles uma pista sobre por onde começar. Ao documentar sua API, você pode aumentar o conhecimento e a adoção da API e diminuir o tempo e os custos de integração de desenvolvedores remotos e internos. Além disso, a documentação ajuda suas equipes internas a conhecer os detalhes de seus métodos, recursos, solicitações e respostas, tornando a manutenção e as atualizações mais fáceis e rápidas.
Idealmente, você deve escrever tutoriais claros para ajudar os desenvolvedores a começar a trabalhar mais rápido e com mais facilidade. Não negligencie a criação de um dicionário onde você define os termos usados ​​em sua API. Você deve definir os recursos e métodos usados ​​de uma maneira que seja fácil de entender.
Certifique-se de listar todos os termos usados ​​em seu projeto e colocar todos na mesma página para que seus usuários finais (desenvolvedores) possam obter o conceito de URLs e URIs, por exemplo, mesmo sem entender totalmente a tecnologia por trás deles.
O LinkedIn tem uma página separada com a terminologia usada em sua API.
Felizmente, existem muitas ferramentas de software (Swagger, Raml, Apiary, etc.) que simplificam a tarefa de gerar documentação.

Formatos de dados suportados para API RESTful

Na arquitetura cliente-servidor, uma API é uma ponte que conecta o cliente ao servidor. É por isso que sua API deve enviar e receber informações em um formato conveniente e compreensível para ambas as partes. Sua escolha de formato de dados define o quão eficaz sua API funcionará, afetando o sucesso de chamadas de rotina e específicas.
Os formatos de dados comuns usados ​​em APIs modernas são:

  • Formatos de dados diretos. Eles são projetados para lidar com dados para uso direto em outros sistemas (usuários). Eles são melhores para interação com outras APIs e para integração máquina a máquina. Os três formatos de dados diretos mais comuns são JSON, XML e YAML.
  • Formatos de dados de feed. Formatos desse tipo são normalmente usados ​​para serializar atualizações de servidores, sites e interfaces de front-end e alertar os usuários sobre essas alterações. Os formatos de dados de feed – que incluem RSS, Atom e SUP – são mais usados ​​para blogs, compartilhamento de vídeo e mídia social.
  • Formatos de dados de banco de dados. Esses formatos são normalmente usados ​​para lidar com a comunicação entre bancos de dados e entre bancos de dados e usuários. Os formatos nesta categoria incluem CSV e SQL.

Identificadores Uniformes de Recursos da API RESTful

O principal princípio do REST é dividir sua API em recursos lógicos. Um Uniform Resource Identifier, ou URI, é uma sequência de símbolos que identifica um recurso e geralmente permite que os desenvolvedores acessem as representações desse recurso. A estrutura e a sintaxe atuais dos URIs são definidas pelo padrão RFC 3986.
Neste ponto, não podemos evitar a pergunta permanente: quais são as diferenças entre um URI e um URL? Na verdade, um URL (Uniform Resource Locator) e um URN (Uniform Resource Name) são os dois tipos de URIs.
Um URL identifica a localização de um determinado recurso e como você pode recuperá-lo; por exemplo: http://example.com/example.html
Um URN identifica o recurso por seu nome, mas não mostra necessariamente sua localização. Geralmente começa com um prefixo urn:; por exemplo:urn:uuid:6e7bc280-7c3a-11d9-9889-0800200c9a66
Seu URI deve comunicar claramente o modelo de recursos da API. Coletamos várias regras para ajudá-lo a projetar URIs claros e bonitos:

  1. Use hifens, mas não sublinhados, para tornar seu URI legível. Esta é uma boa prática: http://api.example.com/best-products/home-decor. Esta é uma prática ruim: http://api.example.com/best_products/home_decor/. Os sublinhados são quase invisíveis devido ao sublinhado e podem causar confusão.
  2. Não inclua extensões em URIs. Deixe a determinação do tipo de conteúdo no corpo para o cabeçalho Content-Type.
  3. Use letras minúsculas, se possível. Lembre-se de que todos os componentes URI, exceto os componentes do host e o esquema, diferenciam maiúsculas de minúsculas. Isso significa que http://api.example.com/best-products/home-decore http://API.EXAMPLE.COM/best-products/home-decor são idênticos. Mas http://api.example.com/My-Folder/my-docé um URI completamente diferente.
  4. Use uma barra para indicar relacionamentos. Evite usar uma barra invertida, pois pode causar confusão. Algumas APIs apenas redirecionarão os usuários para um URI sem uma barra, mas outras enviarão a resposta 301: Movido Permanentemente.
  5. Em geral, cada recurso de sua API terá pelo menos um URI. É por isso que cada URI deve descrever adequadamente o recurso e seguir uma estrutura hierárquica previsível para melhorar a usabilidade.

Endpoints 

Os terminais especificam onde os recursos estão localizados e como eles podem ser acessados ​​por software de terceiros. Normalmente, eles são acessados ​​por meio de um URI para o qual as solicitações HTTP são enviadas e de onde a resposta é esperada.
Se você pesquisar ‘O que é uma API RESTful’, encontrará a seguinte definição: uma interface de programa de aplicativo que usa solicitações HTTP para GET, PUT, POST e DELETE dados. Então, o que são GET, PUT, POST, DELTE e por que estão capitalizados? Estes são os principais métodos que indicam que tipo de operação deve ser realizada. Vamos dar uma olhada neles:

  • GET – recupera recursos do servidor usando um determinado URI
  • POST – enviar recursos para o servidor
  • PUT – atualiza as informações existentes com o conteúdo carregado
  • DELETE – remove todos os recursos existentes

Assim como com URIs, nomear terminais de recursos é crucial para a usabilidade da API. Aqui estão algumas dicas sobre como nomear pontos de extremidade:

  • Use substantivos (não verbos) ao sugerir o nome do caminho do recurso; no nosso caso, vamos chamar o caminho de fotos. A seguinte nomenclatura de recursos deve ser totalmente evitada: / getAllPhotos, / createPhoto, / updatePhoto, / deletePhoto.
  • Não misture substantivos no singular e no plural. Embora você possa considerar errado descrever uma única instância de um recurso usando uma forma plural, as regras de design da API afirmam que você deve ser consistente e sempre usar substantivos no plural para todos os recursos. Use em /settingsvez de /setting e em /productsvez de /product.
  • Use sub-recursos para relações se um recurso estiver relacionado a outro recurso. Por exemplo, GET /products/:id/reviewsretorna uma lista de análises para um produto específico e GET /products/:id/reviews/:id retorna uma análise específica para um produto específico.

Controle de versão

APIs mudam lentamente, mas ainda mudam. Vamos ser muito claros sobre isso: mesmo que sua API RESTful seja completamente reescrita e atualizada várias vezes, você deve manter as versões antigas de sua API em execução e com suporte pelo tempo que seus usuários precisarem. Existem quatro maneiras comuns de criar uma versão de uma API RESTful para que os usuários ainda possam contar com as versões anteriores e fazer upgrade para as versões subsequentes quando estiverem prontas:

  1. URI. Com esse método, uma versão é colocada explicitamente no URI da API. (Exemplo: api.example.com/v1/resource or example.com/api/v1/resource)
  2. Cabeçalhos de solicitação personalizados. As APIs também podem ter controle de versão fornecendo cabeçalhos personalizados com o número da versão incluído como um atributo. (Exemplo: curl -H “API-version: 1.0” http://www.example.com/api/products)
  3. Controle de versão de tipo de mídia (também conhecido como negociação de conteúdo ou cabeçalho de aceitação). Nesse caso, você modifica o cabeçalho de aceitação para especificar a versão. (Exemplo: curl -H “Accept: application/vnd.example.v2+json” http://www.example.com/api/products)

4.Controle de versão de parâmetro. Outra opção é incluir o número da versão como um parâmetro de consulta. (Exemplo: http://www.example.com/api/products?version=1)

Segurança e autenticação

Sempre proteja as informações do aplicativo de hackers e outros usuários duvidosos. Aqui estão algumas regras essenciais para garantir a segurança durante o desenvolvimento de back-end:

  • Use HTTPS. Uma API RESTful segura deve fornecer apenas terminais HTTPS. Essa é uma boa maneira de proteger as credenciais de autenticação, como chaves de API, senhas e JSON Web Tokens (JWT).
  • Adicione um carimbo de data / hora às solicitações HTTP. Junto com outros parâmetros, inclua um carimbo de data / hora para sua solicitação. Desta forma, o servidor pode comparar o carimbo de data / hora do pedido com o carimbo de data / hora atual e aceitar o pedido apenas dentro de um determinado período de tempo, por exemplo, um ou dois minutos. Isso elimina casos de ataques de repetição de hackers que tentam usar força bruta no sistema.
  • Restrinja os métodos HTTP. Crie uma lista de métodos permitidos e rejeite todas as solicitações que não estejam nesta lista. Além disso, certifique-se de que o chamador está autorizado a usar o método HTTP de entrada no recurso.
  • Considere a validação de entrada. Valide os parâmetros de solicitação na primeira etapa. Coloque verificações de validação fortes em vigor e rejeite uma solicitação imediatamente se a validação falhar. Valide o tipo de entrada, comprimento, formato e intervalo.
  • Use OAuth. Embora a autenticação básica seja boa e segura o suficiente, considere o OAuth. A estrutura de autorização OAuth 2.0 permite que aplicativos de terceiros obtenham acesso limitado a um serviço HTTP, seja em nome de um proprietário de recurso orquestrando uma interação de aprovação entre o proprietário do recurso e o serviço HTTP ou permitindo que o aplicativo de terceiros obtenha acesso em seu próprio nome.
  • Não exponha dados confidenciais em URLs. Nomes de usuário, senhas, JWT e chaves de API nunca devem aparecer em um URL. Se o fizerem, eles podem ser capturados em logs do servidor da web, tornando-os facilmente exploráveis.
  • Execute verificações de segurança. Criar uma lista de verificação de segurança para minimizar a possibilidade de injeções de SQL e XSS: proteger cabeçalhos, sessões e cookies e permitir parâmetros; ocultar dados confidenciais em registros; usar tokens CSRF; validar redirecionamentos e encaminhamentos; implementar verificação de senha de segurança forte; proteger bancos de dados, etc. Para simplificar essas tarefas, você pode usar ferramentas automatizadas como Brakeman.

As empresas usam APIs para conectar serviços e transferir dados. APIs quebradas, expostas ou hackeadas estão por trás das principais violações de dados. Uma API mal protegida pode ser arriscada para uma empresa e, portanto, os desenvolvedores não vão querer usá-la.

Escalabilidade e flexibilidade

Escalabilidade é a capacidade do sistema de lidar com um número crescente de solicitações de maneira rápida e estável ou a capacidade do sistema de ser expandido para acomodar o crescimento. É uma consideração importante para todas as plataformas de API.
Existem dois tipos de escalabilidade: vertical (use uma máquina mais potente) ou horizontal (distribua a carga por várias máquinas). Se uma nuvem for usada, ela pode dimensionar automaticamente o sistema.
Antes de projetar um sistema, você deve avaliar sua carga estimada (solicitações por segundo, tamanho das solicitações, etc.). Durante o tempo de atividade do sistema, você deve verificar várias métricas, como distribuição de carga, latência e tempo de resposta.

Escalabilidade na sua API

Projete a arquitetura de sua API com escalabilidade em mente.
Dessa forma, quando seu aplicativo crescer, você não terá problemas para adicionar novos recursos e melhorar o desempenho. Para fazer isso, mantenha a arquitetura simples. Para resolver problemas de escalabilidade, é preferível usar uma nuvem.
Os serviços em nuvem permitem que você inicie rapidamente novas instâncias de servidor sob demanda, em vez de adicionar equipamentos caros para lidar com mais dados.
Além disso, é importante realizar a otimização manual do código, que envolve a análise do código manualmente para definir as partes com baixo desempenho e otimizá-las.

Monitoramento e tratamento de erros

Monitorar o acesso à API em tempo real e as tendências de uso é fundamental. É importante obter controle sobre o tratamento de exceções para que você possa fornecer informações importantes que permitam aos clientes da API saber o que acontece no servidor.
Todas as exceções devem ser mapeadas em uma carga útil de erro. Normalmente, é importante demonstrar de onde veio um erro. Também é importante fornecer algumas orientações sobre como corrigir uma chamada com falha.
Se você construir sua API usando Ruby on Rails, você pode usar a gem exception_notification para configurar rapidamente os canais de notificação mais usados, como email, Slack e WebHooks. Ou, se precisar visualizar estatísticas, você pode usar serviços de terceiros como Honeybadger, Sentry e NewRelic.

Códigos de status HTTP

Os códigos de status HTTP, às vezes chamados de códigos de erro da Internet ou do navegador, são códigos de resposta padrão enviados por um servidor da web que identificam se uma operação realizada foi bem-sucedida ou por que as páginas ou recursos não estão sendo carregados corretamente.
Eles também ajudam os desenvolvedores na solução de problemas e tratamento de erros.
Existem cinco categorias de respostas e mais de cinquenta códigos de resposta. Criamos uma lista dos códigos mais comumente usados:

2XX (sucesso)

200: OK. Esta é a resposta mais comumente usada para informar que uma solicitação foi bem-sucedida.
201: Objeto criado. O servidor atendeu à solicitação e criou um novo recurso.
204: Sem conteúdo. O servidor atendeu à solicitação e a API se recusa a enviar de volta qualquer mensagem de status ou representação no corpo da mensagem de resposta.
206: Conteúdo parcial. O servidor atendeu à solicitação e o corpo contém os intervalos de dados solicitados, conforme descrito no cabeçalho Range da solicitação.

3XX (redirecionamento)

304: Não modificado. O cliente solicitou dados em cache e não há necessidade de transferi-los novamente.

4XX (erro do cliente)

400: Pedido inválido. O servidor não conseguiu compreender o pedido devido a uma sintaxe inválida (por exemplo, enquadramento de mensagem de pedido inválido ou encaminhamento de pedido enganoso).
401 não autorizado. O usuário ou o sistema está tentando operar em um recurso protegido sem fornecer credenciais de autenticação adequadas.
403: Proibido. O servidor entende a solicitação, mas se recusa a autorizá-la.
404 não encontrado. O servidor de origem não consegue encontrar uma representação atual para o recurso de destino ou não está disposto a divulgar que existe.
5XX (erro do servidor)
500: Erro interno do servidor: O ideal é que você não retorne isso explicitamente, mas se algo quebrar inesperadamente, é isso que seu usuário receberá.
503 serviço indisponível: O servidor atualmente não consegue lidar com a solicitação devido a uma sobrecarga temporária ou manutenção programada.
Esses são códigos de status padrão, mas são extensíveis. Se você criar códigos de resposta HTTP personalizados, certifique-se de colocá-los na categoria correta. Lembre-se de que não é uma boa prática, pois alguns proxies filtram códigos desconhecidos.
Quer você crie códigos personalizados ou padrões, documente-os sempre. Aqui está um exemplo de códigos de status na documentação da API do Twitter.

Teste, estabilidade e suporte da API Restful

Sempre use ferramentas de teste para testar facilmente os terminais e verificar suas respostas. Existem várias ferramentas disponíveis para automatizar a rotina de teste: Rspec, API Fortress, API Science, Parasoft, Postman, SmartBear, Runscope, etc.

Manutenibilidade

Após uma implantação bem-sucedida, vem a manutenção e o suporte contínuos. Isso inclui manter o sistema operacional, investigar falhas, corrigir bugs e adicionar novos recursos.
Manter o sistema operacional envolve:
– Aplicação de patches e correções
– Capacidade de planejamento
– Melhorar o gerenciamento de configuração
– Preservando a base de conhecimento sobre o sistema
Adicionar novos recursos requer adaptação fácil às mudanças. Isso está intimamente ligado à simplicidade e abstrações do sistema. Sistemas simples e fáceis de entender são fáceis de modificar.

Cache

O cache é usado para armazenar dados solicitados com frequência (ou os mais recentes) em algum armazenamento de acesso rápido (na memória ou sem memória) para atender rapidamente a uma solicitação.
Usando cabeçalhos HTTP, um servidor de origem indica se uma resposta pode ser armazenada em cache e, em caso afirmativo, por quem e por quanto tempo.

Navegadores

Normalmente, os navegadores tratam todas as solicitações GET como armazenáveis ​​em cache.
As solicitações POST não são armazenáveis ​​em cache por padrão, mas podem ser armazenadas em cache se você adicionar um cabeçalho expires ou um cabeçalho Cache-Control à resposta.
As respostas às solicitações PUT e DELETE não podem ser armazenadas em cache.
Existem quatro cabeçalhos de resposta HTTP principais que podemos usar para controlar o comportamento do cache:

Expires

O cabeçalho HTTP Expires especifica um tempo de expiração absoluto para uma representação em cache. Após esse período, a representação em cache é considerada obsoleta e deve ser revalidada com o servidor de origem.
Para indicar que uma representação nunca expira, um serviço pode incluir um período de até um ano no futuro.

Cache-Control

O valor do cabeçalho compreende uma ou mais diretivas separadas por vírgula. Essas diretivas determinam se uma resposta pode ser armazenada em cache e, em caso afirmativo, por quem e por quanto tempo. Diretivas disponíveis:
– public – indica que um recurso pode ser armazenado em cache por qualquer componente.
– privado – indica que um recurso pode ser armazenado em cache apenas pelo cliente e pelo servidor (nenhum intermediário pode armazenar o recurso em cache).
– no-cache / no-store – indica que um recurso não pode ser armazenado em cache.
– max-age – indica que os dados em cache são válidos até max-age em segundos. Depois disso, o cliente deve fazer outro pedido.
– s-max-age – Substitui max-age para um cache compartilhado, como em servidores proxy. Normalmente, você tem mais controle sobre o cache do proxy do que o cache local do cliente, portanto, pode adicionar valores mais longos aqui.
– must-revalidate – Diz ao servidor para revalidar o recurso se max-age tiver passado.
Exemplo: Cache-Control: max-age=3600`
As respostas armazenáveis ​​em cache (seja para uma solicitação GET ou POST) também devem incluir um validador: um ETag ou um cabeçalho Last-Modified.

·        ETag

Um valor ETag é um token de string opaco que um servidor associa a um recurso para identificar exclusivamente o estado desse recurso durante sua vida útil. Quando o recurso muda, o ETag muda de acordo. Exemplo: `ETag: “abcd1234567n34jv”`

·        Última modificação

Enquanto o cabeçalho Date de uma resposta indica quando a resposta foi gerada, o cabeçalho Last-Modified indica quando o recurso associado mudou pela última vez. O valor da Última Modificação não pode ser posterior ao valor da Data.
Além disso, é uma boa ideia usar camadas de cache não apenas em HTTP, mas ao longo de todo o pipeline de processamento de solicitação (memcached, Redis, Cassandra).

Pesquisar, filtrar e classificar a API Restful

Filtros de resultados complexos, requisitos de classificação e pesquisa avançada podem ser facilmente implementados como parâmetros de consulta na parte superior da URL base e facilitar muito a vida dos desenvolvedores.
Para filtrar um conjunto de dados, passe um parâmetro de consulta exclusivo para todos os campos por meio da linguagem de consulta. Os parâmetros de URL são a maneira mais fácil de adicionar filtragem básica às APIs REST. Por exemplo:
GET /dogs?breed=Akita&age<=2
Para classificar itens, use o parâmetro de URL de classificação. Para habilitar requisitos de classificação complexos, deixe o parâmetro de classificação obter uma lista de campos separados por vírgulas, com um possível negativo unário para habilitar uma ordem de classificação decrescente. Por exemplo:
GET /dogs?sort=-breed,+name or  GET /dogs?sort=breed_desc,name_asc
Às vezes, os filtros básicos não são suficientes e você precisa do poder da pesquisa de texto completo. Se você precisar de pesquisa em terminais, poderá adicionar suporte para filtros e intervalos diretamente com o parâmetro de pesquisa. Você pode usar ElasticSearch ou outra tecnologia de pesquisa baseada em Lucene.

Paginação 

Para manter seus servidores satisfeitos, a API RESTful precisa paginar automaticamente os itens solicitados. Quando o conjunto de dados for muito grande, divida-o em partes menores.
Isso é útil para melhorar o desempenho e torna mais fácil lidar com as respostas. Torne a paginação mais flexível, suportando parâmetros por página.
GET /dogs?page=3&per_page=20
Ao criar uma API, você deve se lembrar constantemente que, se for mal projetada, documentada ou suportada, ninguém a usará, a menos que seja forçado. O design de uma API RESTful deve se concentrar em uma combinação de funcionalidade, usabilidade e experiência do desenvolvedor.
Esperamos que este tutorial ajude você a construir uma API RESTful amigável e eficiente para o desenvolvedor. Se você tiver dúvidas ou precisar de ajuda para criar sua API, pode sempre contar conosco.
Quer saber mais sobre negócios e tecnologia? Basta preencher o formulário abaixo que te nós da Codificar te manteremos informado sobre estratégias e ferramentas para alavancar sua empresa ou colocar a sua ideia em prática.