Skip to content

rafaelgeronimo/trybe-project-blogs-api

Repository files navigation

JavaScript NodeJS

trybe-project-blogs-api

📗 Sobre

Projeto desenvolvido para o módulo de Desenvolvimento Back-end da Trybe, onde estudamos os princípios da Arquitetura SOLID e ORM (Interface da aplicação com o banco de dados e Associations).

Nesse projeto, praticamos o desenvolvimento de um back-end usando ORM com o pacote sequelize do npm, mostrando que após as aulas, nós somos capazes de:

  • Criar e associar tabelas usando models do sequelize
  • Construir endpoints para consumir os models que criamos
  • Fazer um CRUD com o ORM

Módulo: Desenvolvimento Back-end

Bloco: Arquitetura: SOLID e ORM

O que foi desenvolvido

Foi arquiteturado e desenvolvido uma API de um CRUD posts de blog (com o sequelize). Começando pela API, desenvolvemos alguns endpoints (seguindo os princípios do REST) que estão conectados ao banco de dados, aplicando os princípios SOLID!

Primeiro, criamos uma tabela para os usuários que desejam se cadastrar na aplicação. Após isso, criamos também uma tabela de Categorias para seus Posts e por fim a tabela de Posts, guardando todas as informações dos posts realizados na plataforma.

Para fazer um post é necessário usuário e login, portanto foi trabalhada a relação entre user e post. Também foi necessário a utlização de categorias para seus posts, assim trabalhando a relação de posts para categorias e de categorias para posts.

🚀 Demo

URL Base: https://rafaelgeronimo-blogs-api.herokuapp.com/

Rotas: https://rafaelgeronimo-blogs-api.herokuapp.com/user

https://rafaelgeronimo-blogs-api.herokuapp.com/login

https://rafaelgeronimo-blogs-api.herokuapp.com/categories

https://rafaelgeronimo-blogs-api.herokuapp.com/post

Obs.: O método POST na rota /user é a única que não é necessário o token authotization no header da requisição. Todos os demais métodos exigem essa variável para autenticação.

🖼 Captura de tela

Em breve

🛠 Instalação

  • Realize o clone do projeto com o comando:
git clone git@github.com:rafaelgeronimo/trybe-project-blogs-api.git
  • Instale o projeto com npm ou yarn:
cd trybe-project-blogs-api

## instalando com o npm:
npm install

## instalando com o yarn:
yarn install
  • Configurando as variáveis de ambiente: Para que esse projeto funcione adequadamente no seu ambiente, será necessário criar o arquivo .env na raíz do projeto, contendo os dados de acesso ao banco de dados MySQL:
# Banco de dados
MYSQL_USER=nome_de_user_do_mysql
MYSQL_PASSWORD=senha_de_user_do_mysql
HOSTNAME=endereco_do_servidor_mysql(localhost ou outro)

# JWT
JWT_SECRET=senha_aleatória_para_criptografia

💻 Tecnologias

Este projeto foi desenvolvido com as seguintes tecnologias:

  • NodeJs
  • Express
  • MySQL
  • SOLID
  • ORM Sequelize

Requisitos do projeto

Requisitos obrigatórios

1. Sua aplicação deve ter o endpoint POST /user
  • O endpoint deve ser capaz de adicionar um novo user a sua tabela no banco de dados;
  • O corpo da requisição deverá ter o seguinte formato:
            {
              "displayName": "Brett Wiltshire",
              "email": "brett@email.com",
              "password": "123456",
              "image": "http://4.bp.blogspot.com/_YA50adQ-7vQ/S1gfR_6ufpI/AAAAAAAAAAk/1ErJGgRWZDg/S45/brett.png"
            }
          
  • O campo displayName deverá ser uma string com no mínimo de 8 caracteres;
  • O campo email será considerado válido se tiver o formato @ e se for único. Ele é obrigatório.
  • A senha deverá conter 6 caracteres. Ela é obrigatória.
  • Caso exista uma pessoa com o mesmo email na base, deve-se retornar o seguinte erro:
            {
              "message": "User already registered"
            }
          
  • Caso contrário, retornar a mesma resposta do endpoint de /login, um token JWT:
            {
              "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjp7ImlkIjo1LCJkaXNwbGF5TmFtZSI6InVzdWFyaW8gZGUgdGVzdGUiLCJlbWFpbCI6InRlc3RlQGVtYWlsLmNvbSIsImltYWdlIjoibnVsbCJ9LCJpYXQiOjE2MjAyNDQxODcsImV4cCI6MTYyMDY3NjE4N30.Roc4byj6mYakYqd9LTCozU1hd9k_Vw5IWKGL4hcCVG8"
            }
          
    O token anterior é fictício
2. Sua aplicação deve ter o endpoint POST /login
  • O corpo da requisição deverá seguir o formato abaixo:
            {
              "email": "email@mail.com",
              "password": "123456"
            }
          
  • Caso algum desses campos seja inválido ou não exista um usuário correspondente no banco de dados, retorne um código de status 400 com o corpo { message: "Campos inválidos" }.
  • Caso esteja tudo certo com o login, a resposta deve ser um token JWT, no seguinte formato:
            {
              "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjp7ImlkIjo1LCJkaXNwbGF5TmFtZSI6InVzdWFyaW8gZGUgdGVzdGUiLCJlbWFpbCI6InRlc3RlQGVtYWlsLmNvbSIsImltYWdlIjoibnVsbCJ9LCJpYXQiOjE2MjAyNDQxODcsImV4cCI6MTYyMDY3NjE4N30.Roc4byj6mYakYqd9LTCozU1hd9k_Vw5IWKGL4hcCVG8"
            }
          
    O token anterior é fictício
