training-center / R2D2

Front-End da Plataforma do Mentoria
MIT License
44 stars 9 forks source link

JSON Schema da API v1 #40

Open bernardodiasc opened 7 years ago

bernardodiasc commented 7 years ago

JSON Schema API v1

Pra começar uma primeira versão, observar os dados pre-existentes e requisitos da plataforma.

Caso de uso

Eu enquanto desenvolvedor, gostaria de ter acesso às definições da estrutura de dados da API para poder avançar o projeto client em paralelo ao server e vice-versa. Além de poder validar as versões da API e gerar conteúdo fictício para desenvolvimento local.

Critério de aceitação

Cenário simples:

  1. Visitante cadastra no site;
  2. Visitante acessa o site como membro cadastrado;
  3. Membro registra uma solicitação, podendo ser tanto para ser mentor ou mentorado;
  4. Mentores existentes observam a lista de espera das solicitações e eventualmente escolhem um mentorado para mentorar;
  5. Administradores e mentores podem ver uma lista que mostra todos os registros mentorias;

Requisitos

(sujeito a alterações)

A priori foi identificado 3 entidades: pessoas, mentoria e solicitacoes, essa tarefa será aceita quando entregarmos o schema delas (e eventuais mudanças propostas).

Os dados oficiais disponíveis constam aqui:

Recursos

Notas técnicas

A tarefa para criar o wireframe pode contribuir reciprocamente com esta já que ambas requerem a definição dos dados que irão ser usados na interface https://github.com/training-center/R2D2/issues/29

bernardodiasc commented 7 years ago

Pensei numa estrutura de dados assim pra versão 1 da API:

{
  "pessoas": {
    "UID": {
      "nome": "Fulano",
      "email": "fulano@email.com",
      "conhecimentos": ["UID", "UID", "UID", "UID"],
      "contatos": {
        "LinkedIn": "",
        "GitHub": "",
        "FaceBook": "",
        "Twitter": "",
        "Site": "",
        "Youtube": ""
      },
      "termos": true
    }
  },

  "mentoria": {
    "UID": {
      "mentor": "UID",
      "mentorado": "UID",
      "inicio": "TIMESTAMP",
      "conclusao": "TIMESTAMP",
      "materias": ["UID", "UID"]
    }
  },

  "solicitacoes": 
    "UID": {
      "solicitante": "UID",
      "motivo": "ENUM",
      "registro": "TIMESTAMP",
      "materias": ["UID"],
      "nivel": "ENUM",
      "mentoria": "UID"
    }
  },

  "materias": {
    "UID": "PHP",
    "UID": "MongoDB",
    "UID": "Sass"
  }
}

Sugestões?

lflimeira commented 7 years ago

@bernardodiasc a galera começou a definir a estrutura na issue acima com base no que vc descreveu aqui, bora lá ver se podemos finalizar essas issues?

angeliski commented 7 years ago

@bernardodiasc Eu não sei o quão útil essa sugestão pode ser (nem se ela deveria ser feita aqui), mas e se considerarmos usar o Graphql? Claro que ainda tem que ser montado um schema, mas muda um pouco a abordagem.

bernardodiasc commented 7 years ago

@angeliski não tenho experiência com GraphQL pra poder te responder com certeza. Eu acho que adicionar uma camada GraphQL nesse projeto seria como comprar um caminhão pra ir comprar pão pro lanche da tarde.

Mas dei uma olhada e vou tentar esclarecer... o que estamos fazendo aqui é o Schema do JSON vanilla, é exatamente isso aqui http://json-schema.org/. O Schema do JSON é escrito em JSON. O GraphQL, assim como várias outras libs que utilizam de linguagem/syntax especificas, tem suas próprias maneira fazer as definições, no caso do GraphQL da pra entender como é aqui http://graphql.org/learn/schema/

Geralmente queremos partir direto pro código né? Mas o schema precisa vir primeiro, pois é o contrato da estrutura de dados que vamos trabalhar. Todos os devs tanto de front quanto de back vão ter isso como referencia pra poder avançar mais rapidamente sem sair quebrando tudo. Então, se houver necessidade de mudar o formato da API, isso deve ser planejado e lançado em novas versões. Novamente, o motivo disso é pro time todo evoluir melhor, é algo que é muito útil em equipe e as vezes muito difícil de ver seu valor quando estamos trabalhando solo.

angeliski commented 7 years ago

@bernardodiasc não sou experiente com GraphQL, mas vou expor o motivo da sugestão. O ponto em si não é ter uma camada a mais com ele e sim substituir o padrão rest por ele. Existem diversas vantagens, como por exemplo a evolução da api de maneira mais "facil" (tem outras que acho que não cabem ser citadas aqui, pra não extender muito, se alguém quiser podemos discutir no slack ). Eu sugeri porque achei válido cogitar, mas realmente seria necessário experiência com a tecnologia, afinal teríamos que guiar quem não conhece. Além de aumentar o ponto de entrada para novas contribuições. Em todo caso, concordo plenamente no ponto em que definir o schema permite a evolução consistente dos times. :)

bernardodiasc commented 7 years ago

To muito afim de usar GraphQL já tem um tempo, parece ser claramente superior ao REST, mas os pontos que voce colocou concordo plenamente, acho que pode não ser tão boa ideia para este projeto em particular.

nicholasess commented 7 years ago

