Dada uma palavra contínua, e um conjunto de regras, Joaquim precisa verificar se a senha é válida baseada nas regras pedidas
- minSize: tem pelo menos x caracteres.
- minUppercase: tem pelo menos x caracteres maiúsculos
- minLowercase: tem pelo menos x caracteres minúsculos
- minDigit: tem pelo menos x dígitos (0-9)
- minSpecialChars: tem pelo menos x caracteres especiais
- Os caracteres especiais são os caracteres da seguinte string: "!@#$%^&*()-+/{}[]"
- noRepeted: (esta regra pode ser ignorada)
query {
verify(password: "TesteSenhaForte!1223&", rules: [
{rule: "minSize",value: 8},
{rule: "minSpecialChars",value: 2},
{rule: "noRepeted",value: 0},
{rule: "minDigit",value: 4}
]){ noMatch, verify }
}
├── go.mod
├── go.sum
├── gqlgen.yml - Configuração gqlgen, com as instruções e definições de diretórios
├── graph
│ ├── generated - Pacotes que são gerados em tempo de execução pela lib
│ │ └── generated.go
│ ├── model - Models da nossa API, sendo eles gerados automaticamente pelo gqlgen ou manualmente inseridos
│ │ └── models_gen.go
│ ├── resolver.go - Resolver principal responsável pela injeção de dependência gerais da aplicação
│ ├── schema.graphqls - Definição do schema, podendo ser dividido para facilitar a estruturação da API em projetos maiores
│ └── schema.resolvers.go - O resolver para o schema definido acima com as funções necessárias para sua validação e manipulação
└── server.go - Definição do servidor, endpoints, rota e portas
Para rodar o projeto é necessário que tenha o Docker instalado, você pode acessar o link Get Docker para realizar o download.
Se preferir você poderá rodar utilizando Go
em sua máquina local, cheque as instruções abaixo.
O projeto funciona de maneira bem simples, ao iniciá-lo você terá acesso tanto ao servidor GraphQL quanto ao cliente através da interface do GraphiQL onde você poderá visualizar e ralizar os testes da API.
Para realizar apenas a consulta você pode utilizar um cliente como Postman
A api recebe uma consulta verify
que aceita os parâmetros password
uma string com a senha à ser validade e um array rules
que deve ser preenchido com os objetos
de regras, contendo uma rule
que é o nome da regra e um value
que é o valor da regra à ser validada. Você pode seguir a consulta de exemplo para montar a sua consulta.
Você pode buildar a imagem com docker build
, ou apenas executar o container com docker run
É possível realizar o tudo em um único comando, buildar e executar o contâiner, para isto utilize os comandos abaixo substituindo os valores
Para facilitar realize os comandos de build na pasta do projeto onde se encontra o
Dockerfile
- <nome_imagem> nome que deseja registrar para sua imagem
- <nome_container> nome que deseja registrar para seu container
- porta:8080 você deve mapear a porta do host onde o container irá se conectar, como padrão pode utilizar
8080:8080
docker build -t <nome_imagem> . && docker run --name <nome_container> -p <porta:8080> <nome_imagem>
Você poderá apenas executar a imagem, isto fará com que o Docker realize o download da versão disponível no DockerHub, inicie a aplicação e remova o container quando o serviço for finalizado.
docker run -p <porta:8080> --rm -d sglauber/go-graphql
Após executar o comando acima acesse a rota localhost:<porta>/
para visualizar o GraphiQL.
Obs.: Por padrão o servidor será iniciado na porta: 8080
- Execute
go mod tidy
para adicionar automaticamente as dependências - Com
go run server.go
você irá iniciar o servidor - Então acesse a rota
localhost:8080/
para visualizar o GraphiQL - Realize consultas na rota
localhost:8080/graphql
Este foi meu primeiro contato com a linguagem Go
, assim como APIs em graphql, foi prazeroso poder realizar este projeto e entender um pouco como funcionam estas tecnologias.
Decidi escolher Go
para linguagem de implementação exatamente pelo desafio, acredito que o framework ou linguagem são ferramentas que se utilizadas corretamente nos auxiliam a chegar no objetivo de forma satisfatória e sou grato por poder tê-lo completado e feliz com o resultado, foi uma ótima oportunidades de aprendizado.
A escolha da biblioteca gqlen
se dá pelas funcionalidades de abstração, documentação e quantidade de exemplos que ela oferece se comparada à outras bibliotecas como graphql-go
e gophers
. Como podemos definir o schema-first ao invés de implementar interfaces e tipos diretamente no código ela facilitou o processo de aprendizagem e elimina boa parte dos problemas com relação à tipagem, porém, é um pouco chato de lidar quando se é necessário realizar o regenerate para mapear os models, já que ela irá também reescrever os resolvers.
Começo recuperando as regras que foram passadas, percorrendo a lista das regras informadas através da api e comparando-as com as possíveis regras (veja regras do projeto). Se uma destas regras for encontrada na lista então iremos checar se a senha informada através da API se encontra dentro dos padrões.
Para estas verificações criei funções com responsabilidade única, uma função para cada uma das regras, que verifica a existência dos caracteres especiais, existencia de números (dígitos), letras maiúsculas, letras minúsculas e se a quantidade destes caracteres é maior ou igual ao valor informado através da API, se o caractere é encontrado, então acumulamos este valor e após percorrermos toda a string (password), passamos esta informação para a função isEqualOrGreaterThan
, que retorna um boolean (true, false)
caso o valor de caracteres encontrados no password
for maior ou igual ao exigido pela regra. Se o retorno desta função for false
adiciono-a à lista failedRules
que será retornada em nossa API GraphQL.
A excessão à esta regra é a função arrayContains
que recebe a nossa lista de failedRules e verifica se a regra já existe nesta lista, assumi que regras repetidas ainda possam contar como entradas válidas mas não seria correto retornar a mesma regra mais de uma vez.