3. Sua aplicação deve ter o endpoint GET /user
  • Deve listar todos os Users e retorná-los na seguinte estrutura:
            [
              {
                "id": "401465483996",
                "displayName": "Brett Wiltshire",
                "email": "brett@email.com",
                "image": "http://4.bp.blogspot.com/_YA50adQ-7vQ/S1gfR_6ufpI/AAAAAAAAAAk/1ErJGgRWZDg/S45/brett.png"
              }
            ]
          
  • A requisição deve ter token de autenticação nos headers e, caso contrário, retorne um código de status 401.
4. Sua aplicação deve ter o endpoint GET /user/:id
  • Retorna os detalhes do usuário baseado no id da rota. Os dados devem ter o seguinte formato:
            {
              "id": "401465483996",
              "displayName": "Brett Wiltshire",
              "email": "brett@email.com",
              "image": "http://4.bp.blogspot.com/_YA50adQ-7vQ/S1gfR_6ufpI/AAAAAAAAAAk/1ErJGgRWZDg/S45/brett.png"
            }
          
  • A requisição deve ter token de autenticação nos headers e, caso contrário, retorne um código de status 401.
5. Sua aplicação deve ter o endpoint POST /categories
  • Esse endpoint deve receber uma _Categoria_ no corpo da requisição e criá-la no banco. O corpo da requisição deve ter a seguinte estrutura:
            {
              "name": "Inovação"
            }
          
  • Caso a Categoria não contenha o name a API deve retornar um erro de status 400.
  • A requisição deve ter o token de autenticação nos headers e, caso contrário, retorne um código de status 401.
6. Sua aplicação deve ter o endpoint GET /categories
  • Esse endpoint deve listar todas as Categorias e retorná-las na seguinte estrutura:
            [
              {
                "id": 1,
                "name": "Escola"
              },
              {
                "id": 2,
                "name": "Inovação"
              }
            ]
          
7. Sua aplicação deve ter o endpoint POST /post
  • Esse endpoint deve receber um _BlogPost_ no corpo da requisição e criá-lo no banco. O corpo da requisição deve ter a seguinte estrutura:
            {
              "title": "Latest updates, August 1st",
              "content": "The whole text for the blog post goes here in this key",
              "categoryIds": [1, 2]
            }
          
  • Caso o post não contenha o title, content ou categoryIds a API deve retornar um erro de status 400.
  • A requisição deve ter o token de autenticação nos headers e, caso contrário, retorne um código de status 401.
8. Sua aplicação deve ter o endpoint GET /post
  • Esse endpoint deve listar todos os _BlogPosts_ e retorná-los na seguinte estrutura:
            [
              {
                "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_2017_Malaysia.jpg"
                },
                "categories": [
                  {
                    "id": 1,
                    "name": "Inovação"
                  }
                ]
              }
            ]
          
9. Sua aplicação deve ter o endpoint GET post/:id
  • Retorna um **BlogPost** com o id especificado. O retorno deve ter os seguinte formato:
            {
              "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"
                }
              ]
            }
          
10. Sua aplicação deve ter o endpoint PUT /post/:id
  • O endpoint deve receber um **BlogPost** que irá sobrescrever o original com o id especificado na URL. Só deve ser permitido para o usuário que criou o **BlogPost**.
  • A(s) categoria(s) do post **não** podem ser editadas, somente o title e content.
  • O corpo da requisição deve ter a seguinte estrutura:
            {
              "title": "Latest updates, August 1st",
              "content": "The whole text for the blog post goes here in this key"
            }
          
  • Caso uma pessoa diferente de quem criou faça a requisição, deve retornar um código status 401.
  • Caso uma requisição sem token seja recebida, deve-se retornar um código de status 401.
  • Caso o post não contenha o title e/ou o content a API deve retornar um erro de status 400.

Requisitos Bônus

11. Sua aplicação deve ter o endpoint DELETE post/:id
  • Deleta o post com o id especificado. Só deve ser permitido para o usuário que criou o **BlogPost**.
  • Caso uma pessoa diferente de quem criou faça a requisição, deve retornar um código status 401.
  • Caso uma requisição sem token seja recebida, deve-se retornar um código de status 401.
  • Caso o post referido não exista, deve-se retornar um código de status 404.
12. Sua aplicação deve ter o endpoint DELETE /user/me
  • Utilizando o token de autenticação nos headers, o usuário correspondente deve ser apagado.
13. Sua aplicação deve ter o endpoint GET post/search?q=:searchTerm
  • Retorna uma array de **BlogPosts** que contenham em seu título, ou conteúdo, o termo pesquisado no queryParam da URL. O retorno deve ter o seguinte formato:
            [
              {
                "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"
                  }
                ]
              }
            ]
          
  • Caso nenhum **BlogPost** satisfaça a busca, retorne um array vazio.

Execução de testes unitários

Estamos usando o Jest para executar os testes. Para executá-lo, use o comando a seguir:

## npm
npm test

## yarn
yarn test

Caso queria executar só um arquivo de test use o seguinte comando, considerado que quer testar o arquivo tests/req07-createPost.test.js:

## npm
npm test tests/req07-createPost.test.js

## ou

npm test req07

## yarn 

yarn test tests/req07-createPost.test.js

## ou

yarn test req07

Linter

Para garantir a qualidade do código, usamos o ESLint para fazer a sua análise estática.

Este projeto já vem com as dependências relacionadas ao linter configuradas nos arquivos package.json.

Para poder rodar os ESLint basta executar o comando npm run lint ou yarn lint. Se a análise do ESLint encontrar problemas no seu código, tais problemas serão mostrados no seu terminal. Se não houver problema no seu código, nada será impresso no seu terminal.

Você também pode instalar o plugin do ESLint no VSCode, bastar ir em extensions e baixar o plugin ESLint.