GithubHelp home page GithubHelp logo

project-blogs-api's Introduction

Boas-vindas ao repositório do projeto API de Blogs!

Para realizar o projeto, atente-se a cada passo descrito a seguir, e se tiver qualquer dúvida, nos envie por Slack! #vqv 🚀

Aqui você vai encontrar os detalhes de como estruturar o desenvolvimento do seu projeto a partir deste repositório, utilizando uma branch específica e um Pull Request para colocar seus códigos.


Termos e acordos

Ao iniciar este projeto você concorda com as diretrizes do Código de Conduta e do Manual da Pessoa Estudante da Trybe.


Entregáveis

🤷🏽‍♀️ Como entregar

Para entregar o seu projeto você deverá criar um Pull Request neste repositório.

Lembre-se que você pode consultar nosso conteúdo sobre Git & GitHub e nosso Blog - Git & GitHub sempre que precisar!


👨‍💻 O que deverá ser desenvolvido

Neste projeto você vai desenvolver uma API e um banco de dados para a produção de conteúdo para um blog!

Você deverá desenvolver uma aplicação em Node.js usando o pacote sequelize para fazer um CRUD de posts.

  1. Você deverá desenvolver endpoints que estarão conectados ao seu banco de dados seguindo os princípios do REST;

  2. Para fazer um post é necessário usuário e login, portanto será trabalhada a relação entre user e post;

  3. Será necessária a utilização de categorias para os posts, trabalhando, assim, a relação de posts para categories e de categories para posts.


🗓 Data de Entrega
  • Projeto individual.
  • Serão 3 dias de projeto.
  • Data de entrega para avaliação regular do projeto: 14/03/2023 14:00.
  • Data de entrega para avaliação final do projeto: 27/03/2023 14:00.

Orientações

🐋 Rodando no Docker vs Localmente

👉 Com Docker

⚠️ Antes de começar, seu docker-compose precisa estar na versão 1.29 ou superior. Veja aqui ou na documentação como instalá-lo. No primeiro artigo, você pode substituir onde está com 1.26.0 por 1.29.2.

ℹ️ Rode os serviços node e db com o comando docker-compose up -d --build.

  • Lembre-se de parar o mysql se estiver usando localmente na porta padrão (3306), ou adapte, caso queria fazer uso da aplicação em containers;

  • Esses serviços irão inicializar um container chamado blogs_api e outro chamado blogs_api_db;

  • A partir daqui você pode rodar o container blogs_api via CLI ou abri-lo no VS Code;

ℹ️ Use o comando docker exec -it blogs_api bash.

  • Ele te dará acesso ao terminal interativo do container criado pelo compose, que está rodando em segundo plano.

ℹ️ Instale as dependências [Caso existam] com npm install. (Instale dentro do container)

  • ⚠️ Atenção: Caso opte por utilizar o Docker, TODOS os comandos disponíveis no package.json (npm start, npm test, npm run dev, ...) devem ser executados DENTRO do container, ou seja, no terminal que aparece após a execução do comando docker exec citado acima.

  • ⚠️ Atenção: O git dentro do container não vem configurado com suas credenciais. Ou faça os commits fora do container, ou configure as suas credenciais do git dentro do container.

  • ⚠️ Atenção: Não rode o comando npm audit fix! Ele atualiza várias dependências do projeto, e essa atualização gera conflitos com o avaliador.

  • Dica: A extensão Remote - Containers (que estará na seção de extensões recomendadas do VS Code) é indicada para que você possa desenvolver sua aplicação no container Docker direto no VS Code, como você faz com seus arquivos locais.

sequelize test


👉 Sem Docker

ℹ️ Instale as dependências [Caso existam] com npm install

  • ⚠️ Atenção: Não rode o comando npm audit fix! Ele atualiza várias dependências do projeto, e essa atualização gera conflitos com o avaliador.

  • ✨ Dica: Para rodar o projeto desta forma, obrigatoriamente você deve ter o node instalado em seu computador.

  • ✨ Dica: O avaliador espera que a versão do node utilizada seja a 16.


