Neste projeto foi desenvolvida uma API RESTful
utilizando a arquitetura MSC, em conjunto com o ORM
Sequelize
.
A API trata-se de um sistema de gerenciamento de um Blog, onde é possível, utilizando o CRUD
, gerenciar posts, usuários e categorias. Também possui rotas de cadastro e login, feitas utilizando a biblioteca JSON Web Token
para gerenciar o login e atividades dos usuários no Blog.
Desenvolvido usando: Javascript, Express, Node.js, Sequelize, JWT, Joi, ESlint, Mysql, Mocha, Chai, Sinon
Instale as dependências do projeto:
npm install
Para que o projeto funcione corretamente será necessário criar um arquivo do tipo .env
com as variáveis de ambiente referentes ao banco de dados, portas a serem utilizadas e o seu segredo para utilizar o JWT. Por exemplo, caso o seu usuário SQL seja nome
e a senha 1234
seu arquivo .env
ficará desta forma:
MYSQL_USER=nome
MYSQL_PASSWORD=1234
HOSTNAME=localhost
PORT=3000
JWT_SECRET=secret
Logo em seguida será necessário criar o banco de dados e as tabelas que vão compor o banco. Para isso basta ter o MySQL ativo na máquina, e utilizar os seguintes comandos:
npm run prestart
Este comando vai automaticamente criar o banco de dados da API e criar todas as tabelas.
Caso queira automaticamente incluir alguns dados para testes nas tabelas, basta rodar o seguinte comando:
npm run seed
O banco tem as seguintes tabelas: users
, categories
e blogposts
e postscategories
.
A tabela users
tem o seguinte formato:
A tabela categories
tem o seguinte formato:
A tabela blogposts
tem o seguinte formato:
A tabela postscategories
, é a tabela que faz o relacionamento N:N
entre blogposts
e categories
e tem o seguinte formato:
Para executar a aplicação normalmente:
npm start
Para executar em modo de desenvolvimento, com a ferramenta Nodemon
, onde a cada vez que um arquivo é alterado, o servidor é reiniciado automaticamente, assim, não há a necessidade de utilizar o npm start
a cada alteração feita nos arquivos.
npm run debug
A API possui até o momento somente testes unitários para a camada Service
, para rodar os testes basta executar o comando abaixo:
npm test
Rota responsável por cadastrar um usuário no blog, na tabela users
. o body
da requisição deve ter o seguinte formato:
{
"displayName": "nome",
"email": "email@email.com",
"password": "123456",
"image": "http://image/image.png"
}
Exemplo de retorno com sucesso:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjp7ImlkIjo1LCJkaXNwbGF5TmFtZSI6InVzdWFyaW8gZGUgdGVzdGUiLCJlbWFpbCI6InRlc3RlQGVtYWlsLmNvbSIsImltYWdlIjoibnVsbCJ9LCJpYXQiOjE2MjAyNDQxODcsImV4cCI6MTYyMDY3NjE4N30.Roc4byj6mYakYqd9LTCozU1hd9k_Vw5IWKGL4hcCVG8"
}
token fictício
Ao realizar o cadastro será retornado um token, que será necessário para realizar ações outras ações na API.
- Somente o atributo
image
é opcional ao realizar a requisição; - Atributo
displayName
não pode ter menos de 8 caracteres; - Não será possível cadastrar um usuário que já esteja com o mesmo
email
no banco; - Atributo
email
deve ter o formato correto<prefixo>@<domínio>
; - Atributo
password
deve ter6
caracteres.
Rota responsável por realizar o login de um usuário cadastrado. o body
da requisição deve ter o seguinte formato:
{
"email": "email@mail.com",
"password": "123456"
}
Exemplo de retorno com sucesso:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjp7ImlkIjo1LCJkaXNwbGF5TmFtZSI6InVzdWFyaW8gZGUgdGVzdGUiLCJlbWFpbCI6InRlc3RlQGVtYWlsLmNvbSIsImltYWdlIjoibnVsbCJ9LCJpYXQiOjE2MjAyNDQxODcsImV4cCI6MTYyMDY3NjE4N30.Roc4byj6mYakYqd9LTCozU1hd9k_Vw5IWKGL4hcCVG8"
}
token fictício
Ao realizar o login será retornado um token, que será necessário para realizar ações outras ações na API.
Quando os dados de login estão incorretos:
{
"message": "Invalid fields"
}
- Atributos
email
epassword
não podem estar vazios ou faltando.
Rota responsável por listar todos os usuários cadastrados na tabela users
. Para realizar a listagem será necessário possuir um token, que é gerado ao realizar o cadastro ou o login do usuário, e incluí-lo nos headers
da requisição com a chave authorization
.
Quando o token não é informado na requisição:
{
"message": "Token not found"
}
Quando o token é inválido:
{
"message": "Expired or invalid token"
}
Exemplo de retorno com sucesso:
[
{
"id": 1,
"displayName": "nome",
"email": "email@email.com",
"password": "123456",
"image": "http://image/image.png"
}
]
Rota responsável por listar um único usuário cadastrado na tabela users
. Para realizar a listagem será necessário possuir um token, que é gerado ao realizar o cadastro ou o login do usuário, e incluí-lo nos headers
da requisição com a chave authorization
.
Quando o token não é informado na requisição:
{
"message": "Token not found"
}
Quando o token é inválido:
{
"message": "Expired or invalid token"
}
Exemplo de retorno com sucesso:
{
"id": 1,
"displayName": "nome",
"email": "email@email.com",
"password": "123456",
"image": "http://image/image.png"
}
Quando o usuário com o id informado não existe:
{
"message": "User does not exist"
}
Rota responsável por deletar o usuário logado. Para realizar a remoção do usuário será necessário possuir um token, que é gerado ao realizar o cadastro ou o login do usuário, e incluí-lo nos headers
da requisição com a chave authorization
.
Quando o token não é informado na requisição:
{
"message": "Token not found"
}
Quando o token é inválido:
{
"message": "Expired or invalid token"
}
Quando o usuário é removido com sucesso, é retornado o status 204
sem nenhum conteúdo:
no body returned for response
Rota responsável por cadastrar uma nova categoria na tabela categories
. Para realizar o cadastro será necessário possuir um token, que é gerado ao realizar o cadastro ou o login do usuário, e incluí-lo nos headers
da requisição com a chave authorization
.
Quando o token não é informado na requisição:
{
"message": "Token not found"
}
Quando o token é inválido:
{
"message": "Expired or invalid token"
}
Além disso, o body
da requisição deve ter o seguinte formato:
{
"name": "Tecnologia"
}
Exemplo de retorno com sucesso:
{
"id": 1,
"name": "Tecnologia"
}
- Atributo
name
não pode estar vazio ou faltando.
Rota responsável por listar as categorias cadastradas na tabela categories
. Para realizar a listagem será necessário possuir um token, que é gerado ao realizar o cadastro ou o login do usuário, e incluí-lo nos headers
da requisição com a chave authorization
.
Quando o token não é informado na requisição:
{
"message": "Token not found"
}
Quando o token é inválido:
{
"message": "Expired or invalid token"
}
Exemplo de retorno com sucesso:
[
{
"id": 1,
"name": "Escola"
},
{
"id": 2,
"name": "Inovação"
}
]
Rota responsável por cadastrar um novo post do blog na tabela blogposts
. Para realizar o cadastro será necessário possuir um token, que é gerado ao realizar o cadastro ou o login do usuário, e incluí-lo nos headers
da requisição com a chave authorization
.
Quando o token não é informado na requisição:
{
"message": "Token not found"
}
Quando o token é inválido:
{
"message": "Expired or invalid token"
}
Além disso, o body
da requisição deve ter o seguinte formato:
{
"title": "New post",
"content": "Information about the new post",
"categoryIds": [1, 2]
}
Exemplo de retorno com sucesso, o post é vinculado ao id do usuário que está logado:
{
"id": 3,
"userId": 1,
"title": "New post",
"content": "Information about the new post",
"categoryIds": [1, 2]
}
Quando o id da categoria informada não existe:
{
"message": "categoryIds not found"
}
- Atributos
title
,content
ecategoryIds
não podem estar vazios ou faltando.
Rota responsável por listar todos os posts cadastrados na tabela blogposts
. Para realizar a listagem será necessário possuir um token, que é gerado ao realizar o cadastro ou o login do usuário, e incluí-lo nos headers
da requisição com a chave authorization
.
Quando o token não é informado na requisição:
{
"message": "Token not found"
}
Quando o token é inválido:
{
"message": "Expired or invalid token"
}
Exemplo de retorno com sucesso:
[
{
"id": 1,
"title": "Post",
"content": "Post content",
"userId": 1,
"published": "2011-08-01T19:58:00.000Z",
"updated": "2011-08-01T19:58:51.000Z",
"user": {
"id": 1,
"displayName": "User",
"email": "email@email.com",
"image": "https://image/image.jpg"
},
"categories": [
{
"id": 1,
"name": "Tecnologia"
}
]
}
]
Rota responsável por listar um único post cadastrado na tabela blogposts
. Para realizar a listagem será necessário possuir um token, que é gerado ao realizar o cadastro ou o login do usuário, e incluí-lo nos headers
da requisição com a chave authorization
.
Quando o token não é informado na requisição:
{
"message": "Token not found"
}
Quando o token é inválido:
{
"message": "Expired or invalid token"
}
Exemplo de retorno com sucesso:
{
"id": 1,
"title": "Post",
"content": "Post content",
"userId": 1,
"published": "2011-08-01T19:58:00.000Z",
"updated": "2011-08-01T19:58:51.000Z",
"user": {
"id": 1,
"displayName": "User",
"email": "email@email.com",
"image": "https://image/image.jpg"
},
"categories": [
{
"id": 1,
"name": "Tecnologia"
}
]
}
Quando o post com o id informado não existe:
{
"message": "Post does not exist"
}
Rota responsável por atualizar os dados de um post cadastrado na tabela blogposts
com base no id. Para realizar a listagem será necessário possuir um token, que é gerado ao realizar o cadastro ou o login do usuário, e incluí-lo nos headers
da requisição com a chave authorization
.
Quando o token não é informado na requisição:
{
"message": "Token not found"
}
Quando o token é inválido:
{
"message": "Expired or invalid token"
}
Exemplo de retorno com sucesso:
{
"title": "Update Post",
"content": "Updated content",
"userId": 1,
"categories": [
{
"id": 1,
"name": "Tecnologia"
}
]
}
Quando o usuário que está tentando atualizar o post não é o criador do post:
{
"message": "Unauthorized user"
}
Não será possível atualizar o conteúdo do post quando informado o atributo categoryIds
na requisição, caso o atributo seja enviado, será retornado o seguinte erro:
{
"message": "Categories cannot be edited"
}
Quando o post com o id informado não existe:
{
"message": "Post does not exist"
}
- Atributos
title
econtent
não podem estar vazios ou faltando.
Rota responsável por deletar um post cadastrado na tabela blogposts
com base no id. Para realizar a remoção do post será necessário possuir um token, que é gerado ao realizar o cadastro ou o login do usuário, e incluí-lo nos headers
da requisição com a chave authorization
.
Quando o token não é informado na requisição:
{
"message": "Token not found"
}
Quando o token é inválido:
{
"message": "Expired or invalid token"
}
Quando o post é removido com sucesso, é retornado o status 204
sem nenhum conteúdo:
no body returned for response
Quando o usuário que está tentando remover o post não é o criador do post:
{
"message": "Unauthorized user"
}
Quando o post com o id informado não existe:
{
"message": "Post does not exist"
}
Rota responsável por listar todos os posts cadastrados na tabela blogposts
com base em um termo de pesquisa, sendo possível procurar pelo titulo ou pelo conteúdo do post. Para realizar a listagem será necessário possuir um token, que é gerado ao realizar o cadastro ou o login do usuário, e incluí-lo nos headers
da requisição com a chave authorization
.
Quando o token não é informado na requisição:
{
"message": "Token not found"
}
Quando o token é inválido:
{
"message": "Expired or invalid token"
}
Exemplo de retorno com sucesso, procurando pelo titulo do Post. post/search?q=Post
:
[
{
"id": 1,
"title": "Post",
"content": "Post content",
"userId": 1,
"published": "2011-08-01T19:58:00.000Z",
"updated": "2011-08-01T19:58:51.000Z",
"user": {
"id": 1,
"displayName": "User",
"email": "email@email.com",
"image": "https://image/image.jpg"
},
"categories": [
{
"id": 1,
"name": "Tecnologia"
}
]
}
]
- Quando não é informado nada na pesquisa são retornados todos os posts.
- Quando se busca um post inexistente é retornado um array vazio
[]