4
\$\begingroup\$

I have a personal project that runs the backend under spring boot that implements websocket for real-time functionality and I apply it to a crud operations.

Although the code is working and work as expected I doubt if I do the correct implementation of spring websocket here.

I've used React as my frontend as call the crud function on their @MessageMapping annotation.

The way I implement the backend to my frontend is.

  • Fetching all Person records and store in an array state.
  • Then for create Person record I just append in to the new record to the persons state array

I doubt if I do it correctly because when I debug the websocket client, I found out that it.

@Autowired
private SimpMessagingTemplate template;

@Autowired
public PersonController(PersonRepository personRepository) {
    this.personRepository = personRepository;
}

@MessageMapping("/person/add")
public void createPerson(Person person) {
    Person savePerson = new Person(person.getFirstName(), person.getLastName());
    personRepository.save(savePerson);
    this.template.convertAndSend("/topic/person", viewPersons());
}


@RequestMapping("/person")
@ResponseBody
public List<Person> viewPersons(){
    List<Person> persons = personRepository.findAll();
    return persons;
}

@MessageMapping("/person/delete")
public void deletePerson(@Payload PersonDeleteRequest request) {
    Person person = personRepository.findById(request.getId()).orElseThrow(() -> new RuntimeException("No id found."));
    personRepository.delete(person);
    this.template.convertAndSend("/topic/person", viewPersons());
}

@MessageMapping("/person/update")
public void updatePerson(@Payload Person requestPerson) {
    Person person = personRepository.findById(requestPerson.getId()).orElseThrow(() -> new RuntimeException("No id found."));
    person.setFirstName(requestPerson.getFirstName());
    person.setLastName(requestPerson.getLastName());
    personRepository.save(person);
    this.template.convertAndSend("/topic/person", viewPersons());
}
\$\endgroup\$
1
\$\begingroup\$

@Autowired is not required on constructor in Spring over 4.3 (class has to be annotated as bean and have only one constructor).

Inject SimpMessagingTemplate template in a constructor. Now you mix annotation and constructor injection.

IMHO you shouldn't put any business login in controller methods. I would move it all to separate service. For example I would write updatePerson() like this:

@MessageMapping("/person/update")
public void updatePerson(@Payload Person requestPerson) {
    personService.updatePerson(requestPerson);
    this.template.convertAndSend("/topic/person", personService.viewPersons());
}

In updatePerson() and createPerson() you should have separate objects instead of Person class. E.g. CreatePersonRequest and UpdatePersonRequest

I would change viewPersons() to getAllPersons()

The rest look fine :)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.