‼️ Antes de começar a desenvolver
  1. Clone o repositório
  • git clone [email protected]:betrybe/sd-025-b-project-blogs-api.git.
  • Entre na pasta do repositório que você acabou de clonar:
    • cd sd-025-b-project-blogs-api
  1. Instale as dependências [Caso existam]
  • npm install
  1. Crie uma branch a partir da branch master
  • Verifique que você está na branch master
    • Exemplo: git branch
  • Se não estiver, mude para a branch master
    • Exemplo: git checkout master
  • Agora crie uma branch à qual você vai submeter os commits do seu projeto
    • Você deve criar uma branch no seguinte formato: nome-de-usuario-nome-do-projeto
    • Exemplo: git checkout -b joaozinho-sd-025-b-project-blogs-api
  1. Adicione as mudanças ao stage do Git e faça um commit
  • Verifique que as mudanças ainda não estão no stage
    • Exemplo: git status (deve aparecer listada a pasta joaozinho em vermelho)
  • Adicione o novo arquivo ao stage do Git
    • Exemplo:
      • git add . (adicionando todas as mudanças - que estavam em vermelho - ao stage do Git)
      • git status (deve aparecer listado o arquivo joaozinho/README.md em verde)
  • Faça o commit inicial
    • Exemplo:
      • git commit -m 'iniciando o projeto x' (fazendo o primeiro commit)
      • git status (deve aparecer uma mensagem tipo nothing to commit )
  1. Adicione a sua branch com o novo commit ao repositório remoto
  • Usando o exemplo anterior: git push -u origin joaozinho-sd-025-b-project-blogs-api
  1. Crie um novo Pull Request (PR)
  • Vá até a página de Pull Requests do repositório no GitHub
  • Clique no botão verde "New pull request"
  • Clique na caixa de seleção "Compare" e escolha a sua branch com atenção
  • Clique no botão verde "Create pull request"
  • Adicione uma descrição para o Pull Request e clique no botão verde "Create pull request"
  • Não se preocupe em preencher mais nada por enquanto!
  • Volte até a página de Pull Requests do repositório e confira que o seu Pull Request está criado

⌨️ Durante o desenvolvimento
  • Faça commits das alterações que você fizer no código regularmente

  • Lembre-se de sempre após um (ou alguns) commits atualizar o repositório remoto

  • Os comandos que você utilizará com mais frequência são:

    • git status (para verificar o que está em vermelho - fora do stage - e o que está em verde - no stage)
    • git add (para adicionar arquivos ao stage do Git)
    • git commit (para criar um commit com os arquivos que estão no stage do Git)
    • git push -u nome-da-branch (para enviar o commit para o repositório remoto na primeira vez que fizer o push de uma nova branch)
    • git push (para enviar o commit para o repositório remoto após o passo anterior)

🤝 Depois de terminar o desenvolvimento (opcional)

Para "entregar" seu projeto, siga os passos a seguir:

  • Vá até a página DO SEU Pull Request, adicione a label de "code-review" e marque seus colegas
    • No menu à direita, clique no link "Labels" e escolha a label code-review
    • No menu à direita, clique no link "Assignees" e escolha o seu usuário
    • No menu à direita, clique no link "Reviewers" e digite students, selecione o time tryber/students-sd-00

Se ainda houver alguma dúvida sobre como entregar seu projeto, aqui tem um video explicativo.

⚠️ Lembre-se de garantir que todas as issues comentadas pelo Linter estão resolvidas!


🕵🏿 Revisando um pull request

À medida que você e as outras pessoas que estudam na Trybe forem entregando os projetos, vocês receberão um alerta via Slack para também fazer a revisão dos Pull Requests de colegas. Fique atento às mensagens do "Pull Reminders" no Slack!

Use o material que você já viu sobre Code Review para te ajudar a revisar os projetos que chegaram para você.


🛠 Execução de testes localmente

ℹ️ IMPORTANTE

  • O teste local deve rodar o script npm run start:test, que vai iniciar e depois encerrar, em segundo plano outra instância da sua API, na porta 3030. Dessa forma, o teste conseguirá consumir sua API e validar os requisitos.

    • Caso seu computador não suporte rodar um servidor extra para os testes, execute um servidor na porta 3000 e rode o script npm run test:dev, este não vai criar outra instância, mas vai esperar um servidor na porta 3000.
  • Sua API deve estar funcionando minimamente para que o teste comece, dado que ele aguarda o estabelecimento da mesma para começar o teste.

  • Todos os testes vão gerar e consumir um banco de dados próprio com final *-test, que é gerado através da configuração do arquivo src/config/config.js.

  • Isso vai garantir que durante seu desenvolvimento, o teste não manipule ou derrube sua API na porta padrão (3000) ou seu banco de dados padrão (final *-dev), isolando os mesmos.

  • Caso ocorra algum problema, encerre o teste com [CTRL] + [C] e utilize o script npm run kill:test


O teste local já é configurado, internamente, com a variável de ambiente NODE_ENV=test para indicar o banco a ser utilizado pelo Sequelize, o que deve resultar na criação de um banco, somente para o teste:

