Neste projeto foi desenvolvida uma API e um banco de dados para a produção de conteúdo para um blog. Foi feito um CRUD de postagens com uma camada de autenticação de pessoas usuárias.
-
Criação de um banco de dado;
-
Desenvolvimento de endpoints devidamente conectados ao banco de dados seguindo os princípios do REST;
-
Aderência do código à especificação;
-
Organização do código.
- Clone o repositório
git clone git@github.com:GeovanaAugusta/blogs-api-project.git.
- Entre na pasta do repositório que você acabou de clonar:
cd blogs-api-project
-
Instale o Docker, caso ainda não o tenha instalado;
-
Ainda no seu terminal, use o comando:
docker-compose up -d
- Dessa forma será inicializado um container chamado blogs_api e outro chamado blogs_api_db, sendo assim possível rodar o container blogs_api via CLI ou abri-lo no VS Code. Na sequência use o comando:
docker exec -it blogs_api bash
-
Dessa forma terá acesso ao terminal interativo do container criado pelo compose que está rodando em segundo plano;
-
Por fim, instale as dependências e inicie a aplicação que rodará na porta 3000:
npm install
npm run debug- Configure as variáveis de ambiente editando o arquivo
.env.examplecom suas respectivas variáveis e o renomeando em seguida para.env. - Por fim, instale as dependências e inicie a aplicação que rodará na porta 3000:
npm install
npm run debug POST /login- Formato do corpo da Requisição:
- Body
{
"email": "lewishamilton@gmail.com",
"password": "123456"
}- Response se o login for feito com sucesso, com um status http
200:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjoiYWRtaW5AYWRtaW4uY29tIiwiaWF0IjoxNjY0NDY2NDE2LCJleHAiOjE2NjUyNDQwMTZ9.6F-bmiupvvyGZUsyzZAx8Mw7FE16ayDlU9ev0J9TtVA"
}- Response de validação ao tentar realizar um login com um usuário ou e-mail que não existe, com um status http
400:
{
"message": "Invalid fields"
}- Response de validação ao tentar realizar um login sem todos os campos devidamente preenchidos, com um status http
400:
{
"message": "Some required fields are missing"
} POST /user- Formato do corpo da Requisição:
- Body
{
"displayName": "Brett Wiltshire",
"email": "brett@email.com",
"password": "123456",
"image": "http://4.bp.blogspot.com/_YA50adQ-7vQ/S1gfR_6ufpI/AAAAAAAAAAk/1ErJGgRWZDg/S45/brett.png"
}- Response se o usuário for cadastrado com sucesso, com um status http
201:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjoiYWRtaW5AYWRtaW4uY29tIiwiaWF0IjoxNjY0NDY2NDE2LCJleHAiOjE2NjUyNDQwMTZ9.6F-bmiupvvyGZUsyzZAx8Mw7FE16ayDlU9ev0J9TtVA"
}- Response de validação ao tentar cadastrar com um email já existente, com um status http
409:
{
"message": "User already registered"
}- Response de validação ao tentar cadastrar com o campo
emailcom formato inválido<email@email.com>, com um status http400:
{
"message": "\"email\" must be a valid email"
}- Response de validação ao tentar cadastrar com o campo
passwordmenor que 6 caracteres, com um status http400:
{
"message": "\"password\" length must be at least 6 characters long"
}- Response de validação ao tentar cadastrar com o campo
displayNamemenor que 8 caracteres, com um status http400:
{
"message": "\"displayName\" length must be at least 8 characters long"
} GET /user- Response se os usuários forem listados com sucesso, 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"
},
/* ... */
]- Response de validação ao tentar listar todos os usuários se o token for inexistente, com um status http
401:
{
"message": "Token not found"
}- Response de validação ao tentar listar todos os usuários se o token for inválido , com um status http
401:
{
"message": "Expired or invalid token"
} GET /user/:id- Response se um usuário for listado com sucesso, 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"
},- Response de validação ao tentar listar um usuário inexistente, com um status http
404:
{
"message": "User does not exist"
}- Response de validação ao tentar listar um usuário se o token for inexistente, com um status http
401:
{
"message": "Token not found"
}- Response de validação ao tentar listar um usuário se o token for inválido , com um status http
401:
{
"message": "Expired or invalid token"
} POST /categories- Formato do corpo da Requisição:
- Body
{
"name": "Typescrypt"
}- Response se a categoria for cadastrada com sucesso, com um status http
201:
{
"id": 3,
"name": "Typescript"
}- Response de validação ao tentar cadastrar uma nova categoria com nome inexistente, com um status http
400:
{
"message": "\"name\" is required"
}- Response de validação ao tentar cadastrar uma nova categoria se o token for inexistente, com um status http
401:
{
"message": "Token not found"
}- Response de validação ao tentar cadastrar uma nova categoria se o token for inválido , com um status http
401:
{
"message": "Expired or invalid token"
} GET /categories- Response se as categorias forem listadas com sucesso, com um status http
200:
[
{
"id": 1,
"name": "Inovação"
},
{
"id": 2,
"name": "Escola"
},
/* ... */
]- Response de validação ao tentar listar todas as categorias se o token for inexistente, com um status http
401:
{
"message": "Token not found"
}- Response de validação ao tentar listar todas as categorias se o token for inválido , com um status http
401:
{
"message": "Expired or invalid token"
} POST /post- Formato do corpo da Requisição:
- Body
{
"title": "Latest updates, August 1st",
"content": "The whole text for the blog post goes here in this key",
"categoryIds": [1, 2]
}- Se o post for deletado com sucesso, retorna-se apenas um status http
20:
{
"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"
}- Response de validação ao tentar cadastrar um novo post sem todos os campos preenchidos, com um status http
400:
{
"message": "Some required fields are missing"
}- Response de validação ao tentar cadastrar um novo post com uma
categoryIdsinexistente, com um status http400:
{
"message": "\"categoryIds\" not found"
}- Response de validação ao tentar listar todas as categorias se o token for inexistente, com um status http
401:
{
"message": "Token not found"
}- Response de validação ao tentar listar todas as categorias se o token for inválido , com um status http
401:
{
"message": "Expired or invalid token"
} GET /post- Response se os posts forem listados com sucesso, 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"
}
]
},
/* ... */
]- Response de validação ao tentar listar todos os posts se o token for inexistente, com um status http
401:
{
"message": "Token not found"
}- Response de validação ao tentar listar todos os posts se o token for inválido , com um status http
401:
{
"message": "Expired or invalid token"
} GET /post/:id- Response se o post for listado com sucesso, 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"
}
]
},- Response de validação ao tentar listar um post inexistente, com um status http
404:
{
"message": "Post does not exist"
}- Response de validação ao tentar listar um post se o token for inexistente, com um status http
401:
{
"message": "Token not found"
}- Response de validação ao tentar listar um post se o token for inválido , com um status http
401:
{
"message": "Expired or invalid token"
} PUT /post/:id- Formato do corpo da Requisição:
- Body
{
"title": "Latest updates, August 1st",
"content": "The whole text for the blog post goes here in this key",
}- Response se o post for editado com sucesso, 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"
}
]
}- Response de validação ao tentar editar um blogpost sem ser o usuário que o criou, com um status http
401:
{
"message": "Unauthorized user"
}- Response de validação ao tentar editar um post sem todos os campos preenchidos, com um status http
400:
{
"message": "Some required fields are missing"
}- Response de validação ao tentar listar um post se o token for inexistente, com um status http
401:
{
"message": "Token not found"
}- Response de validação ao tentar listar um post se o token for inválido , com um status http
401:
{
"message": "Expired or invalid token"
} DELETE /post/:id-
Se o post for deletado com sucesso, retorna-se apenas um status http
204. -
Response de validação ao tentar deletar um post sem ser o usuário que o criou, com um status http
401:
{
"message": "Unauthorized user"
}- Response de validação ao tentar deletar um post inexistente, com um status http
404:
{
"message": "Post does not exist"
}- Response de validação ao tentar deletar um post se o token for inexistente, com um status http
401:
{
"message": "Token not found"
}- Response de validação ao tentar deletar um post se o token for inválido , com um status http
401:
{
"message": "Expired or invalid token"
} DELETE /user/me-
Se o meu usuário for deletado com sucesso, retorna-se apenas um status http
204. -
Response de validação ao tentar deletar meu usuário se o token for inexistente, com um status http
401:
{
"message": "Token not found"
}- Response de validação ao tentar deletar meu usuário se o token for inválido , com um status http
401:
{
"message": "Expired or invalid token"
} GET /post/search?q=:searchTerm- Response se a busca pelo
titlefor bem sucedida, 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"
}
]
}
]- Response se a busca pelo
contentfor bem sucedida, 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"
}
]
}
]- Response se a busca for um termo vazio e listar todos os posts com sucesso, 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"
}
]
},
/* ... */
]- Response se a busca for um post inexistente, com um status http
200:
// GET /post/search?q=TERMOX
[]- Response de validação ao tentar realizar uma busca por um post se o token for inexistente, com um status http
401:
{
"message": "Token not found"
}- Response de validação ao tentar realizar uma busca por um post se o token for inválido , com um status http
401:
{
"message": "Expired or invalid token"
}