Esse projeto contém uma série de informações sobre o que eu aprendi aqui na Trybe ao longo do curso de desenvolvimento web da Trybe.
Esse projeto foi proposto pelo curso de desenvolvimento web da Trybe.
Esse projeto foi desenvolvido no bloco de back-end, desenvolvi uma aplicação Node.js usando sequelize para fazer um CRUD de posts. Desenvolver endpoints que foram conectados ao seu banco de dados seguindo os princípios do REST. Para fazer um post, precisei criar um usuário e login. Fiz a autenticação do login usando o token JWT. Criei uma função para verificar o token criado e o secret.
Os commits foram feitos de acordo com os requisitos finalizados.
Todo o projeto foi feita na branch 'juliana-oliveira-project-blogs-api', isso por conta da exigência do curso.
Antes de realizar o projeto, precisei instalar as dependências usando npm install.
Os testes usando foram feitos através do comando npm test.
Esse foi um projeto individual,que desenvolvido somente por Juliana Oliveira.
Foi usado Visual Studio Code, além do Trello que auxiliou na organização das tarefas.
Nenhum.
Antes de começar, seu docker-compose precisa estar na versão 1.29 ou superior.
No trabalho do desenvolvimento de software a gente sempre tem prazos, muitas vezes os prazos são apertados.
Por outro lado, eu não quero criar algo que não entendo perfeitamente, como também fazer códigos rápidos pode levar a erros que podem demorar muito pra corrigir.
Por isso, usei e sempre uso o método Baby Steps, que é uma estratégia de abordar o desafio passo à passo, defensivamente.
Baby steps é um termo em inglês que quer dizer passos de bebê. Refere-se a fazer as coisas, quaisquer que sejam, devagar, com calma, passo a passo.
- Esse teste fará uma conexão no banco utilizando a configuração de teste do arquivo
src/database/config/config.js
; - Suas
migrations
devem estar no diretório correto e respeitar a nomenclatura pedida no requisito; - Suas
migrations
devem respeitar o diagrama de Entidade-Relacionamento e o formato das entidades, como descrito na seção de Diagrama ER e Entidades. - Exclua na pasta
./src/database/migrations/
, o arquivoremove-me.js
.
Os seguintes pontos serão avaliados:
-
[Será validado que é possível fazer um INSERT e um SELECT na tabela Users]
- O avaliador irá inserir um dado de exemplo na tabela
Users
; - O avaliador irá fazer um select, desse mesmo dado, na tabela
Users
.
- O avaliador irá inserir um dado de exemplo na tabela
-
[Será validado que é possível fazer um INSERT e um SELECT na tabela Categories]
- O avaliador irá inserir um dado de exemplo na tabela
Categories
; - O avaliador irá fazer um select, desse mesmo dado, na tabela
Categories
.
- O avaliador irá inserir um dado de exemplo na tabela
-
[Será validado que, a partir de um INSERT em User, é possível fazer um INSERT e um SELECT na tabela BlogPosts]
- Dado que
BlogPosts
possui uma chave estrangeirauserId
:- O avaliador irá inserir um dado de exemplo na tabela
Users
;
- O avaliador irá inserir um dado de exemplo na tabela
- Desse modo:
- O avaliador irá inserir um dado de exemplo na tabela
BlogPosts
; - O avaliador irá fazer um select, desse mesmo dado, na tabela
BlogPosts
.
- O avaliador irá inserir um dado de exemplo na tabela
- Dado que
-
[Será validado que, a partir de INSERTs em User, Categories e BlogPosts, é possível fazer um INSERT e um SELECT na tabela PostCategories]
- Dado que
PostCategories
possui uma chave primária composta de duas chaves estrangeiras, respectivamente,postId
,categoryId
:- O avaliador irá inserir um dado de exemplo na tabela
Users
; - O avaliador irá inserir um dado de exemplo na tabela
Categories
; - O avaliador irá inserir um dado de exemplo na tabela
BlogPosts
;
- O avaliador irá inserir um dado de exemplo na tabela
- Desse modo:
- O avaliador irá inserir um dado de exemplo na tabela
PostCategories
; - O avaliador irá fazer um select, desse mesmo dado, na tabela
PostCategories
.
- O avaliador irá inserir um dado de exemplo na tabela
- Dado que
- Sua
model
deve estar no diretório correto e respeitar a nomenclatura pedida no requisito; - Sua
model
deve respeitar o diagrama de Entidade-Relacionamento e o formato das entidades, como descrito na seção de Diagrama ER e Entidades.
Os seguintes pontos serão avaliados:
-
[Será validado que existe o arquivo 'user.js']
-
[Será validado que o modelo possui o nome 'User']
-
[Será validado que o modelo possui a propriedade 'id']
-
[Será validado que o modelo possui a propriedade 'displayName']
-
[Será validado que o modelo possui a propriedade 'email']
-
[Será validado que o modelo possui a propriedade 'password']
-
[Será validado que o modelo possui a propriedade 'image']
- O endpoint deve ser acessível através do URL
/login
; - O corpo da requisição deverá seguir o formato abaixo:
{ "email": "[email protected]", "password": "123456" }
Os seguintes pontos serão avaliados:
-
[Será validado que não é possível fazer login sem todos os campos preenchidos]
- Se a requisição não tiver todos os campos devidamente preenchidos(não pode haver campos em branco), o resultado retornado deverá ser conforme exibido abaixo, com um status http
400
:
{ "message": "Some required fields are missing" }
- Se a requisição não tiver todos os campos devidamente preenchidos(não pode haver campos em branco), o resultado retornado deverá ser conforme exibido abaixo, com um status http
-
[Será validado que não é possível fazer login com um usuário que não existe]
- Se a requisição receber um par de
email
epassword
errados/inexistentes, o resultado retornado deverá ser conforme exibido abaixo, com um status http400
:
{ "message": "Invalid fields" }
- Se a requisição receber um par de
-
[Será validado que é possível fazer login com sucesso]
- Se o login foi feito com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
200
:
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjp7ImlkIjo1LCJkaXNwbGF5TmFtZSI6InVzdWFyaW8gZGUgdGVzdGUiLCJlbWFpbCI6InRlc3RlQGVtYWlsLmNvbSIsImltYWdlIjoibnVsbCJ9LCJpYXQiOjE2MjAyNDQxODcsImV4cCI6MTYyMDY3NjE4N30.Roc4byj6mYakYqd9LTCozU1hd9k_Vw5IWKGL4hcCVG8" }
⚠️ O token anterior é fictício, seu token deve ser gerado a partir da variável de ambienteJWT_SECRET
, dopayload
da requisição e não deve conter o atributopassword
em sua construção. - Se o login foi feito com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
- O endpoint deve ser acessível através do URL
/user
; - O endpoint deve ser capaz de adicionar um novo
user
a sua tabela no banco de dados; - O corpo da requisição deverá seguir o formato abaixo:
{ "displayName": "Brett Wiltshire", "email": "[email protected]", "password": "123456", "image": "http://4.bp.blogspot.com/_YA50adQ-7vQ/S1gfR_6ufpI/AAAAAAAAAAk/1ErJGgRWZDg/S45/brett.png" }
Os seguintes pontos serão avaliados
-
[Será validado que não é possível cadastrar com o campo
displayName
menor que 8 caracteres]- Se a requisição não tiver o campo
displayName
devidamente preenchido com 8 caracteres ou mais, o resultado retornado deverá ser conforme exibido abaixo, com um status http400
:
{ "message": "\"displayName\" length must be at least 8 characters long" }
- Se a requisição não tiver o campo
-
[Será validado que não é possível cadastrar com o campo
email
com formato inválido]- Se a requisição não tiver o campo
email
devidamente preenchido com o formato<prefixo@dominio>
, o resultado retornado deverá ser conforme exibido abaixo, com um status http400
:
{ "message": "\"email\" must be a valid email" }
- Se a requisição não tiver o campo
-
[Será validado que não é possível cadastrar com o campo
password
menor que 6 caracteres]- Se a requisição não tiver o campo
password
devidamente preenchido com 6 caracteres ou mais, o resultado retornado deverá ser conforme exibido abaixo, com um status http400
:
{ "message": "\"password\" length must be at least 6 characters long" }
- Se a requisição não tiver o campo
-
[Será validado que não é possível cadastrar com um email já existente]
- Se a requisição enviar o campo
email
com um email que já existe, o resultado retornado deverá ser conforme exibido abaixo, com um status http409
:
{ "message": "User already registered" }
- Se a requisição enviar o campo
-
[Será validado que é possível cadastrar um pessoa usuária com sucesso]
- Se o user for criado com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
201
:
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjp7ImlkIjo1LCJkaXNwbGF5TmFtZSI6InVzdWFyaW8gZGUgdGVzdGUiLCJlbWFpbCI6InRlc3RlQGVtYWlsLmNvbSIsImltYWdlIjoibnVsbCJ9LCJpYXQiOjE2MjAyNDQxODcsImV4cCI6MTYyMDY3NjE4N30.Roc4byj6mYakYqd9LTCozU1hd9k_Vw5IWKGL4hcCVG8" }
⚠️ O token anterior é fictício, seu token deve ser gerado a partir da variável de ambienteJWT_SECRET
, dopayload
da requisição e não deve conter o atributopassword
em sua construção. - Se o user for criado com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
- Após termos feito o requisito de criação de
users
e o requisito delogin
, alguns requisitos abaixo vão precisar desta autenticação prévia, para que seja possível consumir o endpoint; - Todo requisito que precisar validar o
token
terá o símbolo ☝; - ✨ Dica: Se é algo que vamos utilizar em mais de uma rota, será que podemos separa-lo em algum lugar que comece com
M
demiddleware
? 😜
Os seguintes pontos serão avaliados
-
[Será validado que não é possível fazer uma operação sem o token na requisição]
- Se o token for inexistente o resultado retornado deverá ser conforme exibido abaixo, com um status http
401
:
{ "message": "Token not found" }
- Se o token for inexistente o resultado retornado deverá ser conforme exibido abaixo, com um status http
-
[Será validado que não é possível fazer uma operação com o token inválido]
- Se o token for inválido o resultado retornado deverá ser conforme exibido abaixo, com um status http
401
:
{ "message": "Expired or invalid token" }
- Se o token for inválido o resultado retornado deverá ser conforme exibido abaixo, com um status http
- ☝ Não esqueça de validar o
token
neste requisito, como descrito na seção de Validando token nas requisições; - O endpoint deve ser acessível através do URL
/user
; - O endpoint deve ser capaz de trazer todos
users
do banco de dados;
Os seguintes pontos serão avaliados
-
☝ [Será validado o token, como descrito na seção de Validando token nas requisições]
-
[Será validado que é possível listar todos os usuários]
- Ao listar usuários com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
200
:
[ { "id": 1, "displayName": "Lewis Hamilton", "email": "[email protected]", "image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg" }, /* ... */ ]
- Ao listar usuários com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
- ☝ Não esqueça de validar o
token
neste requisito, como descrito na seção de Validando token nas requisições; - O endpoint deve ser acessível através do URL
/user/:id
; - O endpoint deve ser capaz de trazer o
user
baseado noid
do banco de dados se ele existir;
Os seguintes pontos serão avaliados
-
☝ [Será validado o token, como descrito na seção de Validando token nas requisições]
-
[Será validado que é possível listar um usuário específico com sucesso]
- Ao listar um usuário com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
200
:
{ "id": 1, "displayName": "Lewis Hamilton", "email": "[email protected]", "image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg" }
- Ao listar um usuário com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
-
[Será validado que não é possível listar um usuário inexistente]
- Se o usuário for inexistente o resultado retornado deverá ser conforme exibido abaixo, com um status http
404
:
{ "message": "User does not exist" }
- Se o usuário for inexistente o resultado retornado deverá ser conforme exibido abaixo, com um status http
👣Requisito 7 - Crie o modelo 'Category' em 'src/database/models/category.js' com as propriedades corretas
- Sua
model
deve estar no diretório correto e respeitar a nomenclatura pedida no requisito; - Sua
model
deve respeitar o diagrama de Entidade-Relacionamento e o formato das entidades, como descrito na seção de Diagrama ER e Entidades.
Os seguintes pontos serão avaliados
-
[Será validado que existe o arquivo 'category.js']
-
[Será validado que o modelo possui o nome 'Category']
-
[Será validado que o modelo possui a propriedade 'id']
-
[Será validado que o modelo possui a propriedade 'name']
- ☝ Não esqueça de validar o
token
neste requisito, como descrito na seção de Validando token nas requisições; - O endpoint deve ser acessível através do URL
/categories
; - O endpoint deve ser capaz de adicionar uma nova categoria a sua tabela no banco de dados;
- O corpo da requisição deverá seguir o formato abaixo:
{ "name": "Typescript" }
Os seguintes pontos serão avaliados
-
☝ [Será validado o token, como descrito na seção de Validando token nas requisições]
-
[Será validado que não é possível cadastrar uma categoria sem o campo
name
]- Se a requisição não tiver o campo
name
devidamente preenchidos(não pode haver campo em branco), o resultado retornado deverá ser conforme exibido abaixo, com um status http400
:
{ "message": "\"name\" is required" }
- Se a requisição não tiver o campo
-
[Será validado que é possível cadastrar uma categoria com sucesso]
- Se a categoria for criada com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
201
:
{ "id": 3, "name": "Typescript" }
- Se a categoria for criada com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
- ☝ Não esqueça de validar o
token
neste requisito, como descrito na seção de Validando token nas requisições; - O endpoint deve ser acessível através do URL
/categories
; - O endpoint deve ser capaz de trazer todas categorias do banco de dados;
Os seguintes pontos serão avaliados
-
☝ [Será validado o token, como descrito na seção de Validando token nas requisições]
-
[Será validado que é possível listar todas as categoria com sucesso]
- Ao listar categorias com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
200
:
[ { "id": 1, "name": "Inovação" }, { "id": 2, "name": "Escola" }, /* ... */ ]
- Ao listar categorias com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
👣Requisito 10 - Crie o modelo 'BlogPost' em 'src/database/models/blogPost.js' com as propriedades e associações corretas
-
Sua
model
deve estar no diretório correto e respeitar a nomenclatura pedida no requisito; -
Sua
model
deve respeitar o diagrama de Entidade-Relacionamento e o formato das entidades, como descrito na seção de Diagrama ER e Entidades; -
Sua
model
deve respeitar a associação correta (N:1) com o modeloUser
; -
✨ Dica:
- Explore como renomear campos no Sequelize;
Os seguintes pontos serão avaliados
-
[Será validado que existe o arquivo 'blogPost.js']
-
[Será validado que o modelo possui o nome 'BlogPost']
-
[Será validado que o modelo possui a propriedade 'id']
-
[Será validado que o modelo possui a propriedade 'title']
-
[Será validado que o modelo possui a propriedade 'content']
-
[Será validado que o modelo possui a propriedade 'userId']
-
[Será validado que o modelo possui a propriedade 'published']
-
[Será validado que o modelo possui a propriedade 'updated']
-
[Será validado que o modelo em 'blogPost.js', define a associação 'belongsTo', com a entidade de nome 'User']
-
[Será validado que o modelo em 'user.js', define a associação 'hasMany', com a entidade de nome 'BlogPost']
👣Requisito 11 - Crie o modelo 'PostCategory' em 'src/database/models/postCategory.js' com as propriedades e associações corretas
- Sua
model
deve estar no diretório correto e respeitar a nomenclatura pedida no requisito; - Sua
model
deve respeitar o diagrama de Entidade-Relacionamento e o formato das entidades, como descrito na seção de Diagrama ER e Entidades; - Sua
model
deve respeitar a associação correta (N:N) entre o modeloBlogPost
e o modeloCategory
;
Os seguintes pontos serão avaliados
-
[Será validado que existe o arquivo 'postCategory.js']
-
[Será validado que o modelo possui o nome 'PostCategory']
-
[Será validado que o modelo possui a propriedade 'postId']
-
[Será validado que o modelo possui a propriedade 'categoryId']
-
[Será validado que o modelo em 'postCategory.js', através do(s) modelos(s) de nome(s) 'Category; BlogPost', define a associação 'belongsToMany' respectivamente, com o(s) modelo(s) de nome(s) 'BlogPost, Category']
- ☝ Não esqueça de validar o
token
neste requisito, como descrito na seção de Validando token nas requisições; - O endpoint deve ser acessível através do URL
/post
; - O endpoint deve ser capaz de trazer todos os bogs post, user dono dele e as categorias do banco de dados;
Os seguintes pontos serão avaliados
-
☝ [Será validado o token, como descrito na seção de Validando token nas requisições]
-
[Será validado que é possível listar blogpost com sucesso]
- Ao listar posts com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
200
:
[ { "id": 1, "title": "Post do Ano", "content": "Melhor post do ano", "userId": 1, "published": "2011-08-01T19:58:00.000Z", "updated": "2011-08-01T19:58:51.000Z", "user": { "id": 1, "displayName": "Lewis Hamilton", "email": "[email protected]", "image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg" }, "categories": [ { "id": 1, "name": "Inovação" } ] }, /* ... */ ]
- Ao listar posts com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
- ☝ Não esqueça de validar o
token
neste requisito, como descrito na seção de Validando token nas requisições; - O endpoint deve ser acessível através do URL
/post/:id
; - O endpoint deve ser capaz de trazer o blog post baseado no
id
do banco de dados se ele existir;
Os seguintes pontos serão avaliados
-
☝ [Será validado o token, como descrito na seção de Validando token nas requisições]
-
[Será validado que é possível listar um blogpost com sucesso]
- Ao listar um post com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
200
:
{ "id": 1, "title": "Post do Ano", "content": "Melhor post do ano", "userId": 1, "published": "2011-08-01T19:58:00.000Z", "updated": "2011-08-01T19:58:51.000Z", "user": { "id": 1, "displayName": "Lewis Hamilton", "email": "[email protected]", "image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg" }, "categories": [ { "id": 1, "name": "Inovação" } ] }
- Ao listar um post com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
-
[Será validado que não é possível listar um blogpost inexistente]
- Se o post for inexistente o resultado retornado deverá ser conforme exibido abaixo, com um status http
404
:
{ "message": "Post does not exist" }
- Se o post for inexistente o resultado retornado deverá ser conforme exibido abaixo, com um status http