A construção de APIs com Serverless tem ganhado cada vez mais espaço no mercado tecnológico. Neste artigo, você irá conferir um tutorial sobre a criação de API, desenvolvendo CRUD de usuários, utilizando Typescript e o banco de dados DynamoDB.
[adrotate banner=”4″]
Utilizaremos também o framework Serverless para a criação das configurações iniciais e da estrutura básica de código.
Requisitos Básicos:
- NodeJS;
- Conta na AWS;
- Yarn;
- Framework Serverless;
- Aws-Sdk;
- Insomnia;
- Java:
- No Ubuntu: default-jdk para ubuntu (sudo apt install default-djk)
- No Windows: Java
O que é o Serverless?
Serverless é um modelo de desenvolvimento nativo em nuvem, onde o provedor da cloud será o responsável por executar os códigos com os recursos e regras de negócios da sua aplicação.
Diferentemente dos outros grandes frameworks do mercado de criação de API, o serverless é orientado a eventos, tornando-o assim compatível com diversos tipos de eventos, desde HTTP até WebSocket.
Vantagens
Utilizando clouds extremamente poderosos, como a AWS, Microsoft Azure e Google Cloud, o serverless vem conquistando cada vez mais o mercado, tendo como vantagem:
- Custo operacional reduzido: os containers só são executados quando alguma função é chamada, ficando inativo o resto do tempo;
- Simplificação da infraestrutura e possível escalonamento da aplicação: o provedor da cloud é responsável por quase toda a parte de deploy, escalonamento e gerenciamento dos containers com as funções;
- Mais segurança na infraestrutura: ao retirar o gerenciamento dos servidores de dentro da organização e repassá-lo para uma provedora como a AWS, por exemplo, é adicionada uma camada adicional de segurança. Isso porque tais provedores contam com equipes especializadas e muitos competentes quando o assunto é a segurança e a proteção a ataques.
DynamoDB e Typescript
DynamoDB é um serviço de banco de dados não-relacional (NoSQL) oferecido pela AWS, que tem como foco o fornecimento de uma performance rápida, previsível e com possibilidade de escalabilidade integrada.
Já o Typescript é um superset criado para a linguagem JavaScript pela Microsoft. Com o Typescript, podemos potencializar o Javascript, permitindo a utilização de diversos conceitos e técnicas da Orientação a Objetos, tipos, interfaces, entre outros. Além de proporcionar mais facilidade para encontrar erros de código, utilizar o Intellisense da IDE e aumentar a produtividade do dev em geral
Criação de usuário na AWS
- Pesquise por “IAM” na busca e acesse a página sugerida pela busca;
- Clique na sessão de “Users” e em “Add users”;
- Escolha um nome para o usuário e insira em “user name”;
- Na seção “Select AWS access type”, escolha a opção “Access key – Programmatic access”;
- Clique em “Next: Permissions”;
- Selecione o card de “Attach existing policies directly” e adicione a permissão de “AdministratorAccess”;
- Então é só clicar em “next” até finalizar e criar o usuário;
- Baixe as credenciais do usuário para acesso a AWS.
É importante salientar que dar essa permissão de “AdministratorAccess” só é viável em um ambiente de estudo. Isso porque, com essa permissão, o usuário passa a ter todas as permissões possíveis na AWS, fato que poderia gerar diversos problemas de segurança em um ambiente de produção.
Estrutura básica do projeto criação de API
Para iniciar a criação de API, vamos utilizar o seguinte comando no terminal:
“serverless create –template aws-nodejs-typescript –path luby-users”.
A flag “–path” indica a pasta que o projeto deve ser criado, então pode dar um nome de sua escolha. Já a flag “–template” indica o template que será usado para criar o projeto, que no nosso caso será o template que contempla as tecnologias de NodeJS e Typescript.
Após a finalização da execução do comando, abra a pasta gerada no seu editor favorito, e observe a seguinte estrutura de arquivos:
Confira uma explicação sobre a função das partes mais importantes dessa estrutura:
- Functions: onde ficará as funções criadas pelo dev. Grande parte do código criado ficará nesta pasta, assim como as configurações de endpoints para as chamadas dessas funções.
- Libs: armazena as configurações para padronização dos retornos que serão feitos pelas funções da pasta anteriormente citada. Além de configurações importantes para o deploy/parseamento das funções na AWS.
- serverless.ts: é o coração da aplicação, onde ficam as configurações mais importantes para o funcionamento de toda a aplicação. Armazena as configurações da AWS, plugins, banco de dados, funções, além de outros.
Centralização de configurações
Para esse projeto de criação de API, nós utilizaremos uma estrutura um pouco diferente, onde as configurações de endpoints e lambda ficarão todas no serverless.ts. Assim, centralizando todas as configurações para um único arquivo e deixando a pasta de functions para armazenar apenas as funções criadas neste tutorial.
Sendo assim, refatorando a estrutura de arquivos, ela seguirá desta maneira:
Com a refatoração realizada, iremos limpar as dependências que ficaram sobrando após a deleção dos arquivos que não seriam utilizados. No arquivo serverless.ts, apagaremos a linha 3, que define o import da função “hello”. E, na linha 22, na seção de functions, apagaremos a referencia para essa função, ficando assim:
Para finalizarmos essa parte inicial do projeto de criação de API, utilizaremos o seguinte comando para instalar as dependências necessárias, até o momento.
“yarn”
Ao executar tal comando, as dependências serão baixadas e armazenadas na pasta “node_modules”.
Após a execução do comando “yarn”, se a sua IDE continuar apontando falha nos imports, prossiga com os seguintes passos:
- Apague a pasta “node_modules”;
- Execute novamente o comando “yarn”;
- Reinicie a sua IDE.
Instalação dos plugins necessários
No primeiro momento, a única forma de testar as funções criadas em nosso projeto serverless seria subindo o projeto para a AWS. Entretanto, com as inevitáveis mudanças, testes e refatorações, seria extremamente não produtivo subir o projeto para a AWS a cada pequena mudança feita no código.
Sendo assim, instalaremos alguns plugins para que seja possível subir o projeto localmente, simulando um deploy na amazon. Tais plugins são:
- serverless-offline;
- serverless-dynamodb-local.
A instalação dos plugins é feita da mesma forma que a instalação de pacotes node “yarn add nome_do_pacote”. A única diferença é que vamos adicionar a flag “-D” para indicar que são plugins de desenvolvimento. Sendo assim, os comandos ficarão:
- yarn add serverless-offline -D
- yarn add serverless-dynamodb-local -D
Com os plugins devidamente instalados, vamos iniciar a criação do nosso banco de dados. Diferente de bancos como PostgreSQL e MySQL, onde geralmente são utilizadas migrations para a criação do banco de dados, aqui no serverless iremos utilizar o arquivo “serverless.ts” para definir e criar nosso banco de dados.
Configuração do banco de dados
Para isso, é só criar a sessão de resources e adicionar a definição do BD. No nosso caso, ficará assim:
Como estamos trabalhando com um banco não relacional, precisamos criar apenas o atributo que será único, como uma primary key em um banco relacional. Dessa forma, podemos identificar os usuários que serão adicionados. Já os outros campos serão criados automaticamente ao fazer a inserção no banco.
Configuração de conexão
Com o banco criado, precisamos então iniciar a configuração de conexão com o banco. Para isso, vamos criar uma pasta “utils” dentro da pasta src, e adicionar o arquivo dynamodbClient.ts. Então, dentro do arquivo criado, iremos adicionar o seguinte código para configuração da conexão:
A variável process.env.IS_OFFLINE é definida pelo próprio serverless quando iniciado. Sendo assim, não precisamos nos preocupar com sua definição. No primeiro momento, como estamos trabalhando offline, definiremos o “accessKeyId” e o “secretAccessKey” como “x”, para podermos trabalhar offline sem adicionar as verdadeiras credenciais.
Então, no arquivo “serverless.ts”, vamos adicionar o plugin do dynamo local. Assim, lembre-se de sempre deixar esse plugin antes do “serverless offline”, ficando assim:
E então, vamos adicionar a configuração de iniciar o dynamodb. Na sessão de “custom”, vamos adicionar a configuração do dynamo, ficando assim:
Dessa forma, para finalizarmos a configuração do dynamodb, vamos executar o comando de instalação do dynamo:
“serverless dynamodb install”
Com tudo instalado e devidamente configurado, vamos então testar a criação do banco de dados. Para isso, vamos utilizar o comando:
“serverless dynamodb start”
Caso tudo ocorra da forma correta, deveremos ter o seguinte resultado no terminal:
Criação do CRUD
Create User (C)
Agora que temos os plugins necessários e o database devidamente instalados e configurados, podemos então passar para o coração da aplicação: as nossas funções do CRUD de usuários.
Começaremos com a função de Create. Para isso, dentro da pasta “src/functions”, vamos criar um arquivo chamado createUser.ts e adicionar o seguinte código nele:
Alguns pontos são importantes de salientar: a função de put não retorna nenhum dado, então, precisamos adicionar o user no banco e logo em seguida fazer uma requisição ao banco para retornar esse usuário indicando seu dado que é único, no nosso caso o “id”.
Além disso, a função de buscar no dynamo sempre retorna um array. Então, precisamos especificar que ele precisa pegar o primeiro elemento do array ao retornar o dado para quem fez a requisição.
Show User (R)
Já a função de buscar, foi praticamente feita no código da função anterior. A única diferença nessa função é que nós precisamos pegar o valor de “id” dos parâmetros da rota. Sendo assim, a função ficará da seguinte maneira:
Index User
A função de index, onde mostraremos todos os usuários da aplicação, utiliza uma função diferente no dynamo. Enquanto nas outras utilizamos a função .query (pois queríamos passar parâmetros para a busca do usuário), nessa nós iremos utilizar a função .scan (que não precisa de parâmetros e traz todos os usuários cadastrados no banco). Dessa forma, a função fica assim:
Delete User (D)
Já a função de remover um usuário do banco é bastante simples, precisamos apenas passar a tabela e o dado identificador do usuário. Ficando da seguinte forma:
Update User (U)
A função de atualizar um usuário é a mais complexa entre as feitas até agora. Isso porque, como estamos lidando com um banco não relacional, temos de ter cuidado para não criar novas colunas no lugar de atualizar as colunas já existentes.
Para isso, vamos utilizar a função .update, que recebe a tabela que será pesquisado o usuário, o dado identificado e uma expressão que será utilizada para fazer a atualização. Dessa forma, a função ficará da seguinte forma:
Com todas as funções do CRUD prontas, podemos ir até o arquivo “serverless.ts” e fazer a definição das rotas que chamarão cada uma dessas funções. Para isso, nós iremos até a sessão de “functions” e iremos adicionar o seguinte código:
Testes Offline
Com todas as funções criadas e referenciadas no “serverless.ts”, podemos iniciar os testes! Para isso, vamos iniciar o nosso banco de dados em um terminal e o serverless em outro.
- Iniciar o banco de dados: “serverless dynamodb start”;
- Iniciar o serverless: “serverless offline”.
Caso tudo ocorra corretamente, devemos ter o seguinte resultado:
Com ambos os comandos em execução, podemos testar a aplicação com o insomnia, ou um API Client de sua preferência. Utilizando o insomnia, os resultados das requisições serão:
Deploy na AWS
Para o deploy na AWS, nós vamos precisar das credenciais que criamos logo no início desse tutorial.
O primeiro passo é passar as credenciais para o serverless, com o seguinte comando:
“serverless config credentials –provider aws –key={sua chave} –secret={sua secret} -o”
O segundo passo é configurar o acesso do nosso usuário da AWS para o Dynamodb. Para isso, vamos adicionar as seguintes linhas de código na sessão de “provider” no arquivo “serverless.ts”, deixando o arquivo assim:
Agora com tudo pronto, podemos finalmente fazer o deploy da aplicação utilizando o comando:
“serverless deploy”
Conclusão
Dessa forma, após a criação de API, sua aplicação serverless estará online e pronta para receber requisições!
● Link da aplicação no github: https://github.com/silvavinicyus/luby-users
● Github: https://github.com/silvavinicyus/
Autor: Vinícyus Silva Soares
[adrotate banner=”5″]
Veja também:
Como criar uma API com Express & Prisma