Criando uma API REST escalável usando Serverless, API Gateway e DynamoDB

Quando entrei no Zé Delivery, descobri que as APIs serverless foram fundamentais para que a empresa aguentasse, de forma saudável, a carga proveniente do crescimento acelerado durante a pandemia. Até este momento, eu sempre achei que não era uma boa ideia usar serverless para uma API tão grande, porém, ao ver os resultados eu mudei de ideia rapidamente. Eu achei tão maravilhoso que decidi falar sobre isso em um workshop no evento DoWhile 2020 da Rocketseat, e escrevi este artigo baseado nele.
O objetivo deste artigo é mostrar algumas das tecnologias usadas no Zé, como Serverless Framework, API Gateway, Lambda e DynamoDB e quais são as vantagens e desvantagens de utilizá-las.
Caso você queira ver o repositório do workshop, que é uma API REST feita em Node.js e que usa estas tecnologias, clique aqui.
O Zé Delivery
O Zé Delivery é uma empresa de delivery de bebidas que cresceu exponencialmente durante a pandemia, tendo que suportar uma carga muito maior de requisições. Existem picos de acesso muito altos ao longo do dia, ou seja, em algumas horas são realizados quase todos os pedidos do dia.

Mas mesmo com o crescimento brutal causado pela pandemia de COVID-19 em 2020 (imagine, as pessoas não podem mais beber em bares ou sair livremente para comprar bebidas, e tem um aplicativo que vende as bebidas a um preço baixo e entrega elas geladas e bem rápido), o Zé Delivery conseguiu suportar muito bem, escalando de uma forma que não exigiu que as pessoas ficassem subindo máquinas loucamente de madrugada por que um servidor ficou sem memória ou a CPU está "topando".
Acho que você já percebeu aonde quero chegar, no Zé Delivery a maior parte dos serviços são feitos utilizando serverless, no caso Lambdas com API Gateway e em muitos casos, o DynamoDB como banco de dados. Ao usar estas ferramentas, podemos contar com uma alta disponibilidade e um auto scaling muito eficiente, sem termos que nos preocupar em subir/desligar máquinas na mão, além do que, pagamos pelo que usamos, sem ter que provisionar mais máquinas do que o necessário com o intuito de termos uma gordura para os horários de pico.
As ferramentas
Aqui vou falar brevemente sobre o que são as ferramentas que listei anteriormente e depois vou falar algumas das vantagens e desvantagens que pude observar neste tempo que as utilizei.
Serverless Framework

O Serverless Framework, que é a única ferramenta que não é da AWS na minha lista, facilita bastante o deploy de funções e outros recursos em diversas clouds diferentes. Com ele você pode usar um arquivo, geralmente chamado de serverless.yml
para configurar o que você precisa e utilizar um CLI para fazer o deploy. No caso da AWS, quando você faz um deploy usando o Serverless Framework, é criada uma stack no CloudFormation, e lá você pode acompanhar com detalhes o provisionamento dos seus recursos.
Se você quiser utilizar Serverless na AWS. Sugiro que estude as seguintes ferramentas:
- IAM: Para utilizar Serverless com AWS, você vai precisar de um usuário que será utilizado para o deploy, e este usuário precisa ter as permissões corretas. Além disso, ao criar recursos e definir o que tem acesso a que, é bom saber como funciona o IAM para não acabar criando brechas de segurança por falta de conhecimento.
- CloudFormation: Você não precisa necessariamente acompanhar a criação da stack pelo CloudFormation, mas pode ser que eventualmente aconteça algum erro na criação e você fique no escuro até acessar diretamente a stack para ver os problemas. É sempre bom ter essa carta na manga.
- S3: Como no caso do CloudFormation, você não necessariamente precisará acessar para saber o que está acontecendo, porém é bom saber que os arquivos da sua Lambda ficaram em um bucket do S3, inclusive muitas vezes ao deletar a stack, acontece algum problema no S3 e você tem que manualmente apagar algum bucket.
Lambda
As Lambdas são as funções em si, é aqui que sua lógica é implementada. Suas funções serão invocadas com determinados parâmetros e você deve executar sua lógica em cima deles (caso sua lógica dependa dos parâmetros é claro). Quando se usa lambdas, você não enxerga a máquina na qual seu código é executada, elas basicamente são invocadas e podem te retornar uma resposta.
Não vou entrar em detalhes sobre como elas funcionam e quais linguagens suportam, mas vou deixar uma dica de ferramenta a se saber além da lambda caso queira usar em produção, que é o Cloudwatch, usado para monitorar diversos recursos na AWS, e é aqui que você vai poder ver logs e erros das suas lambdas, muito útil na hora de debugar.
Vantagens de se usar Lambda:
- Não se preocupar em subir mais máquinas para suportar picos de carga;
- Pagar apenas pelo tempo que elas estão executando;
- Integrações com outras ferramentas da AWS.
Mas, também tem desvantagens:
- Código fica atrelado ao modelo da AWS, sendo que podem ser necessárias modificações caso você mude seu provedor de Cloud;
- Se sua aplicação crescer muito, é preciso estar atento a alguns limites, como o número de Lambdas rodando concorrentemente;
- Há um tempo de cold start que é o tempo que uma lambda leva para "subir" caso ela não esteja rodando ainda. Este tempo, apesar de não ser muito grande, varia de tecnologia para tecnologia e no caso de APIs REST, é o tempo a mais que o client fica esperando a resposta;
- Caso você use um banco de dados, você precisa garantir que ele vai aguentar o número de conexões geradas pelas lambdas.
API Gateway
API Gateway é o gerenciador de APIs da AWS. Ele facilita bastante o gerenciamento dos seus endpoints, inclusive tratando-se de segurança, além de que com ele é possível invocar suas funções lambda através de endpoints REST.
Vantagens de se usar API Gateway:
- Integração com as funções lambda;
- Fácil gerenciamento e visualização dos endpoints;
- Suporte a CORS, controle de autorização e acesso e fácil monitoramento.
Desvantagens:
- Você acaba perdendo o controle total que teria sobre a sua aplicação, um exemplo: endpoints que não existem podem acabar retornando um 403, o que pode ser meio confuso em algumas situações.
DynamoDB
O DynamoDB é um banco NoSQL que é totalmente gerenciado. Você não precisa se preocupar com máquinas nas quais vai subir o banco ou tunar sistemas operacionais, tudo isso é feito pela AWS. Você também pode pagar por leituras e escritas, pagando apenas quando utilizar.
As vantagens:
- Altamente escalável;
- Pague pelo que usar.
Desvantagens:
- Curva de aprendizado: você vai precisar aprender como funcionam os dados no DynamoDB (apesar de não ser muito complexo, ele tem sua própria forma de funcionar);
- Um pouco mais difícil de prever os custos;
- Dependência de um banco que fica necessariamente na AWS.
Conclusão
Este artigo aborda brevemente algumas vantagens e desvantagens do uso de algumas ferramentas da AWS. Lembre-se de que não existe a bala de prata (metáfora para designar uma solução simples para um problema complexo com grande eficiência), você precisa ter o conhecimento das opções para escolher a que melhor se adequa a suas necessidades sempre, mesmo que pareça que algumas ferramentas resolverão todos os seus problemas.