Executando verificação de segurança...
5

Checklist para desenvolver uma API de respeito

Existem alguns detalhes que vão além de só fazer funcionar, alguns caprichos vão melhorar a experiência de quem consome suas APIs e ainda torná-la um pouco mais segura.

Vamos montar juntos um checklist de itens que são cruciais para o bom desenvolvimento de uma API? Vou começar listando os tópicos e voltarei atualizando cada tópico com a ajuda de vocês.

É verdade que muitos frameworks já fornecem muito destes itens por padrão, mas vamos tentar montar um guia framework-less. Ou seja, o que deve ser pensado independente de qual sua linguagem ou framework.


1. Validação do Request

Nunca pense que o consumidor vai realmente passar os dados corretos como você informar. E se ele passar um negativo enquanto seu banco está com o campo integer? Você vai retornar o erro de banco para ele?

Validar o payload antes mesmo de processá-lo é muito importante, além de melhorar a segurança da sua API, ainda ajudará a tornar os retornos mais amigáveis. Acredite, parece algo superfícial mas é de extremo valor.

2. Tratativa de Erros Padrão

Também é importante que os erros sejam tratados. Caso dê algum erro imprevisto, talvez por alguma tratativa de banco que você não conhecia ou pensou, talvez por alguma falha de integração entre multiplos serviços, etc.. É uma boa prático você ter um arquivo para controlar os retornos de erros, algo como um ErrorHandler. De forma que você possa fazer um try catch no seu controlador e retornar o ErrorHandler com a exceção capturada. E lá no ErrorHandler, você pode ter um retorno padrão mas também pode tratar as exceções uma a uma.

3. Paginação

Para proteger sua aplicação e melhorar a experiência de seus consumidores, você não vai querer permitir que uma lista de usuários com 10mil linhas seja entregue no request, certo? Para isso que nos ajudará a paginação. Existem maneiras de fazer isso, eu particularmente gosto muito de utilizar os atributos: offset e limit, fica simples de implementar no backend e simples de utilizar no frontend.

4. Documentação - Swagger e OpenAPI

Documentar como sua API pode ser consumida, ajudará você a manter os padrões estabelecidos pela equipe, facilitará a vida do seu consumidor e ainda te dará certos poderes como:

Automatizar criação de pacotes para o consumo da API

Existem pacotes que pegam a sua documentação gerada, e criam para você pacotes para diversas linguagens. Como se fosse um SDK da sua API, simplificando a vida do consumidor, seja ele um serviço rodando em node, python ou php.

Facilitar a importação para o Insominia ou Postman

Com o arquivo gerado pelo swagger, você pode facilmente importar todas as rotas da sua API para seu aplicativo favorito.

5. Validação e Padrão do Response

É importante que sua API tenha um padrão nas respostas. Ou seja, utilizar um formato de payload comum entre todas as respostas e também utilizar STATUS CODES corretos.

Além disso, é importante validar a saída deste response, não apenas entregar o resultado do banco de dados, mas validar a saída na modelagem do response. Ou seja, se o consumidor está chamando algo como users/{id}, nós podemos modelar o response para algo como: { id: "2", name: "usuario X" }. De forma que, mesmo que o seu ORM retorne o password, o mesmo não será entregue na requisição.

6. Testes Automatizados

É crucial que suas APIs possuam testes automatizados para que você não fique refém de ter que testar tudo manualmente a cada mudança. Os testes em APIs podem ser simples de se fazer e bastante reaproveitados, com simples chamadas em cada endpoint e uma validação se o payload recebido é como esperado.

Testes de APIs bem modelados podem ajudar a prevenir mudanças que ferem as regras de negócios pensadas lá atrás no inicio do projeto e que que realmente não devem ser alteradas.

Por exemplo, você pode fazer um teste para validar que caso alguém tente alterar o last_name do usuário, ele não será alterado. Um teste pode ajudar a garantir que essa simples regra não seja quebrada quando houver alguma mudança no método de atualização do usuário.


Lembrando que a ideia desta publicação é unirmos nosso conhecimento para montar um guia bem organizado e modelado. E aí, o que podemos incluir/alterar?

Carregando publicação patrocinada...
1

Que ideia genial pedir envolvimento da comunidade para montar essa lista srdavidsilva! Quero fazer minha contribuição:

Cache com stale-while-revalidate

Isso foi uma das últimas coisas mais legais que aprendi sobre APIs e pode revolucionar a performance de uma aplicação (caso ela possa se utilizar desse recurso) e o princípio por trás já está no nome stale-while-revalidate que traduzindo fica mais ou menos como "obsoleto enquanto revalida".

Imagina uma aplicação onde você faz uma request GET contra um endpoint /users e esse endpoint naturalmente retorna todos os usuários. Dado as características dessa aplicação de exemplo, esse é um endpoint muito devagar de retornar, chegando a demorar 10 segundos a cada request.

Por não ser um endpoint que você não precisa dos dados em tempo-real, ao aplicar o cabeçalho stale-while-revalidate, a primeira request contra esse endpoint continuará devagar da mesma forma como antes, mas terá um efeito colateral muito importante que é o resultado ter sido cacheado (e você pode definir as regras do cache). Mas isso significa que uma segunda request vai ser respondida instantâneamente (talvez com dados obsoletos), mas que por trás dos panos, o backend está fazendo uma nova consulta para atualizar esse cache o mais rápido que conseguir.

Então todas as requests dali para frente são respondidas instantaneamente, enquanto o backend se responsabiliza por ficar somente atualizando esse cache. Se você notar, isso é duplamente poderoso, pois você tira o peso do lado do client (do lado que consome o dado) e principalmente tira o peso do lado do server (do lado que produz o dado) porque independente da quantidade de requests que chegarem, todas vão cair o cache e o server vai só trabalhar uma vez.

Isso eu aprendi usando o Next.js junto com a CDN da Vercel, mas isso não é exclusivo deles. Hoje no TabNews isso está sendo usado na página de status mas eu quero fazer um ajuste na configuração do stale-while-revalidate.

3

Nossa, sensacional, excelente caminho!

Eu tive o prazer de implementar uma API onde o cache ajudou a gente a escalar em um nível absurdo. Mas eu não tive essa ideia genial, nós fizemos um midleware e incluímos na frente de todas as rotas pássiveis de cache com um tempo de expiração padrão. Ficou algo universal para o serviço, usando Redis, cada entrada era a própria rota com os query params ordernados, para não repetir.

Tivemos até o pensamento de como seria fazer algo assim a nível de infraestrutura em contextos de microserviços, imagina definir que determinada rota terá cache no esquema do ingress, ficando abstrato para o serviço. Pensa no time de SRE vendo tal rota GET explodindo e ativa um cache só nela para amenizar o serviço. Nunca trabalhei com time de SRE profissional, talvez tenha soluções mais inteligentes para essa minha ideia kk

0
0