Esse é um dos projetos que eu desenvolvi no módulo de Back-End da Trybe, e consiste de uma API feita com Node e Express com endpoints que manipulam um banco de dados MySQL pelo ORM sequelize.
Clone o repositório e entre na pasta com:
$ git clone https://github.com/gralmeidan/trybe-blog-api.git
$ cd trybe-blog-api
Suba o contâiner do banco de dados com:
$ docker-compose up -d
Instale as dependências com:
$ npm install
Faça a devida configuração do arquivo .env
de acordo com o template do .env.example
.
Configure o banco de dados com os comandos:
$ npm run prestart
$ npm run seed
E por fim, inicie o servidor com:
$ npm run debug
Recebe um body com um email e uma senha, verifica se ambos existem em conjunto dentro do banco de dados, e se existirem, retorna um token de autenticação
Exemplo de corpo de requisição:
{
"email": "lewishamilton@gmail.com",
"password": "123456"
}
Recebe um body com as informações de um usuário e os registra em um banco de dados, requer um token de autenticação no campo Authorization do Header.
Exemplo de corpo de requisição:
{
"displayName": "Brett Wiltshire",
"email": "brett@email.com",
"password": "123456",
"image": "http://4.bp.blogspot.com/_YA50adQ-7vQ/S1gfR_6ufpI/AAAAAAAAAAk/1ErJGgRWZDg/S45/brett.png"
// a imagem não é obrigatória
}
Exemplo de resposta:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjp7ImlkIjo1LCJkaXNwbGF5TmFtZSI6InVzdWFyaW8gZGUgdGVzdGUiLCJlbWFpbCI6InRlc3RlQGVtYWlsLmNvbSIsImltYWdlIjoibnVsbCJ9LCJpYXQiOjE2MjAyNDQxODcsImV4cCI6MTYyMDY3NjE4N30.Roc4byj6mYakYqd9LTCozU1hd9k_Vw5IWKGL4hcCVG8"
}
Retorna uma lista com todos os usuários registrados no banco de dados. Requer um token de autenticação no campo Authorization do Header.
Exemplo de resposta:
[
{
"id": 1,
"displayName": "Lewis Hamilton",
"email": "lewishamilton@gmail.com",
"image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg"
},
/* ... */
]
Retorna o usuário identificado pelo parâmetro id. Requer um token de autenticação no campo Authorization do Header.
Exemplo de resposta:
{
"id": 1,
"displayName": "Lewis Hamilton",
"email": "lewishamilton@gmail.com",
"image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg"
}
Recebe um body com as informações de uma categoria e as registra no banco de dados. Requer um token de autenticação no campo Authorization do Header.
Exemplo de corpo de requisição:
{
"name": "Typescript"
}
Exemplo de resposta:
{
"id": 3,
"name": "Typescript"
}
Retorna todas as categorias registradas no banco de dados. Requer um token de autenticação no campo Authorization do header.
Exemplo de resposta:
[
{
"id": 1,
"name": "Inovação"
},
{
"id": 2,
"name": "Escola"
},
/_ ... _/
]
Recebe um body com as informações de um post de blog e as registra no banco de dados. Requer um token de autenticação no campo Authorization do Header.
Exemplo de corpo de requisição:
{
"title": "Latest updates, August 1st",
"content": "The whole text for the blog post goes here in this key",
"categoryIds": [1, 2]
}
Exemplo de resposta:
{
"id": 3,
"title": "Latest updates, August 1st",
"content": "The whole text for the blog post goes here in this key",
"userId": 1,
"updated": "2022-05-18T18:00:01.196Z",
"published": "2022-05-18T18:00:01.196Z"
}
Retorna todos os posts registrados no banco de dados. Requer um token de autenticação no campo Authorization do header.
Exemplo de resposta:
[
{
"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": "lewishamilton@gmail.com",
"image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg"
},
"categories": [
{
"id": 1,
"name": "Inovação"
}
]
},
/* ... */
]
Retorna um post registrado no banco de dados. Requer um token de autenticação no campo Authorization do header.
Exemplo de resposta:
{
"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": "lewishamilton@gmail.com",
"image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg"
},
"categories": [
{
"id": 1,
"name": "Inovação"
}
]
}
Recebe o title e o content para ser atualizados em um post e os modifica no banco de dados.
Exemplo de corpo de requisição:
{
"title": "Latest updates, August 1st",
"content": "The whole text for the blog post goes here in this key"
}
Exemplo de resposta:
{
"id": 3,
"title": "Latest updates, August 1st",
"content": "The whole text for the blog post goes here in this key",
"userId": 1,
"published": "2022-05-18T18:00:01.000Z",
"updated": "2022-05-18T18:07:32.000Z",
"user": {
"id": 1,
"displayName": "Lewis Hamilton",
"email": "lewishamilton@gmail.com",
"image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg"
},
"categories": [
{
"id": 1,
"name": "Inovação"
},
{
"id": 2,
"name": "Escola"
}
]
}
Deleta um post do banco de dados. Requer um token de autenticação no campo Authorization do header.
Retorna uma mensagem vazia com status 204.
Deleta o próprio usuário do banco de dados. Requer um token de autenticação no campo Authorization do header.
Retorna uma mensagem vazia com status 204.
Retorna todos os posts do banco de dados que tenham o searchTerm em seu title ou content. Requer um token de autenticação no campo Authorization do header.
Exemplo de resposta:
// GET /post/search?q=Vamos que vamos
[
{
"id": 2,
"title": "Vamos que vamos",
"content": "Foguete não tem ré",
"userId": 1,
"published": "2011-08-01T19:58:00.000Z",
"updated": "2011-08-01T19:58:51.000Z",
"user": {
"id": 1,
"displayName": "Lewis Hamilton",
"email": "lewishamilton@gmail.com",
"image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg"
},
"categories": [
{
"id": 2,
"name": "Escola"
}
]
}
]
Estes são os requisitos pelos quais eu fui avaliado na Trybe.
- Esse teste fará uma conexão no banco utilizando a configuração de teste do arquivo
src/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. - Todas as tabelas e colunas devem estar em
snake_case
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 users, é possível fazer um INSERT e um SELECT na tabela blog_posts]
- Dado que
blog_posts
possui uma chave estrangeirauser_id
:- 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
blog_posts
; - O avaliador irá fazer um select, desse mesmo dado, na tabela
blog_posts
.
- O avaliador irá inserir um dado de exemplo na tabela
- Dado que
-
[Será validado que, a partir de INSERTs em users, categories e blog_posts, é possível fazer um INSERT e um SELECT na tabela posts_categories]
- Dado que
posts_categories
possui uma chave primária composta de duas chaves estrangeiras, respectivamente,post_id
,category_id
:- 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
blog_posts
;
- O avaliador irá inserir um dado de exemplo na tabela
- Desse modo:
- O avaliador irá inserir um dado de exemplo na tabela
posts_categories
; - O avaliador irá fazer um select, desse mesmo dado, na tabela
posts_categories
.
- 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; - As propriedades podem estar em
camelCase
seunderscored
fortrue
. Ou seja, quando os dados forem inseridos ou selecionados viamodel
devem estar emcamelCase
, mas quando as queries forem pra o banco os campos das colunas devem estar emsnake_case
. - Sua
model
deve ser desenvolvida em formato funcional, ou seja, não pode ser uma classe.
Se você usa MacOS
Esse requisito pode dar um falso positivo! Garanta que o nome do arquivo está em PascalCase
. O avaliador, que roda em Linux, é case-sensitive para arquivos, enquanto o MacOS, entre outros sistemas, são case-insensitive. Ou seja: na sua máquina pode rodar, e no avaliador não, então fique de olho! Caso queria se aprofundar nesse assunto, veja o seguinte link.
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 'display_name']
-
[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": "lewishamilton@gmail.com",
"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": "brett@email.com", "password": "123456", "image": "http://4.bp.blogspot.com/_YA50adQ-7vQ/S1gfR_6ufpI/AAAAAAAAAAk/1ErJGgRWZDg/S45/brett.png" // a imagem não é obrigatória }
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": "lewishamilton@gmail.com", "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": "lewishamilton@gmail.com", "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
- 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 ser desenvolvida em formato funcional, ou seja, não pode ser uma classe.
Se você usa MacOS
Esse requisito pode dar um falso positivo! Garanta que o nome do arquivo está em PascalCase
. O avaliador, que roda em Linux, é case-sensitive para arquivos, enquanto o MacOS, entre outros sistemas, são case-insensitive. Ou seja: na sua máquina pode rodar, e no avaliador não, então fique de olho! Caso queria se aprofundar nesse assunto, veja o seguinte link.
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
-
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
; -
As propriedades podem estar em
camelCase
seunderscored
fortrue
. Ou seja, quando os dados forem inseridos ou selecionados viamodel
devem estar emcamelCase
, mas quando as queries forem pra o banco os campos das colunas devem estar emsnake_case
. -
Sua
model
deve ser desenvolvida em formato funcional, ou seja, não pode ser uma classe. -
✨ Dica:
- Explore como renomear campos no Sequelize;
Se você usa MacOS
Esse requisito pode dar um falso positivo! Garanta que o nome do arquivo está em PascalCase
. O avaliador, que roda em Linux, é case-sensitive para arquivos, enquanto o MacOS, entre outros sistemas, são case-insensitive. Ou seja: na sua máquina pode rodar, e no avaliador não, então fique de olho! Caso queria se aprofundar nesse assunto, veja o seguinte link.
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 'user_id']
-
[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']
11 - Crie o modelo PostCategory
em src/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
; - As propriedades podem estar em
camelCase
seunderscored
fortrue
. Ou seja, quando os dados forem inseridos ou selecionados viamodel
devem estar emcamelCase
, mas quando as queries forem pra o banco os campos das colunas devem estar emsnake_case
. - Sua
model
deve ser desenvolvida em formato funcional, ou seja, não pode ser uma classe.
Se você usa MacOS
Esse requisito pode dar um falso positivo! Garanta que o nome do arquivo está em PascalCase
. O avaliador, que roda em Linux, é case-sensitive para arquivos, enquanto o MacOS, entre outros sistemas, são case-insensitive. Ou seja: na sua máquina pode rodar, e no avaliador não, então fique de olho! Caso queria se aprofundar nesse assunto, veja o seguinte link.
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 'post_id']
-
[Será validado que o modelo possui a propriedade 'category_id']
-
[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 adicionar um novo blog post e vinculá-lo às categorias em suas tabelas no banco de dados;
-
O corpo da requisição deverá seguir o formato abaixo:
{ "title": "Latest updates, August 1st", "content": "The whole text for the blog post goes here in this key", "categoryIds": [1, 2] }
-
✨ Dicas:
- Explore outros find na documentação do Sequelize;
- Explore outros insert na documentação do Sequelize;
- Explore a seção Transações do dia 24.2 no course, essa seção vai deixar suas aplicações com mais confiablidade e atomicidade, quando o assunto for transações de 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 não é possível cadastrar 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 cadastrar um blog_post com uma
categoryIds
inexistente]- Se a requisição não tiver o campo
categoryIds
devidamente preenchido com um array com pelo menos uma categoria que exista, o resultado retornado deverá ser conforme exibido abaixo, com um status http `400``:
{ "message": "\"categoryIds\" not found" }
- Se a requisição não tiver o campo
-
[Será validado que é possível cadastrar um blog_post com sucesso]
- Se o blog post for criado com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
201
:
{
"id": 3,
"title": "Latest updates, August 1st",
"content": "The whole text for the blog post goes here in this key",
"userId": 1,
"updated": "2022-05-18T18:00:01.196Z",
"published": "2022-05-18T18:00:01.196Z"
}
- ☝ 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 blogs 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": "lewishamilton@gmail.com", "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": "lewishamilton@gmail.com", "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
- ☝ 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 alterar um post do banco de dados, se ele existir;
- Sua aplicação só deve permitir a alteração de um blog post caso a pessoa seja dona dele;
- Sua aplicação não deve permitir a alteração das categorias do post, somente os atributos
title
econtent
podem ser alterados; - O corpo da requisição deverá seguir o formato abaixo:
{ "title": "Latest updates, August 1st", "content": "The whole text for the blog post goes here in this key" }
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 editar um blogpost com outro usuário]
- Somente o user que criou o blog post poderá editá-lo, o resultado retornado deverá ser conforme exibido abaixo, com um status http
401
{ "message": "Unauthorized user" }
- Somente o user que criou o blog post poderá editá-lo, o resultado retornado deverá ser conforme exibido abaixo, com um status http
-
[Será validado que não é possível editar 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 é possível editar um blogpost com sucesso]
- Se o blog post for alterado com sucesso o resultado retornado deverá ser conforme exibido abaixo, com um status http
200
:
{ "id": 3, "title": "Latest updates, August 1st", "content": "The whole text for the blog post goes here in this key", "userId": 1, "published": "2022-05-18T18:00:01.000Z", "updated": "2022-05-18T18:07:32.000Z", "user": { "id": 1, "displayName": "Lewis Hamilton", "email": "lewishamilton@gmail.com", "image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg" }, "categories": [ { "id": 1, "name": "Inovação" }, { "id": 2, "name": "Escola" } ] }
- Se o blog post for alterado 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 deletar um blog post baseado no
id
do banco de dados se ele existir; - Sua aplicação só deve permitir a deleção de um blog post caso a pessoa seja dona dele;
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 deletar um blogpost com outro usuário]
- Somente o user que criou o blog post poderá deletá-lo, o resultado retornado deverá ser conforme exibido abaixo, com um status http
401
{ "message": "Unauthorized user" }
- Somente o user que criou o blog post poderá deletá-lo, o resultado retornado deverá ser conforme exibido abaixo, com um status http
-
[Será validado que é possível deletar um blogpost com sucesso]
- Se o blog post for deletado com sucesso não deve ser retornada nenhuma resposta, apenas um status http
204
:
- Se o blog post for deletado com sucesso não deve ser retornada nenhuma resposta, apenas um status http
-
[Será validado que não é possível deletar 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
- ☝ 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/me
; - O endpoint deve ser capaz de deletar você do banco de dados, baseado no
id
que esta dentro do seutoken
; - Sua aplicação deve ser capaz de utilizar o token de autenticação nos headers, para saber o user logado correspondente á ser apagado;
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 excluir meu usuário com sucesso]
- Se o user for deletado com sucesso não deve ser retornada nenhuma resposta, apenas um status http
204
:
- Se o user for deletado com sucesso não deve ser retornada nenhuma resposta, apenas 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/search
; -
O endpoint deve ser capaz de trazer os blogs post baseados no
q
do banco de dados, se ele existir; -
Sua aplicação deve ser capaz de retornar um array de blogs post que contenham em seu título ou conteúdo o termo passado na URL;
-
Sua aplicação deve ser capaz de retornar um array vázio caso nenhum blog post satisfaça a busca;
-
O query params da requisição deverá seguir o formato abaixo:
http://localhost:PORT/post/search?q=vamos
-
✨ Dica:
- Explore como fazer LIKE no Sequelize igual aprendemos no dia 20.3 - Pesquisas mais dinâmicas e maleáveis com LIKE do course;
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 buscar um blogpost pelo
title
]- Se a buscar for pelo
title
o resultado retornado deverá ser conforme exibido abaixo, com um status http200
:
// GET /post/search?q=Vamos que vamos [ { "id": 2, "title": "Vamos que vamos", "content": "Foguete não tem ré", "userId": 1, "published": "2011-08-01T19:58:00.000Z", "updated": "2011-08-01T19:58:51.000Z", "user": { "id": 1, "displayName": "Lewis Hamilton", "email": "lewishamilton@gmail.com", "image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg" }, "categories": [ { "id": 2, "name": "Escola" } ] } ]
- Se a buscar for pelo
-
[Será validado que é possível buscar um blogpost pelo
content
]- Se a buscar for pelo
content
o resultado retornado deverá ser conforme exibido abaixo, com um status http200
:
// GET /post/search?q=Foguete não tem ré [ { "id": 2, "title": "Vamos que vamos", "content": "Foguete não tem ré", "userId": 1, "published": "2011-08-01T19:58:00.000Z", "updated": "2011-08-01T19:58:51.000Z", "user": { "id": 1, "displayName": "Lewis Hamilton", "email": "lewishamilton@gmail.com", "image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg" }, "categories": [ { "id": 2, "name": "Escola" } ] } ]
- Se a buscar for pelo
-
[Será validado que é possível buscar todos os blogpost quando passa a busca vazia]
- Se a buscar for vazia o resultado retornado deverá ser conforme exibido abaixo, com um status http
200
:
// GET /post/search?q= [ { "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": "lewishamilton@gmail.com", "image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg" }, "categories": [ { "id": 1, "name": "Inovação" } ] } /* ... */ ]
- Se a buscar for vazia o resultado retornado deverá ser conforme exibido abaixo, com um status http
-
[Será validado que é possível buscar um blogpost inexistente e retornar array vazio]
- Se a buscar um post inexistente o resultado retornado deverá ser conforme exibido abaixo, com um status http
200
:
// GET /post/search?q=BATATA []
- Se a buscar um post inexistente o resultado retornado deverá ser conforme exibido abaixo, com um status http