Skip to content

Commit

Permalink
Add DTOs for data output format control
Browse files Browse the repository at this point in the history
  • Loading branch information
jultty committed Mar 9, 2024
1 parent 3968038 commit 6af7418
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 19 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,4 @@ out/
/dist/
/nbdist/
/.nb-gradle/
gradle.properties
43 changes: 41 additions & 2 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,44 @@
## 0.x.0
- Repetição espaçada

## 0.x.0
- Página de documentação para desenvolvedories
## Backlog
- Página de documentação para desenvolvedores
- [ ] Novas estruturas de dados
- [x] Course
- [ ] Result
- [ ] Revisar estrutura de dados para questões de ordenação
- [ ] Cada alternativa deve ter um valor numérico
- [ ] Cada alternativa deve ter um valor correto
- [ ] Ao receber o resultado, deve poder informar se está correto
- [ ] Adicionar estruturas de dados para contas
- [x] Adicionar lógica para gerar tokens de acesso temporários
- [ ] Somente um usuário autenticado pode enviar resultados
- [ ] Somente um usuário autenticado pode alterar suas questões
- [ ] Somente um usuário autenticado pode alterar seus conjuntos de questões
- [ ] Somente um usuário autenticado pode alterar suas turmas
- [ ] Somente um usuário autenticado pode alterar seus dados
- [ ] Adicionar etruturas de dados para níveis de acesso
- [x] Enum Access para conjuntos de questões
- [x] Novo conjunto de questões é privado por padrão
- [ ] Acesso público permite acesso a todos os grupos
- [ ] Acesso "Course" permite acesso somente ao curso associado ao conjunto
- [ ] Adicionar estruturas de dados para receber resultados
- [ ] classe Result
- [ ] Atributos:
- [ ] User
- [ ] Date
- [ ] Question
- [ ] Chosen options
- [ ] Exercícios de ordenação lidam diferentemente com este item
- [ ] Valores numéricos para cada alternativa
- [ ] Course
- [ ] Accuracy
- [ ] Conta docente
- [ ] Interface gráfica para criação de cursos
- [ ] Invalidação de tokens
- [ ] Conjunto de questões em inglês
- [ ] Conjunto de questões de lógica

- [ ] Verificar formatação de data em JSON
- Ver: <https://www.baeldung.com/jackson-serialize-dates?__s=m5n9kdgdsquuqqb9ufy2>
- [ ] `/set/demo-set-pdp` deveria retornar todos os ids de exercícios
15 changes: 15 additions & 0 deletions docs/v0.1.2/relatorio_02.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Mirante: Relatório para v0.1.2

## Tarefas
- Resolução de uma regressão de recursão infinita ao tentar implementar a lógica de autenticação

## Desenvolvimento

A implementação da versão v0.1.1 fornecia todos os dados apenas no endpoint `/option`, que retornava todas as opções existentes.

Para a versão `0.2.0` previa-se o oposto: `/option` não deveria retornar nada, e `/option/{id}` deveria retornar apenas as informações daquela opção, com seu exercício na forma simples do _id_ e não toda a estrutura do exercício.

Embora esta questão tenha sido resolvida com o uso do padrão de `DTOs`, foi introduzido um _bug_ de recursão infinita onde, ao tentar criar opções, elas tentavam referenciar o exercício a que pertenciam, que por sua vez referenciava todas as suas opções, e assim por diante.

A primeira solução encontrada relaciona-se ao uso das anotações e `@JsonManagedReference` e `@JsonBackReference`, fornecidas no pacote `com.fasterxml.jackson.annotation.JsonBackReference`, que instruem o serializador de JSON saber em qual ponta da relação ele deve colocar a listagem completa, e em qual ponta apenas o _id_.

7 changes: 6 additions & 1 deletion src/main/java/mirante/api/exercise/Exercise.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package mirante.api.exercise;

import com.fasterxml.jackson.annotation.JsonManagedReference;
import mirante.api.exercise.option.Option;
import mirante.api.exercise.set.ExerciseSet;

Expand All @@ -17,6 +18,7 @@ public class Exercise {
@Id @JsonProperty("id") private String id;
@JsonProperty("instruction") private String instruction;

@JsonManagedReference
@OneToMany @JoinColumn(name = "exercise_option")
private Set<Option> options;

Expand All @@ -36,11 +38,14 @@ public Exercise(String id, String instruction) {
}

public void addOption(Option option) {
options.add(option);
if (option.getExerciseId().equals(id)) {
options.add(option);
}
}

public String getId() { return id; }
public String getInstruction() { return instruction; }
public String getSetId() { return set.getId(); }
public Set<Option> getOptions() { return options; }
}

