Home > Software design >  how should I use @GetMapping properly to create a /something/{id}/something/{id2} path?
how should I use @GetMapping properly to create a /something/{id}/something/{id2} path?

Time:05-26

I've been stuck to this problem for days. I'm creating a website where chefs can put their buffets, their dishes etc.

This is the code I'm using to get a chef in particular:

//cs is the chefService
@GetMapping("/chef/{id}")
   public String getChef(@PathVariable("id")Long id, Model model) {

       Chef chef = cs.findById(id);
       model.addAttribute("chef",chef);
       return "chef.html";

(It basically return a page with his buffets)

Now I dont know how to do the same thing for his buffets, precisely i dont know if i have to repeat the id part both for the chef and the buffet or just the buffet id or it's something i need to do in my thymeleaf code. Is it correct to do it this way? :

   @GetMapping("/chef/{idChef}/buffet/{idBuffet}") 
   public String getBuffetsOf(@PathVariable("idBuffet") Long id, Model model) {
       Buffet buffet = bs.findById(id);
       model.addAttribute("buffet", buffet);
       return "buffet.html";
   }

Or maybe i need to add another Long variable for the chef id? Thanks for the help

EDIT: Here are the two entities:

@Entity
public class Chef{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String nome;
    private String cognome;
    private String nazionalita;
    @OneToMany
    @JoinTable(name = "chef_buffet")
    private List<Buffet> buffets;


    public Chef(String nome, String cognome, String nazionalita, List<Buffet> buffets) {
        this.nome = nome;
        this.cognome = cognome;
        this.nazionalita = nazionalita;
        this.buffets = buffets;
    }

    public Chef() {

    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getCognome() {
        return cognome;
    }

    public void setCognome(String cognome) {
        this.cognome = cognome;
    }

    public String getNazionalita() {
        return nazionalita;
    }

    public void setNazionalita(String nazionalita) {
        this.nazionalita = nazionalita;
    }

    public List<Buffet> getBuffets() {
        return buffets;
    }

    public void setBuffets(List<Buffet> buffets) {
        this.buffets = buffets;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result   ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Chef other = (Chef) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Chef [id="   id   ", nome="   nome   ", cognome="   cognome   ", nazionalita="   nazionalita
                  ", buffets="   buffets   "]";
    }

@Entity
public class Buffet {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    private String nome;
    private String descrizione;
    private Chef chef;
    @OneToMany
    @JoinTable(name = "buffet_piatti")
    private List<Piatti> piattis;


    public Buffet(String nome, String descrizione, List<Piatti> piattis, Chef chef) {
        this.nome = nome;
        this.descrizione = descrizione;
        this.chef = chef;
        this.piattis = piattis;
    }

    public Buffet() {

    }

    public String getNome() {
        return nome;
    }


    public void setNome(String nome) {
        this.nome = nome;
    }


    public String getDescrizione() {
        return descrizione;
    }


    public void setDescrizione(String descrizione) {
        this.descrizione = descrizione;
    }


    public List<Piatti> getPiattis() {
        return piattis;
    }


    public void setPiattis(List<Piatti> piattis) {
        this.piattis = piattis;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result   ((id == null) ? 0 : id.hashCode());
        return result;
    }
    
    public Chef getChef() {
        return chef;
    }

    public void setChef(Chef chef) {
        this.chef = chef;
    }


    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Buffet other = (Buffet) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Buffet [id="   id   ", nome="   nome   ", descrizione="   descrizione   ", piattis="   piattis   "]";
    }

CodePudding user response:

Since the chef page displays buffets, it makes me believe that you have one-to-many relationship of chef to buffets. When displaying all buffets in chef page, you can build the url for each single buffet in thymeleaf. Something like:

/chef/buffet/${buffet.id}

Then your mapping for single buffet will be:

@GetMapping("/chef/buffet/{idBuffet}") 
public String getBuffet(@PathVariable("idBuffet") Long id, Model model) {
    Buffet buffet = bs.findById(id);
    model.addAttribute("buffet", buffet);
    return "buffet.html";
}

CodePudding user response:

If you need both chef id and buffet id in the method, you can map both path variables.

@GetMapping("/chef/{idChef}/buffet/{idBuffet}") 
public String getBuffetsOf(@PathVariable("idChef") Long idChef,
       @PathVariable("idBuffet") Long idBuffet, Model model) {
       //method code here
   }

CodePudding user response:

Looking at your buffets endpoint,

@GetMapping("/chef/{idChef}/buffet/{idBuffet}") 
   public String getBuffetsOf(@PathVariable("idBuffet") Long id, Model model) {
       Buffet buffet = bs.findById(id);
       model.addAttribute("buffet", buffet);
       return "buffet.html";
}

You might have missed the {idBuffet} parameter.

Correct code should be,

@GetMapping("/chef/{idChef}/buffet/{idBuffet}") 
   public String getBuffetsOf(@PathVariable("idChef") Long idChef, 
     @PathVariable("idBuffet") Long id, Model model) {
       Buffet buffet = bs.findById(id);
       model.addAttribute("buffet", buffet);
       return "buffet.html";
}

This should work.

Also, if you are not using {idChef} in your method why would you even need that? You can just create endpoint without that.

Something like,

@GetMapping("/chef/buffet/{id}") 
   public String getBuffetsOf(@PathVariable("id") Long id, Model model) {
       Buffet buffet = bs.findById(id);
       model.addAttribute("buffet", buffet);
       return "buffet.html";
}

OR

@GetMapping("/buffet/{id}")
   public String getBuffetsOf(@PathVariable("id") Long id, Model model) {
       Buffet buffet = bs.findById(id);
       model.addAttribute("buffet", buffet);
       return "buffet.html";
}

This will look a lot cleaner.

CodePudding user response:

First, you can add in buffetRepository a method which return a buffet using chef. Like,

Optional findBuffetByChef(Chef chef)

After that you can use your controller with id_buffet et id_chef. In the first time, you can find the chef and after use your method buffetService using the method in the top.

  • Related