São poucos profissionais capacitados com GraphQL, assim dificultando a manutenção do projeto. As tecnologias podem ser NodeJs + Mongodb e envio de email, o @woliveiras pode enviar email ao sendgrid e conseguir uma bolsa open source. Também será necessário um CI como Travis para os tests tanto do front, quanto o backend.

hdamaich commented 7 years ago

@bernardodiasc Cara desculpe a demora, estava olhando a API que colocou aqui e o que achas de invés de chamar de materias chamar de skills, pois esse é a nomenclatura que estamos dando na BD para essa mesma coisa.

angeliski commented 7 years ago

O primeiro schema que eu fiz é para a nosso recurso pessoa. Segue a proposta:

{
  "properties": {
    "id": {
      "description": "Codigo identificador do usuário",
      "id": "/properties/id",
      "type": "integer"
    },
    "name": {
      "description": "O nome principal do usuário",
      "id": "/properties/name",
      "type": "string"
    },
    "email": {
      "description": "O email principal do usuário",
      "id": "/properties/email",
      "type": "string"
    },
    "level": {
      "id": "/properties/level",
      "properties": {
        "id": {
          "description": "O level atual do usuário",
          "id": "/properties/level/properties/id",
          "type": "integer"
        },
        "name": {
          "description": "A descrição do level",
          "id": "/properties/level/properties/name",
          "type": "string"
        }
      },
      "type": "object"
    },
    "status": {
      "default": "ATIVO",
      "description": "O status atual do usuário",
      "id": "/properties/status",
      "type": "string"
    },
    "contacts": {
      "id": "/properties/contacts",
      "items": {
        "id": "/properties/contacts/items",
        "properties": {
          "description": {
            "description": "O contato do usuario",
            "examples": [
              "www.linkedin.com/in/fulano"
            ],
            "id": "/properties/contacts/items/properties/description",
            "type": "string"
          },
          "name": {
            "description": "O Label do contato.",
            "examples": [
              "LinkedIn",
              "GitHub",
              "FaceBook",
              "Twitter",
              "Site",
              "Youtube"
            ],
            "id": "/properties/contacts/items/properties/name",
            "type": "string"
          }
        },
        "type": "object"
      },
      "type": "array"
    }
  },
  "type": "object"
}
angeliski commented 7 years ago

Segue demais schemas: Materia

 {
   "properties": {
     "descricao": {
       "id": "/properties/descricao", 
       "type": "string"
    }, 
    "id": {
      "id": "/properties/id", 
      "type": "integer"
    }
  }, 
  "type": "object"
}

Mentoria

{
  "mentor": {
    "$ref": "#/pessoa",
    "type": "object"
  },
  "mentorado": {
    "$ref": "#/pessoa",
    "type": "object"
  },
  "inicio": "TIMESTAMP",
  "conclusao": "TIMESTAMP",
  "materias": [
    {
      "$ref": "#/pessoa",
      "type": "object"
    }
  ]
}

Solicitação

{
  "properties": {
    "data_solicitacao": {
      "id": "/properties/data_solicitacao",
      "format": "date-time",
      "type": "string"
    },
    "level": {
      "$ref": "/properties/level",
      "type": "object"
    },
    "materias": {
      "items": {
        "properties": {
          "$ref": "/properties/materia",
          "type": "object"
        },
        "type": "object"
      },
      "type": "array"
    },
    "mentoria": {
      "properties": {
        "$ref": "/properties/mentoria",
        "type": "object"
      },
      "type": "object"
    },
    "solicitante": {
      "properties": {
        "$ref": "/properties/pessoa",
        "type": "object"
      },
      "type": "object"
    },
    "ultima_atualizacao": {
      "id": "/properties/ultima_atualizacao",
      "format": "date-time",
      "type": "string"
    }
  },
  "type": "object"
}

@bernardodiasc Se tudo estiver de acordo eu monto um schema geral e gero um PR

bernardodiasc commented 7 years ago

Show @angeliski! O schema que voce montou ta legal, não sei dizer se está correto com a API que vamos ter pois não sei exatamente em que pé estamos em relação ao modelo do banco de dados e dos wireframes. Mas acho que voce pode abrir um PR com esses schemas sim, aí montamos uma suite de testes até a API ficar pronta, para então podermos fazer mais ajustes.

É tranquilo não é? Parece complicado no inicio mas não é nada mais que a definição da estrutura dos dados. :)

🚀 🚀 🚀 🚀

angeliski commented 7 years ago

Show! Eu tava meio confuso no começo, mas acho que to no caminho certo.

@lflimeira e @hdamaich, vocês acham que esse schema condiz com nosso db? Se vocês derem o OK, eu gero o schema macro no almoço, ai o dojo amanhã já consegue usar. :)

bernardodiasc commented 7 years ago

Melhor e ter 1 arquivo (json) pra cada endpoint ao invés de um schema master com tudo dentro.

angeliski commented 7 years ago

Salve @bernardodiasc ! O que precisa ser feito naqueles testes ali? Você tem alguma base pra me passar? Assim a gente já mata essa issue :)

bernardodiasc commented 7 years ago

@angeliski a ideia é validar os schemas fazendo um mock dos dados usando o #41 com Jest e https://github.com/epoberezkin/ajv. Quando a API estiver pronta o mesmo teste tem que validar o mock do schema, tem que validar o retorno da API em cada endpoint.

O que falta aqui sao só as suites de testes pra cada schema mesmo. É 1 teste só pra cada schema, valida usando o AJV, fica simplão assim var valid = ajv.validate(schema, data)

Qualquer dúvida me chama :)