4 changes: 2 additions & 2 deletions src/main/java/mirante/api/exercise/ExerciseController.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ExerciseController {
}

@GetMapping("/exercise")
List<ExerciseDTO> all() {
List<ExerciseDTO> getExercises() {
List<Exercise> exercises = repository.findAll();
List<ExerciseDTO> exerciseDTOs = new ArrayList<ExerciseDTO>();

Expand All @@ -26,13 +26,13 @@ List<ExerciseDTO> all() {
dto.id = e.getId();
dto.instruction = e.getInstruction();
dto.set = e.getSetId();

exerciseDTOs.add(dto);
});

return exerciseDTOs;
}


@PostMapping("/exercise")
@ResponseStatus(HttpStatus.CREATED)
Exercise newExercise(@RequestBody Exercise newExercise) {
Expand Down
4 changes: 0 additions & 4 deletions src/main/java/mirante/api/exercise/ExerciseDTO.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package mirante.api.exercise;

import java.util.Set;
import mirante.api.exercise.option.Option;

public class ExerciseDTO {
public String id;
public String instruction;
public String set;
public Set<Option> options;
}
14 changes: 8 additions & 6 deletions src/main/java/mirante/api/exercise/option/Option.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package mirante.api.exercise.option;

import com.fasterxml.jackson.annotation.JsonBackReference;
import mirante.api.exercise.Exercise;

import jakarta.persistence.Entity;
Expand All @@ -16,16 +17,17 @@ public class Option {
@JsonProperty("place") private Integer place;
@JsonProperty("correct") private Boolean correct;

@JsonBackReference
@JsonProperty("exercise_id")
@ManyToOne @JoinColumn(name = "exercise_option", referencedColumnName = "id")
private Exercise exercise;

public Option() {}

public Option(String id, Integer place, String content, String exercise_id, Boolean correct) {
this.id = id;
this.place = place;
this.content = content;
this.correct = correct;
}
public String getId() { return id; }
public String getContent() { return content; }
public Integer getPlace() { return place; }
public Boolean getCorrect() { return correct; }
public Exercise getExercise() { return exercise; }
public String getExerciseId() { return exercise.getId(); }
}
25 changes: 21 additions & 4 deletions src/main/java/mirante/api/exercise/option/OptionController.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package mirante.api.exercise.option;

import java.util.ArrayList;
import java.util.List;

import mirante.api.exercise.option.OptionDTO;

import mirante.api.exercise.Exercise;
import mirante.api.exercise.ExerciseDTO;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException;
Expand All @@ -17,8 +22,20 @@ class OptionController {

@CrossOrigin(origins = "*")
@GetMapping("/option")
List<Option> all() {
return repository.findAll();
List<OptionDTO> all() {
List<Option> options = repository.findAll();
List<OptionDTO> optionDTOs = new ArrayList<OptionDTO>();

options.forEach(e -> {
OptionDTO dto = new OptionDTO();
dto.place = e.getPlace();
dto.content = e.getContent();
dto.correct = e.getCorrect();
dto.exercise = e.getExerciseId();
optionDTOs.add(dto);
});

return optionDTOs;
}

@PostMapping("/option")
Expand All @@ -31,8 +48,8 @@ Option newOption(@RequestBody Option newOption) {
Option one(@PathVariable String id) {
return repository.findById(id)
.orElseThrow(() -> new ResponseStatusException(
HttpStatus.NOT_FOUND, "Option with id ${id} not found")
);
HttpStatus.NOT_FOUND, "Option with id ${id} not found")
);
}

@DeleteMapping("/option/{id}")
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/mirante/api/exercise/option/OptionDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package mirante.api.exercise.option;

public class OptionDTO {
public String id;
public String content;
public Integer place;
public Boolean correct;
public String exercise;
}
11 changes: 11 additions & 0 deletions src/test/hurl/v0.1.2/A1-option-single.hurl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
POST http://localhost:8888/option
{
"id": "option-demo-pdp-0001A",
"content": "Polimorfismo",
"correct": true,
"place": 1,
"exercise_id": "demo-pdp-0001"
}

HTTP 201

0 comments on commit 6af7418

Please sign in to comment.