sequelize test

Sem essa variável (modo padrão de desenvolvimento), sua API deve resultar algo como:

sequelize development


ℹ️ Scripts para executar os testes locais:

Vamos usar o Jest para executar os testes, use o comando a seguir para executar todos os testes:

npm test

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

npm test tests/req07-createPost.test.js

ou

npm test req07

Caso queira omitir dados de debug nos testes, utilize a variável de ambiente DEBUG=false, como em DEBUG=false npm test.


🎛 Linter

Para garantir a qualidade do código, usaremos 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 nos seguintes caminhos:

  • sd-025-b-project-blogs-api/package.json

Para poder rodar os ESLint em um projeto basta executar o comando npm install dentro do projeto e depois npm run 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 baixar o plugin ESLint e instalá-lo

⚠️ PULL REQUESTS COM ISSUES DE LINTER NÃO SERÃO AVALIADAS. ATENTE-SE PARA RESOLVÊ-LAS ANTES DE FINALIZAR O DESENVOLVIMENTO! ⚠️


⚠️ Informações importantes sobre o projeto

⚠️ Leia-os atentamente e siga à risca o que for pedido. ⚠️

👀 Observações importantes:

Em cada requisito você encontrará uma imagem demonstrando como sua API deverá se comportar, dada a requisição específica.

O não cumprimento de um requisito, total ou parcialmente, impactará em sua avaliação.

O projeto possui uma pasta src, e é fortemente recomendável que você construa sua aplicação dentro dessa pasta.

Não é necessário usar o comando npx sequelize-cli init uma vez que já é fornecido no projeto.

Arquivos importantes

⚠️ Essa pasta ainda conta com alguns arquivos auxiliares que serão consumidos pelo avaliador e não devem ser apagados em nenhuma hipótese:

src/app.js

const express = require('express');

// ...

const app = express();

// não remova ou mova esse endpoint
app.get('/', (_request, response) => {
  response.send();
});

app.use(express.json());

// ...

// É importante exportar a constante `app`,
// para que possa ser utilizada pelo arquivo `src/server.js`
module.exports = app;

Que ficará responsável por receber as definições de middlewares e rotas de sua API



👉 src/server.js

require('dotenv').config();
const app = require('./app');

// não remova a variável `API_PORT` ou o `listen`
const port = process.env.API_PORT || 3000;

app.listen(port, () => console.log('ouvindo porta', port));

Que ficará responsável por iniciar sua API



👉 src/config/config.js

require('dotenv').config();

const environment = process.env.NODE_ENV || 'test';

const suffix = {
  dev: '-dev',
  development: '-dev',
  test: '-test',
};

const options = {
  host: process.env.MYSQL_HOST || 'localhost',
  port: process.env.MYSQL_PORT || '3306',
  database: 
    `${process.env.MYSQL_DB_NAME || 'blogs-api'}${suffix[environment] || suffix.test}`,
  username: process.env.MYSQL_USER || 'root',
  password: process.env.MYSQL_PASSWORD || '1234',
  dialect: 'mysql',
  dialectOptions: {
    timezone: 'Z',
  },
  logging: process.env.DEBUG !== 'false',
};

module.exports = {
  development: {
    ...options,
  },
  test: {
    ...options,
  },
};

Que é o arquivo de configuração principal do Sequelize



👉 .sequelizerc

const path = require('path');

module.exports = {
  'config': path.resolve('src',  'config', 'config.js'),
  'models-path': path.resolve('src',  'models'),
  'seeders-path': path.resolve('src',  'seeders'),
  'migrations-path': path.resolve('src',  'migrations'),
};

Responsável por identificar os caminhos dos recursos do Sequelize



Você irá precisar configurar as variáveis de ambiente para uso do MySQL. Você pode usar esse Conteúdo de variáveis de ambiente com NodeJS como referência.

O arquivo a seguir, contém um modelo das variáveis de ambiente utilizadas no projeto. Para o contexto de teste local, é importante configurar as variáveis: MYSQL_HOST, MYSQL_PORT, MYSQL_USER, MYSQL_PASSWORD:

👉 .env.example

#### SERVER VARS
NODE_ENV=development
API_PORT=3000
API_HOST=localhost

#### DATABASE VARS
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_DB_NAME=blogs-api
MYSQL_USER=root
MYSQL_PASSWORD=1234

#### SECRECT VARS
JWT_SECRET=suaSenhaSecreta

Variável JWT_SECRET:

Esta variável de ambiente deverá ser utilizada tanto para criar o token quanto para verificá-lo. Os teste locais e o avaliador vão utilizar a variável de ambiente JWT_SECRET para testar os requisitos

⚠️️ Variáveis de ambiente além das especificadas acima não são suportadas, pois não são esperadas pelo avaliador do projeto.


👀 Dicas

Status HTTP

Tenha em mente que todas as "respostas" devem respeitar os status do protocolo HTTP com base no que o REST prega.

Alguns exemplos:

  • Requisições que precisam de token mas não o receberam devem retornar um código de status 401;

  • Requisições que não seguem o formato pedido pelo servidor devem retornar um código de status 400;

  • Um problema inesperado no servidor deve retornar um código de status 500;

  • Um acesso ao criar um recurso, no nosso caso usuário ou post, deve retornar um código de status 201.

🎲 Diagrama ER e Entidades

Diagrama de Entidade-Relacionamento

Para orientar a construção das tabelas através do ORM, utilize o DER a seguir:

DER


Formato das entidades

O seu projeto deverá usar o ORM Sequelize para criar e atualizar o seu banco de dados.

Os primeiros requisitos do projeto devem orientar a produção de suas migrations para gerar:

  • Uma tabela chamada users, contendo dados com a seguinte estrutura:

    id display_name email password image
    1 Brett Wiltshire [email protected] // tem quer ser único 123456 http://4.bp.blogspot.com/_YA50adQ-7vQ/S1gfR_6ufpI/AAAAAAAAAAk/1ErJGgRWZDg/S45/brett.png
  • Uma tabela chamada categories, contendo dados com a seguinte estrutura:

    id name
    18 News
  • Uma tabela chamada blog_posts, contendo dados com a seguinte estrutura:

    id title content user_id published updated
    21 Latest updates, August 1st The whole text for the blog post goes here in this key 14 // Chave estrangeira, referenciando o id de users 2011-08-01T19:58:00.000Z 2011-08-01T19:58:51.947Z
  • Uma tabela chamada PostCategories, contendo uma chave primária composta utilizando os dois atributos da estrutura:

    post_id category_id
    50 // Chave primária e estrangeira, referenciando o id de BlogPosts 20 // Chave primária e estrangeira, referenciando o id de Categories

    Os dados acima são fictícios, e estão aqui apenas como exemplo

    ⚠️️ Em caso de dúvidas, consulte os conteúdos:


    Dicas de scripts prontos

    • Deleta o banco de dados:
    "drop": "npx sequelize-cli db:drop"
    • Cria o banco e gera as tabelas:
    "prestart": "npx sequelize-cli db:create && npx sequelize-cli db:migrate"
    • Insere dados/Popula a tabela:
    "seed": "npx sequelize-cli db:seed:all"

    👀 OBS: Os testes irão rodar através do seu migrate usando os scripts acima, também listados no package.json.

    ⚠️ Preste bastante atenção, pois a alteração desses scripts pode impedir o avaliador de funcionar corretamente

    ⚠️️ Haverá um arquivo na pasta /seeders, que irá conter as queries para inserção no banco de dados. Não a remova, pois o avaliador depende dela.


🗣 Nos dê feedbacks sobre o projeto!

Ao finalizar e submeter o projeto, não se esqueça de avaliar sua experiência preenchendo o formulário. Leva menos de 3 minutos!

FORMULÁRIO DE AVALIAÇÃO DE PROJETO

⚠️ O avaliador automático não necessariamente avalia seu projeto na ordem em que os requisitos aparecem no readme. Isso acontece para deixar o processo de avaliação mais rápido. Então, não se assuste se isso acontecer, ok?


🗂 Compartilhe seu portfólio!

Você sabia que o LinkedIn é a principal rede social profissional e compartilhar o seu aprendizado lá é muito importante para quem deseja construir uma carreira de sucesso? Compartilhe esse projeto no seu LinkedIn, marque o perfil da Trybe (@trybe) e mostre para a sua rede toda a sua evolução.


Requisitos Obrigatórios

