O servico tem como objetivo controlar o ciclo de vida de abertura de vagas de oportunidades de trabalho e banco de talentos.
Organizo a base de código usando um esquema de monorepo me aproveitando bem da arquitetura hexagonal:
.
+-- ports/aws-lambda
| +-- talents.handler.js
| +-- talents-worker.handler.js
| +-- openings.handler.js
| +-- openings-worker.handler.js
Por se tratar de microservicos que em conjunto resolve um problema em específico e estão interligados em termos de negócio, ficou coerente unificar todos eles em uma mesma base de código.
Utilizei o template de hexagonal disponível nesse repositório como base de desenvolvimento.
-
talents.handler: responsável pelo controle de ciclo de vida dos dados de talentos, ele deve controlar todo o ciclo de vida, mas não terá nenhuma capacidade de escrita no repositório de dados, pois essa responsabilidade será feita pelo worker, toda operacao de escrita é assincrona.
-
talents-worker.handler: responsável pelas operacoes de escrita (CREATE/UPDATE/DELETE) e também responsável por buscar matching de talentos quando informado no payload os dados da vaga.
-
openings.handler: responsável pelo controle de ciclo de vida dos dados de oportunidades, ele deve controlar todo o ciclo de vida, mas não terá nenhuma capacidade de escrita no repositório de dados, pois essa responsabilidade será feita pelo worker, toda operacao de escrita é assincrona.
-
openings-worker.handler: responsável pelas operacoes de escrita (CREATE/UPDATE/DELETE) e também responsável por buscar matching de vagas quando informado no payload os dados do talento.
Podemos perceber um comportamento nos workers que operam em duas vias:
-
Se uma oportunidade é criada/alterada, o talents worker tenta fazer match com os talentos existentes
-
Se um talento é criado/alterado, o openings worker tenta fazer match com as vagas existentes
Utilizamos SQS para realizar os trabalhos assíncronos de cada worker, DynamoDB para manter os dados de cada repositório, e um tópico de SNS para emitir sempre que ocorrer um match, do SNS pra frente, seu 💗 que vai decidir o que fazer daí pra frente.
No diagrama não está diagramado o comportamento de DeadLetter, mas ela será implementada nas filas de SQS para lidar com mensagens que não processar e por sua vez, devem ser monitoradas usando CloudWatch.
-
- cobertura de código a prova de mutacões, ou seja, os testes falham quando altera o código. leia esse artigo para entender mais.
-
- usamos standardjs como padrão de formatacao e protegido por linters.
-
- todos os nossos commits são cobertos pelo padrão do conventional-changelogs, nesse artigo explico a respeito dele.
-
- usamos padrão standard de release, embora ainda não tenha nenhum release feito. Standard release consegue criar um texto em cima dos commits do conventional changelogs, mostrando a sugestão da nova versão baseado no Semver, e os textos agrupados em
features
efixes
.
O diagrama representa sua configuracão mais simples onde a escrita feita pelos servicos que respondem ao api-gateway, escrevem direto na lambda, para mudar isso, basta alterar a variável WRITE_OPERATION_LEVEL=ONLY_VALIDATE
que o processo de escrita no dynamo será assíncrono e de responsabilidade dos workers.
Para saber mais como funciona em termos de business a solucao entre na documentacão de business layer.
O projeto possui no circleCI todo processo de integracao contínua que:
- impede deploy se tiver quebra na build
- faz teste de mutacao sempre que uma feature é entregue (pr fechada com a main).
- deploy contínuo usando um usuário limitado a operacoes de deploy na aws.
- deploy é feito com base no padrão de tags.
É bem simples de já começar rodando
- Configure o
.env
baseado no.env.example
; - Instale as dependências com
yarn install
- ligue o localstack com
docker-compose --env-file=.env.localstack up -d
; - Se estiver usando OSX, recomendado usar o arquivo
docker-compose-osx.yaml
, pois ele já está configurado para tal. - levante o ambiente demo usando terraform com os comandos:
$terraform init
$terraform plan (avalia se é isso mesmo que quer criar)
$terraform apply
Iremos ter endpoints funcionando tanto na arquitetura da AWS simulada com localstack, quanto em endpoints no port de http
para facilitar desenvolvimento e debug.
Agora vamos para segunda parte...
- Observe no output do terraform a variável
services_api_id = <id-da-api>
- Utilize de um console terminal para executar a leitura dos logs com o comando
docker logs -f localstack_talent-retainer-service
e observe durante a validacao. - Execute as chamadas de api a partir do endpoints
localhost:4566/restapis/<id-da-api>/dev/_user_request_/v1/openings
elocalhost:4566/restapis/<id-da-api>/dev/_user_request_/v1/talents
Para fazer as validacoes detalhadas, siga esse roteiro.
Na pasta iaac/aws
foi criado a infrasestrutura completa do caso de uso, onde teremos um api-gateway respondendo pelas entradas e terá autenticacao por api key. no roteiro de validacão iremos abordar como validar na AWS.
Para implantar na AWS:
- tenha terraform 0.11.14 instalado.
- tenha AWS cli v2 instalado e configurado com uma conta de sua preferencia em um profile definido.
- tenha nível de acesso para realizar as operacoes, utilize perfil administrativo de uma conta de
brinquedo
para validar. - entre na pasta
iaac/aws
e exporte a variável de ambiente do seu profileexport AWS_PROFILE=<meu profile>
- realize o comando
terraform init
e depoisterraform apply -target=module.s3
- guarde o resultado do output para usarmos no roteiro de validacao.
- no bucket que foi criado rode o comando
yarn build-lambda
para que os códigos da lambdas sejam criados em.serverless
, em seguida mova eles para a pasta/latest
dentro do bucket criado pelo terraform no passo 5) - volte na pasta
iaac/aws
e termine de deployar a infraestrutura comterraform apply
. - Entre na conta da aws e obtenha o endopoint da api, assim como a chave de api
developer
no painel do apigateway. - Agora é seguir o roteiro.
- CUIDADO, não estamos usando backend para persistir estado, não apague os arquivos
terraform.tfstate
eterraform.tfstate.backup
, se perder eles, terá que remover manualmente os recursos criados. - Ao final do processo, só dar
terraform destroy
e ser feliz.
Mapeei as melhorias a serem feitas aqui.