How to change the result of requesting a Rest API with Spring?

Asked

Viewed 46 times

1

Eai guys, all right? I started studying Spring recently on my own and am trying to create a Rest API for enrolling students and exams at a school.

I have the following problem:

When I make a GET request to list all students enrolled in the bank, returns a giant json like this:

localhost:8080/api/students

[{
    "id" : 1,
    "nome" : "Carlos Eduardo Ribeiro",
    "media" : 0.0,
    "provas" : [{
        "id" : 1,
        "nota" : 0.0,
        "aluno" : {
            "id" : 1,
            "nome": "Carlos Eduardo Ribeiro",
            "media" : 0.0,
            "provas" : [{
                "id" : 1,
                "nota" : 0.0,
                "aluno" : {
                    "id" : 1,
                    "nome" : "Carlos Eduardo Ribeiro",
                    "media": 0.0,
                    "provas": [{
                        "id" : 1,
                        "nota" : 0.0,
                        "aluno" : {
                            "id" : 1,
                            "nome":"Carlos Eduardo Ribeiro",
                            "media":0.0,
                            "provas": [{
                                ......
                                    ......
                                        ......

Here are the models:
Java student.

@Entity(name = "aluno")
public class Aluno {

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false, length = 50)
    private String nome;

    @Column(nullable = false)
    private Float media;

    // Um aluno contem uma lista de Provas:
    @OneToMany(mappedBy = "aluno")
    private List<Prova> provas;

    // Construtor
    public Aluno() {
        this.setMedia(0.0f);
    }

    // Getters | Setters
    
}

Java tasting.

@Entity
public class Prova {

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private Float nota;

    @ManyToOne
    @JoinColumn(name = "id_aluno")
    private Aluno aluno;

    @OneToMany(mappedBy = "prova")
    private List<Questao> questoes;


    // Contrutor:
    public Prova() {
        this.setNota(0.0f); // define a nota padrão
    }

    // Getters | Setters
    
}

Here is the Controller: Alunocontroller.java

@RestController
public class AlunoController {

    @Autowired
    private AlunosRepository repository;

    // Faz uma consulta pelo id do aluno:
    @GetMapping(path = "/api/aluno/{id}")
    public ResponseEntity consultar(@PathVariable(name = "id") Integer id) {
        // Faz e retorna a consulta:
        return this.repository.findById(id)
                .map(record -> ResponseEntity.ok().body(record))    // Monta e retorna o ResponseBody com o registro
                .orElse(ResponseEntity.notFound().build());         // Caso contrário retorna um notFound
    }

    // Cadastra um novo aluno:
    @PostMapping(path = "/api/aluno/cadastrar")
    public Aluno cadastrar(@RequestBody Aluno aluno) {
        return this.repository.save(aluno); // Cadastra o aluno recebido no RequestBody e retorna
    }

    // Retorna todos os alunos cadastrados:
    @GetMapping(path = "/api/alunos")
    public List<Aluno> consultarAlunos() {
        return this.repository.findAll();
    }

}

I tried to make:

I tried to change the query method Students() to go through the records with a foreach and go assigning null to the student object of the Test entity and it worked, however, I do not want the result return the "student" within each test in the list.
The method was like this:

@GetMapping(path = "/api/alunos")
public @ResponseBody ResponseEntity<Aluno> consultarAlunos() {

    List<Aluno> alunos = new ArrayList<>(); // Cria uma lista para receber o resultado da request
    List<Prova> provas = new ArrayList<>(); // Array list para armazenas as provas sem o objeto aluno.

    // Percorre a lista de alunos:
    for ( Aluno aluno : this.repository.findAll() ) {

        // percorre a lista de provas do aluno:
        for( Prova prova : aluno.getProvas() ) {
            prova.setAluno(null);   // O objeto aluno não precisa ser especificado mais de uma vez.
            provas.add(prova);
        }

        aluno.setProvas(provas);
        alunos.add(aluno);

    }

    return new ResponseEntity(alunos, HttpStatus.OK);   // Cria e retorna os resultados.
}
outworking:

localhost:8080/api/students

[{
    "id" : 1,
"nome" : "Carlos Eduardo Ribeiro",
        "media" : 0.0,
    "provas" : [
        {
            "id" : 1,
            "nota" : 0.0,
            "aluno" : null,
            "questoes" : []
        }
    ]
}]

How do I get a result similar to the above, however in place of the "student" : null I get the id related to proof? Thank you.

  • A suggestion would be in the method query Lunos use as return a DTO and customize the return information as needed and in the future until adding a pagination in this method as well. Here is a legal explanation of DTO: https://medium.com/@msealvial/shielding-its-api-spring-boot-with-the-standard%C3%A3o-dto-44f97020d1a0

  • Thanks for the tip, I’m already in the DTO classes. Regarding the above problem, I solved it by adding a @Jsonignore in the student property of the Proof entity.

1 answer

0


Problem solved by adding @JsonIgnore on the property aluno of the entity Prova. The code went something like this:

@ManyToOne
@JsonIgnore
@JoinColumn(name = "id_aluno")
private Aluno aluno;

The result was:

[
    {
        "id": 1,
        "nome": "Carlos Eduardo Ribeiro",
        "media": 0.0,
        "provas": [
            {
                "id": 1,
                "nota": 0.0
            },
            {
                "id": 2,
                "nota": 0.0
            }
        ]
    }
]

Browser other questions tagged

You are not signed in. Login or sign up in order to post.