POST /api/accounts/
- cria usuáriosPOST /api/login/
- faz autenticaçãoPOST /api/courses/
- cria curso (user: instrutor apenas)PUT /api/courses/registrations/
- matricula estudantes num determinado curso (user: instrutor apenas)GET /api/courses/
- lista cursos e alunos matriculados (sem autenticação)POST /api/activities/
- cria atividade do estudante (sem nota, user: estudante apenas)PUT /api/activities/
- edita atividade - atribui nota - (user: facilitador e instrutor)GET /api/activities/
- lista atividades do estudante (user: estudante)GET /api/activities/
- lista todas as atividades de todos os estudantes (user: facilitador e instrutor)GET /api/activities/<int:user_id>/
- filtra as atividades por user_id (user: facilitador e instrutor)
Esta plataforma terá 3 tipos de usuário:
Estudante Facilitador Instrutor Você deverá utilizar os campos que vêm no User padrão do Django, ou seja:
username first_name last_name email password groups user_permissions is_staff is_active is_superuser last_login date_joined Confira a documentação em: (Links para um site externo.) https://docs.djangoproject.com/pt-br/3.1/ref/contrib/auth/ (Links para um site externo.) para mais detalhes, se necessário.
Para diferenciar entre os tipos de acesso, você deverá trabalhar com os campos is_staff e is_superuser, sendo que:
Estudante - terá ambos os campos is_staff e is_superuser com o valor False Facilitador - terá os campos is_staff == True e is_superuser == False Instrutor - terá ambos os campos is_staff e is_superuser com o valor True
Para poder criar usuários de diferentes tipos, é necessário utilizar o seguinte endpoint:/api/accounts/.
Não implemente qualquer tipo de autenticação para este endpoint - ou seja, qualquer pessoa pode criar qualquer usuário.
POST /api/accounts/ - criando um estudante:
// REQUEST
{
"username": "student",
"password": "1234",
"is_superuser": false,
"is_staff": false
}
// RESPONSE STATUS -> HTTP 201
{
"id": 1,
"username": "student",
"is_superuser": false,
"is_staff": false
}
POST /api/accounts/ - criando um facilitador:
// REQUEST
{
"username": "facilitator",
"password": "1234",
"is_superuser": false,
"is_staff": true
}
// RESPONSE STATUS -> HTTP 201
{
"id": 2,
"username": "facilitator",
"is_superuser": false,
"is_staff": true
}
POST /api/accounts/ - criando um instrutor:
// REQUEST
{
"username": "instructor",
"password": "1234",
"is_superuser": true,
"is_staff": true
}
// RESPONSE STATUS -> HTTP 201
{
"id": 3,
"username": "instructor",
"is_superuser": true,
"is_staff": true
}
Caso haja a tentativa de criação de um usuário que já está cadastrado o sistema deverá responder com HTTP 409 - Conflict.
A API funcionará com autenticação baseada em token.
POST /api/login/ - fazendo login (serve para qualquer tipo de usuário):
// REQUEST
{
"username": "student",
"password": "1234"
}
// RESPONSE STATUS -> HTTP 200
{
"token": "dfd384673e9127213de6116ca33257ce4aa203cf"
}
Esse token servirá para identificar o usuário em cada request. Na grande maioria dos endpoints seguintes, será necessário colocar essa informação nos Headers. O header específico para autenticação tem o formato Authorization: Token .
Course é um model que representa um curso dentro da plataforma Kanvas. Apenas um User com acesso de instrutor (ou seja is_superuser == True) pode criar novos cursos e matricular usuários nos cursos.
Naturalmente, existe uma relação de N→ N entre Course e User. Um curso tem vários alunos. Simultaneamente, um estudante pode estar matriculado em diversos cursos.
POST /api/courses/ - criando um curso:
// REQUEST
// Header -> Authorization: Token <token-do-instrutor>
{
"name": "Javascript 101"
}
// RESPONSE STATUS -> HTTP 201
{
"id": 1,
"name": "Javascript 101",
"user_set": []
}
Se for fornecido um token de estudante ou facilitador, o sistema deverá responder da seguinte forma:
// REQUEST
// Header -> Authorization: Token <token-do-facilitador ou token-to-estudante>
{
"name": "Javascript 101"
}
// RESPONSE STATUS -> HTTP 403
{
"detail": "You do not have permission to perform this action."
}
Dica: para obter este comportamento, você precisará criar uma classe de permissões e utilizá-la adequadamente nas views. Dê uma olhada no material sobre esse assunto. 📖
PUT /api/courses/registrations/- atualizando a lista de estudantes matriculados em um curso:
// REQUEST
// Header -> Authorization: Token <token-do-instrutor>
{
"course_id": 1,
"user_ids": [1, 2, 7]
}
// RESPONSE STATUS -> HTTP 200
{
"id": 1,
"name": "Javascript 101",
"user_set": [
{
"id": 1,
"is_superuser": false,
"is_staff": false,
"username": "luiz"
},
{
"id": 7,
"is_superuser": false,
"is_staff": false,
"username": "isabela"
},
{
"id": 2,
"is_superuser": false,
"is_staff": false,
"username": "raphael"
}
]
}
Desta forma é possível matricular vários alunos simultaneamente. Da mesma maneira, é possível remover vários estudantes ao mesmo tempo ao registrar novamente a lista de alunos.
// REQUEST
// Header -> Authorization: Token <token-do-instrutor>
{
"course_id": 1,
"user_ids": [1]
}
// RESPONSE STATUS -> HTTP 200
{
"id": 1,
"name": "Javascript 101",
"user_set": [
{
"id": 1,
"is_superuser": false,
"is_staff": false,
"username": "luiz"
}
]
}
Toda requisição feita para esse endpoint deverá atualizar a lista de alunos matriculados no curso. No primeiro exemplo os alunos 1, 2 e 7 foram vinculados ao curso 1. Já na segunda requisição a lista de alunos foi atualizada, matriculando somente o aluno 1 e removendo os alunos 2 e 7 que não estavam na nova listagem.
Se for fornecido um token de estudante ou facilitador, o sistema deverá responder da seguinte forma:
// REQUEST
// Header -> Authorization: Token <token-do-facilitador ou token-to-estudante>
{
"course_id": 1,
"user_ids": [1]
}
// RESPONSE STATUS -> HTTP 403
{
"detail": "You do not have permission to perform this action."
}
- Dica: para obter este comportamento, você precisará criar uma classe de permissões e utilizá-la adequadamente nas views. Dê uma olhada no material sobre esse assunto. 📖
GET /api/courses/ - obtendo a lista de cursos e alunos: Este endpoint pode ser acessado por qualquer client (mesmo sem autenticação). A resposta do servidor deve trazer uma lista de cursos, mostrando cada aluno inscrito, no seguinte formato:
// RESPONSE STATUS -> HTTP 200
[
{
"id": 1,
"name": "Javascript 101",
"user_set": [
{
"id": 1,
"is_superuser": false,
"is_staff": false,
"username": "luiz"
}
]
},
{
"id": 2,
"name": "Python 101",
"user_set": []
}
]
Activity representa uma atividade feita por um User. Existe uma relação de 1 → N entre User e Activity. Somente um usuário do tipo estudante pode criar uma Activity porém não pode atribuir uma nota. Apenas um User com no mínimo is_staff == True pode atribuir a nota (grade) à Activity.
Dica: Para simplificar, não crie associações entre Activity e Course.
POST /api/activities/ - criando uma atividade (estudante)
Mesmo que o User do tipo estudante faça um request que tem o campo grade, a nota não deve ser registrada no momento da criação.
// REQUEST
// Header -> Authorization: Token <token-do-estudante>
{
"repo": "gitlab.com/cantina-kenzie",
"grade": 10 // Esse campo é opcional
}
// RESPONSE STATUS -> HTTP 201
// Repare que o campo grade foi ignorado
{
"id": 6,
"user_id": 7,
"repo": "gitlab.com/cantina-kenzie",
"grade": null
}
Podemos observar que nesse request o campo grade não foi passado, e a resposta do sistema foi um grade: null.
// REQUEST
// Header -> Authorization: Token <token-do-estudante>
{
"repo": "gitlab.com/cantina-kenzie",
}
// RESPONSE STATUS -> HTTP 201
// Repare que o campo grade foi ignorado
{
"id": 6,
"user_id": 7,
"repo": "gitlab.com/cantina-kenzie",
"grade": null
}
Não deve ser possível criar duas ou mais atividades com o mesmo repo, ou seja, caso tenha sido criada uma atividade com o "repo: gitlab.com/cantina-kenzie (Links para um site externo.)", ao cadastrar uma nova atividade com o "repo: gitlab.com/cantina-kenzie (Links para um site externo.)" o sistema não deverá criar uma nova atividade.
Se for fornecido um token de facilitador ou instrutor, o sistema deverá responder com HTTP 401 - Unauthorized.
PUT /api/activities/ - editando a nota de uma atividade (facilitador ou instrutor)
//REQUEST
//Header -> Authorization: Token <token-do-facilitador ou instrutor>
{
"id": 6,
"grade": 10
}
//RESPONSE STATUS -> HTTP 201
{
"id": 6,
"user_id": 7,
"repo": "gitlab.com/cantina-kenzie",
"grade": 10
}
Se for fornecido um token de estudante o sistema deverá responder com HTTP 401 - Unauthorized.
Caso seja informado o id de uma atividade inválido o sistema deverá responder com HTTP 404 - Not Found.
Além disso, um User do tipo estudante pode apenas visualizar uma lista com as suas próprias atividades. Já os usuários do tipo instrutor e facilitador podem visualizar todas as atividades de todos os estudantes e filtrar as atividades por usuários.
GET /api/activities/ - listando atividades (estudante)
//REQUEST
//Header -> Authorization: Token <token-do-estudante>
[
{
"id": 1,
"user_id": 1,
"repo": "github.com/luiz/cantina",
"grade": null
},
{
"id": 6,
"user_id": 1,
"repo": "github.com/hanoi",
"grade": null
},
{
"id": 15,
"user_id": 1,
"repo": "github.com/foodlabs",
"grade": null
},
]
Reparem que todas as atividades têm o mesmo user_id.
GET /api/activities/ - listando atividades (facilitador ou instrutor)
//REQUEST
//Header -> Authorization: Token <token-do-facilitador ou token-do-instrutor>
[
{
"id": 1,
"user_id": 1,
"repo": "github.com/luiz/cantina",
"grade": null
},
{
"id": 6,
"user_id": 1,
"repo": "github.com/hanoi",
"grade": null
},
{
"id": 10,
"user_id": 2,
"repo": "github.com/foodlabs",
"grade": null
},
{
"id": 35,
"user_id": 3,
"repo": "github.com/kanvas",
"grade": null
},
]
Reparem que agora listamos atividades com user_id diferentes.
GET /api/activities/int:user_id/ - filtrando atividades fornecendo um user_id opcional (facilitador ou instrutor) Como os instrutores e facilitadores podem ver as atividades de todos os alunos, precisamos dar a eles a opção de filtrar esses dados através do user_id. Se o id enviado for 1, o retorno deve ser a lista de todas as atividades do usuário (estudante) que possui user_id = 1.
//REQUEST (/api/activities/1/)
//Header -> Authorization: Token <token-do-facilitador ou token-do-instrutor>
[
{
"id": 1,
"user_id": 1,
"repo": "github.com/luiz/cantina",
"grade": null
},
{
"id": 6,
"user_id": 1,
"repo": "github.com/hanoi",
"grade": null
},
{
"id": 15,
"user_id": 1,
"repo": "github.com/foodlabs",
"grade": null
},
]
Caso o user_id enviado seja inválido, você deverá retornar um status HTTP 404 NOT FOUND.
//REQUEST (/api/activities/x/)
//Header -> Authorization: Token <token-do-facilitador ou instrutor>
// RESPONSE STATUS -> HTTP 404 NOT FOUND
{
"detail": "Invalid user_id."
}