45

(I'm not familiar to RESTFul, please correct me if my concept is wrong)

In RESTFul architecture, we map every action to an URL. If I click "post a article", may it's actually URL http://example.com/ and some data action=post&content=blahblah.

If I want to post, but not refresh the whole web page, I can use javascript's XMLHTTPRequest. I post it and then get it's content and insert it to a div in my page. These action is all asynchronous.

Then I know there is something named WebSocket and it's wrapper socket.io. It use "message" to communicate between client and server. When I click "post" the client just call socket.send(data) and wait for server's client.send(data). It's magical. But how about URL?

It's possible to use the two model both without repeating myself? In other word, every action has it's URL, and some of them can interact with user real-timely(by socket.io?)

Moreover, should I do this? In a very interactive web program(ex. games), the RESTFul is still meaningful?

Lai Yu-Hsuan
  • 27,509
  • 28
  • 97
  • 164
  • When you post to a restful URL, you're posting to something like `http://example.com/product/create`, then when the "post" is complete, your web service will return some form of JSON or XML to tell whether or not the post was successful. I really don't think you need to use sockets as you're describing. – Chase Florell Jun 14 '11 at 05:26
  • In this example you're right. I added the edit. What I want to do is like a interactive white board(people can post and draw and so on). I think socket.io is a good idea. In this case, is it meaningful to add RESTFul-API? If yes, how can I do? – Lai Yu-Hsuan Jun 14 '11 at 05:31
  • 1
    @rockinthesixstring You mean your sending a `POST` request to `/products/` – Raynos Jun 14 '11 at 06:42
  • 2
    `socket.send(data)` is missing a lot of the picture. To make the data transfer useful, you still need routing. Just with JSON instead of urls. `socket.send({ post:'product/create', . . . })` – generalhenry Jun 14 '11 at 07:05

2 Answers2

42

You're defining a handler for actions that map to REST over http. POST and GET generally refer to update and query over an entity. There's absolutely no reason you can't just define a handler for generic versions of these CRUD operations that can be used in both contexts. The way I generally do this is by introducing the concept of a 'route' to the real-time transport, and mapping those back to the same CRUD handlers.

You have a session, you can impose the same ACL, etc.

 +---------------------------------+
 |                                 |
 |      BROWSER                    |
 |                                 |
 +--+--^-------------------+---^---+
    |  |                   |   |
    |  |                   |   |
 +--v--+---+            +--v---+---+
 |         |            |          |
 | HTTP    |            | SOCKET.IO|
 +--+---^--+            +--+---^---+
    |   |                  |   |
 +--v---+------------------v---+---+
 |                                 |
 |        ROUTING/PUBSUB           |
 +-+--^-------+--^-------+--^------+
   |  |       |  |       |  |
 +-v--+--+  +-v--+--+  +-v--+-+
 |       |  |       |  |      |
 | USERS |  | ITEMS |  |ETC   |
 +-------+  +-------+  +------+
     ENTITY CRUD HANDLERS
Josh
  • 12,602
  • 2
  • 41
  • 47
  • I have a question based on your reply. On my side I have a public server and an API one. I listen to you and put the socket io server on the public server. But now, when I make a call to the API directly from the client (ajax), the API have no access to socket to broadcast this information.. And it's more difficult to handle with mobile apps.. Where is the best way to put the socket io server ? on public or api ? and why ? – Arthur Dec 02 '15 at 22:06
  • What's special about the public server, since the API one is public as well? It seems complicated to have two different servers with that division. Load balancing between identical servers may be a better choice for scalability. If you must have that division, you need some bi-directional communication between your servers so that they have the same state. – jswetzen Jan 02 '16 at 14:48
41

I posted this on my blog recently:

Designing a CRUD API for WebSockets

When building Weld, we are using both REST and WebSockets (Socket.io). Three observations on WebSockets:

  1. Since WebSockets are so free-form, you can name events how you want but it will eventually be impossible to debug.
  2. WebSockets don’t have the request/response form of HTTP so sometimes it can be difficult to tell where an event is coming from, or going to.
  3. It would be nice if the WebSockets could fit into the existing MVC structure in the app, preferably using the same controllers as the REST API.

My solution:

  • I have two routing files on my server: routes-rest.js and routes-sockets.js
  • My events look like this example: "AppServer/user/create".
  • I use forward slashes (“/”) to make the events look like routing paths.
  • The first string is the target (~”host name” if this actually was a path).
  • The second string is the model.
  • The third string is the CRUD verb: i.e. create, read, update, delete.
Tom Söderlund
  • 4,743
  • 4
  • 45
  • 67