Criando um Serverless .NET Core Web API com AWS Lambda
Para muitos que como eu estão se aventurando na AWS e estudando em como utilizar e implementar os serviços disponíveis na Amazon (que não sou poucos), resolvi compartilhar um pouco do meu aprendizado e mostrar o pouco que aprendi até agora.
Resolvi começar mostrando como criar uma pequena API em .Net Core com AWS Lambda. Para isso, precisaremos de:
- Visual Studio 2019
- AWS Toolkit para o Visual Studio (mostrarei como instalar)
- Ter uma conta na AWS
- Postman
Então vamos lá. Primeiramente vamos instalar o AWS Toolkit for Visual Studio.
Após efetuar o download, clique no instalador e a seguinte tela aparecerá:

Como possuo a versão 2017 e 2019 do Visual Studio, o instalador me dá a opção de instalação nos dois produtos. Apenas clique em Install e espere a instalação ser concluída.


Após a instalação, abra o Visual Studio e veja que novas opções de projetos estarão disponíveis. Clique em Create a New Project e escolha o template AWS Servless Application (.NET Core – C#) e clique em Next:


O nome do nosso projeto será AWSProductListWebAPI e o objetivo dele será inserir e excluir dados de uma lista de produtos que ficará em memória.
Clique em Create.

Escolha a opção AP.NET Core Web API e clique em Next.

Clique em Create e o seu projeto será criado.

Vamos apagar os dois Controllers criados no projeto, pois escreveremos o nosso próprio.
A API que criaremos fará a inclusão de produtos e suas respectivas quantidades em uma lista em memória. Algo bem simples.
Antes de continuarmos, entenda que não é objetivo desse artigo ensinar C#, portanto, descreverei a estrutura e disponibilizarei os fontes a seguir.
Estrutura de nossa API:
- Controllers
- Models
- Services
Controllers
using System.Linq; using System.Threading.Tasks; using AWSProductListWebAPI.Models; using AWSProductListWebAPI.Services; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace AWSProductListWebAPI.Controllers { [Route("v1/productList")] public class ProductListController : ControllerBase { private readonly IProductListService _productListService; public ProductListController(IProductListService productListService) { _productListService = productListService; } [HttpGet] public IActionResult GetProductList() { var result = _productListService.GetItemsFromProductList(); return Ok(result); } [HttpPost] public IActionResult AddItemToProductList([FromBody] ProductListModel productList) { _productListService.AddItemToProductList(productList); return Ok(); } [HttpDelete] public IActionResult DeleteItemsFromProductList([FromBody] ProductListModel productList) { _productListService.RemoveItem(productList.Name); return Ok(); } } }
Aqui definimos a rota de chamada de nossa API (v1/productList) e os métodos HTTP get, delete e post.
Models
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace AWSProductListWebAPI.Models { public class ProductListModel { public string Name { get; set; } public int Quantity { get; set; } } }
Aqui o modelo de nossa lista de produtos
Services
Primeiro a interface de nosso Serviço:
using System.Collections.Generic; using AWSProductListWebAPI.Models; namespace AWSProductListWebAPI.Services { public interface IProductListService { Dictionary GetItemsFromProductList(); void AddItemToProductList(ProductListModel productList); void RemoveItem(string name); } }
E sua implementação:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace AWSProductListWebAPI.Services { public class ProductListService : IProductListService { private readonly Dictionary _productListStorage = new Dictionary(); public Dictionary GetItemsFromProductList() { return _productListStorage; } public void AddItemToProductList(Models.ProductListModel productList) { _productListStorage.Add(productList.Name, productList.Quantity); } public void RemoveItem(string productListName) { _productListStorage.Remove(productListName); } } }
A estrutura ficará assim no Visual Studio:

Compile tudo (CTRL+SHIFT+B), e se nenhum erro se apresentar, o seu projeto está íntegro ! 🙂
Vamos fazer um teste. Clique em F5 para executar o projeto e levantar o IIS ( Internet Information Services). Vamos agora testar o nosso serviço utilizando o Postman. Se você não o tem instalado e nem sabe como utilizá-lo, veja o artigo abaixo:
Quando o IIS levantar, o navegador abrirá e mostrará o endereço localhost com a respectiva porta. Copie esse link para utilizarmos na chamada de nossa API.

Vamos fazer a nossa primeira chamada com GET:

Observe que o JSON retornou vazio, pois não inserimos nada em nossa lista de produtos.
Vamos fazer uma chamada com POST incluindo um produto e sua quantidade:
{ "Name": "mouse", "Quantity": 1 }

Incluiremos outro produto agora:
{ "Name": "keyboard", "Quantity": 1 }
Agora faremos uma nova chamada GET.

Veja que o retorno foi os dois produtos que enviamos para a lista. Mouse e teclado.
Vamos fazer uma chamada DELETE apagando um produto de nossa lista. Vamos retirar o keyboard de nossa lista.
{ "Name": "keyboard" }

E um novo GET agora.

Observe que apenas o mouse permanece na lista. Isso mostra que a nossa API está 100% funcional ! 🙂
Agora vem o mais interessante. Vamos publicá-la na AWS ! Para isso, clique com o botão direito no nome da nossa API e escolha a opção Publish to AWS Lambda.

A seguinte tela se apresentará. Clique no botão para incluir o Account profile to use para preencher todos os dados da credencial.

Os principais campos a serem preenchidos são:
- Access Key Id – Chave de acesso do usuário AWS que deverá possuir permissões para fazer a criação do Bucket S3, do Lambda Function e API Gateway
- Secret Access Key – Chave de acesso secreta do usuário
- Account Number – Account Number de sua conta AWS
Criando um usuário na AWS
O usuário que utilizaremos não é o root (master) que acessa todos os serviços da AWS, e sim um que contenha apenas as roles necessárias para a publicação de nossa API.

Clique em Serviços > Identity and Access Managemente (IAM) e depois Adicionar usuario.

Criemos o usuário tester. No Tipo de acesso, habilite o Acesso programático para que tenhamos as chaves de acesso necessárias para publicarmos nossa API. Após isso clique no botão Próximo: Permissões.

Escolha a opção Anexar políticas existentes de forma direta e escolha as permissões abaixo:


Em uma implementação de produção real, nunca daríamos acesso full aos serviço, mas como o objetivo desse artigo não é o aprofundamento na criação de usuário na AWS, vamos prosseguir do jeito mais fácil.
Clique em Criar usuário.

Voltemos ao IAM. Clique no usuário tester que criamos e acesse a aba Credenciais de Segurança. Lá clique em Criar chave de acesso para obtermos o Access Key ID e o Secret Access Key.

Voltemos ao Visual Studio para preenchermos os dados faltantes e clicar em OK. A seguinte tela se apresentará:

Preencha os seguintes campos:
- Region: Região do datacenter onde você publicaremos a nossa API
- Configuration: Release
- Framework: netcoreapp2.1
- Stack Name: ProductListLambdaWebAPI
- S3 Bucket: Se não possuir um criado, clique em New e crie o seu bucket
Clique em Publish.


Se qualquer problema ocorrer, ele efetuará o ROLLBACK do deploy e apresentará a tela acima. Caso tudo funcione como esperamos, a tela abaixo aparecerá:

Onde está em vermelho, aparecerá o link para executarmos a nossa API. No Postman, substitua o localhost por esse link e faça os mesmos testes que efetuamos anteriormente. Se tudo funcionar, meus parabéns ! Você acabou de publicar sua primeira API na AWS !!
Dica: Após o término de seus testes, sugiro que bloqueie o seu bucket S3 para acesso público, pois ele estará exposto a ser chamado por qualquer um. Para isso, acesse sua conta na AWS, clique em Serviços e busque por Amazon S3. Clique na aba Permissões e depois em Editar.
Agora clique em Bloquear todo Acesso Público e depois em Salvar.


Digite confirmar e clique no botão Confirmar.
Pronto ! Seu bucket S3 não estará mais exposto a acesso público !
Assim chegamos ao fim de nosso artigo. Espero que ele seja útil e ajude um pouco a entender e a implementar APIs na AWS.
Fontes

Formado em Gestão em Tecnologia da Informação, com sólidos conhecimentos em SQL, PL/SQL, Oracle Forms, Reports e E-Business Suite (AP,AR e GL).
Foi durante 3 anos gerente de tecnologia de grande empresa do setor de saúde, e atualmente atua como Analista de Sistema Sênior na Scania Latin America e também como Diretor-fundador do GPO (Grupo de Profissionais Oracle).