1 - Crie migrations para as tabelas users, categories, blog_posts, posts_categories

  • 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.
  • [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.
  • [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 estrangeira user_id:
      • O avaliador irá inserir um dado de exemplo na tabela users;
    • 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.
  • [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;
    • 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.


2 - Crie o modelo User em src/models/User.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;
  • As propriedades podem estar em camelCase se underscored for true. Ou seja, quando os dados forem inseridos ou selecionados via model devem estar em camelCase, mas quando as queries forem pra o banco os campos das colunas devem estar em snake_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']



3 - Sua aplicação deve ter o endpoint POST /login

  • 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"
    }
  • [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 e password errados/inexistentes, o resultado retornado deverá ser conforme exibido abaixo, com um status http 400:
    {
      "message": "Invalid fields"
    }
  • [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 ambiente JWT_SECRET, do payload da requisição e não deve conter o atributo password em sua construção.



4 - Sua aplicação deve ter o endpoint POST /user

  • 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"
      // 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 http 400:
    {
      "message": "\"displayName\" length must be at least 8 characters long"
    }
  • [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 http 400:
    {
      "message": "\"email\" must be a valid email"
    }
  • [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 http 400:
    {
      "message": "\"password\" length must be at least 6 characters long"
    }
  • [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 http 409:
    {
      "message": "User already registered"
    }
  • [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 ambiente JWT_SECRET, do payload da requisição e não deve conter o atributo password em sua construção.



⚠️ Validando token nas requisições

  • Após termos feito o requisito de criação de users e o requisito de login, 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 de middleware? 😜
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"
    }
  • [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"
    }

5 - Sua aplicação deve ter o endpoint GET /user

  • ☝ 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"
      },
    
      /* ... */
    ]


6 - Sua aplicação deve ter o endpoint GET /user/:id

  • ☝ 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 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 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"
    }
  • [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"
    }


7 - Crie o modelo Category em src/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.
  • 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']



8 - Sua aplicação deve ter o endpoint POST /categories

  • ☝ 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 http 400:
    {
      "message": "\"name\" is required"
    }
  • [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"
    }


9 - Sua aplicação deve ter o endpoint GET /categories

  • ☝ 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"
      },
    
      /* ... */
    ]


10 - Crie o modelo BlogPost em src/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 modelo User;

  • As propriedades podem estar em camelCase se underscored for true. Ou seja, quando os dados forem inseridos ou selecionados via model devem estar em camelCase, mas quando as queries forem pra o banco os campos das colunas devem estar em snake_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 modelo BlogPost e o modelo Category;
  • As propriedades podem estar em camelCase se underscored for true. Ou seja, quando os dados forem inseridos ou selecionados via model devem estar em camelCase, mas quando as queries forem pra o banco os campos das colunas devem estar em snake_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']



12 - Sua aplicação deve ter o endpoint POST /post

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"
    }
  • [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 todas as categorias existentes, o resultado retornado deverá ser conforme exibido abaixo, com um status http `400``:
    {
      "message": "one or more \"categoryIds\" not found"
    }
  • [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"
}


13 - Sua aplicação deve ter o endpoint GET /post

  • ☝ 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": "[email protected]",
          "image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg"
        },
        "categories": [
          {
            "id": 1,
            "name": "Inovação"
          }
        ]
      },
      
      /* ... */
    ]


14 - Sua aplicação deve ter o endpoint GET /post/:id

  • ☝ 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"
          }
      ]
    }
  • [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"
    }


15 - Sua aplicação deve ter o endpoint PUT /post/:id

  • ☝ 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 e content 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"
      }
  • [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"
    }
  • [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": "[email protected]",
        "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"
        }
      ]
    }


Requisitos Bônus

16 - Sua aplicação deve ter o endpoint DELETE /post/:id

  • ☝ Não esqueça de validar o token neste requisito, como descrito na seção de Validando token nas requisições;
  • ⚠️ Para que os testes passem é necessário que o requisito 12 esteja funcionando completamente ⚠️;
  • 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"
      }
  • [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:
  • [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"
    }


17 - Sua aplicação deve ter o endpoint DELETE /user/me

  • ☝ 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 seu token;
  • 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:


18 - Sua aplicação deve ter o endpoint GET /post/search?q=:searchTerm

  • ☝ 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:

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 http 200:
    // 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": "[email protected]",
          "image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg"
        },
        "categories": [
          {
            "id": 2,
            "name": "Escola"
          }
        ]
      }
    ]
  • [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 http 200:
      // 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": "[email protected]",
            "image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg"
          },
          "categories": [
            {
              "id": 2,
              "name": "Escola"
            }
          ]
        }
      ]
  • [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": "[email protected]",
            "image": "https://upload.wikimedia.org/wikipedia/commons/1/18/Lewis_Hamilton_2016_Malaysia_2.jpg"
          },
          "categories": [
            {
              "id": 1,
              "name": "Inovação"
            }
          ]
        },
        
        /* ... */
      ]
  • [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
    
      []

project-blogs-api's People

Contributors

mirelladourado avatar henriquebaetaleite avatar trybe-tech-ops avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.