Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mix spring-data-rest with spring websocket into a single implementation

I'd like to synchronize the state to all the clients interested in particular entity changes. So I'd like to achieve something like:

  • exposing CRUD API on entity (via HTTP/REST and websockets)
  • and routing the response (of the modifying calls) to websockets topic

So technically, I'd be interested in ideas to mix spring-data-rest with spring websockets implementation to achieve something like spring-data-websocket.

There are a two solutions coming to my mind, and in fact both would be:

  • spring-data-rest to expose my entities via REST/HTTP API
  • websocket controllers (used for the modification calls on entities)

The websocket controllers would look like this:

@Controller public class EntityAWebSocketController {       @MessageMapping("/EntityA/update")       @SendTo("/topic/EntityA/update")       public EntityA update(EntityA entityA) throws Exception {            // persist,....            return entityA;      } } 

Scenario 1: Websocket API called from REST/HTTP API

Rules:

  • client request is always REST/HTTP API
  • response is REST/HTTP API for all the operations
  • moreover for modifying operations the websocket message comes as well

Technically, could be achieved, by:

  • calling the websocket controllers from the spring-rest-data events (namely in the AfterCreateEvent, AfterSaveEvent, AfterLinkSaveEvent, AfterDeleteEvent)

Still the solution seems quite sick to me, as I'd need to go for:

  1. client A --HTTP request--> Server (spring-data-rest controller)
  2. Server (AfterXXXEvent in the spring-data-rest controller) --websocket message--> Spring websocket controller
  3. Spring websocket controller --websocket message via topic--> all Clients interested in the topic
  4. Server (spring-data-rest controller) --HTTP response--> client A

Scenario 2: Websocket API independent from REST API

Rules:

  • client request is REST/HTTP API for non-modifying operations only
  • response is REST/HTTP API for non-modifying operations only
  • client sends websocket message for all the modifying operations
  • websocket message is sent to client for all the modifying operations only

Well, if no other ideas come up, I'd go for the later one, but still, it would be great if I could have somehow generated C(R)UD methods exposed via websockets as well, something like spring-data-websockets and handle only the routes in my implementation.

As I feel like I'd have to manually expose (via *WebSocketControllers) all the CUD methods for all my entities. And I might be too lazy for that.

Ideas?

like image 210
Peter Butkovic Avatar asked Jan 22 '14 08:01

Peter Butkovic


People also ask

Can I use WebSocket with REST API?

REST requires a stateless protocol according to the statelessness constraint, websockets is a stateful protocol, so it is not possible.

How does Spring boot connect to WebSockets?

In order to tell Spring to forward client requests to the endpoint , we need to register the handler. Start the application- Go to http://localhost:8080 Click on start new chat it opens the WebSocket connection. Type text in the textbox and click send. On clicking end chat, the WebSocket connection will be closed.

Can you upgrade only to WebSocket Spring boot?

If you hit the link with your browser, you will probably get an error Can "Upgrade" only to "WebSocket" . This is because browsers not open WebSockets by default, this needs a proper client. Since we not yet implemented a real client it is hard to verify our implementation.


1 Answers

Scenario 2 talks about, in the last step, a single client.But I thought your requirement was for a topic since you wanted multiple clients. If I wanted to complete 2 for your stated requirement, then you might want to maintain a list of clients and implement your own queue or use a ForkJoinPool to message all your clients listening in on your WebSockets. Having said that, A topic is definitely more elegant here but overall looks too complicated with different interfaces

For all messages from client to server, just go with a simple wire protocol and use a collection to parameterize, it could be RParam1.......

At the server, you need a controller to map these to different requests(and operations). Somehow does not look like too much work. Hope this helps.

like image 182
Wile E K Avatar answered Oct 01 '22 09:10

Wile E K