Is performance the only reason not to use SignalR (websockets) entirely in lieu of a traditional REST API?

softwareengineering.stackexchange https://softwareengineering.stackexchange.com/questions/262045

سؤال

I have used SignalR to achieve real-time messaging functionality in several of my projects. It seems to work reliably and is very easy to learn to use.

The temptation, at least for me, is to abandon developing a Web API service and use SignalR for everything.

I feel like this could be achieved by thoughtful design, and if it were, it would mean far less client code would be necessary. More importantly, it would mean that there would be a single interface to services rather than a split interface, and in the worst case, that one could wire this up without thinking about when things get rendered, etc.

So, I would like to know:

  1. Is there any other reason not to use SignalR in lieu of all web services besides performance?
  2. Is SignalR's performance sufficiently concerning that it would not make sense to do so?

It has long been a dream of mine to be able to translate server-side object and service definitions to client-side service access code without something silly like node.js. For instance, if I define an interesting object InterestingObject and a service to CRUD the object InterestingObjectService, I can define a standard URL route to the service - say, "/{serviceName}/{methodName}" - but I still need to write client code to access the service. Since the object is going to be passed from client to server and back, there is no practical reason to have to define the object explicitly in client-side code, nor should there be a need to explicitly define the routes to perform CRUD operations. I feel like there should be a way to standardize all of this so that it is possible to write a client under the assumption that service access works from the client to the server and back as transparently as it would if I were writing a WinForms or Java Applet or Native App or what have you.

If SignalR is good enough to use in lieu of a traditional web service, it may be a viable way to achieve this. SignalR already includes functionality to make the hub work like service I describe, so I could define a common base (CRUD) service that would offer all of this functionality out-of-the-box with some reflection. Then I could almost take for granted the service access, saving me the annoyance of re-writing code to access something that could be accessed by convention - and more importantly, the time I would have to spend writing code to define how this is updated in the DOM.

After reading my edit I feel like it may be a little nonsensical so please feel free to ask me if you have questions about what I am getting at. Basically, I want the service access to be as transparent as possible.

هل كانت مفيدة؟

المحلول

Those two technologies have a very different purpose.

  • REST is for ordinary calls to an API, with client being an active actor of the exchange. When the client needs to find GPS coordinates of an address, the client initiates the call to the API and waits until it receives the coordinates, or a error occurs, or a timeout elapses.

  • Web sockets are for everything which needs to do things the opposite way. For example, when I use an intranet website which shows me in real time the logs and the performance of different servers, the client may be passive and wait until the server sends him a newly published log message or performance metrics.

The difference is clear: in the first case, the client decides when it needs a specific piece of information; in the second case, the client simply waits to be contacted, and may not know when it would be.

In some way, both are interchangeable: you can implement web sockets when you don't need them (i.e. the client will call the server through web sockets instead of making a REST call) and you can use polling or long polling as a substitute to web sockets (given that this was used successfully for years until web sockets became so popular).

But their interchangeability comes at a cost:

  • When you use polling or long polling instead of web sockets, you're often wasting bandwidth.

  • When you use web sockets to do what can be done through web api, you keep all the connections from all the active clients opened, which may not be what you really want. For a small website where you expect to have at most 5 clients at the same time, this is not an issue. For a service such as Amazon AWS, this wouldn't be easy to solve technically.

Don't use web sockets when you don't need them. To get GPS coordinates of an address, I gain nothing in opening web sockets connection, making the call, waiting for an answer and closing the connection: REST fulfills my needs for such scenarios.

  • If you find yourself repeatedly and frequently checking for information through a REST call to a service, this may be a good sign that you should move to web sockets. Similarly, Stack Overflow reduces bandwidth usage by using web sockets, since it helps people to not spend their time pressing F5 on the home page to see if they have new messages.

  • If you find that you open web sockets connections, use them to make a single call, and then close them, or if your connections remain opened but the server is sending something to the client only on client's request, switch to REST.

Also, web sockets have still a limited support and are not always easy to implement. While SignalR makes it easy to implement, this doesn't mean that you won't have any difficulties to implement it in other languages/contexts/environments. With REST, that's easy: it may be a curl call or a similar feature available in every mainstream language. With web sockets, you can't be sure how long would it take to make a client using [insert the name of a language you don't know yet here].

I've used web sockets in several projects in .NET, Python and node.js.

  • In .NET, it wasn't too difficult, but still, I've still spent a few days trying to figure out some cryptic problems, such as the connection dropped as soon as it is opened. (This was prior to SignalR; I never tried SignalR). I also used WCF in web sockets mode, which wasn't without issues either (but I believe that WCF always comes with issues).

  • In node.js, this was doable, but I had to switch twice the libraries until I've found one which works. I believe I've spent at least a week trying to make a web sockets Hello World.

  • In Python, I tried once, spent two or three days, and abandoned. It never worked.

Compare this to REST: the only problems one can encounter with a new language/framework is to know how to POST files or receive a very large binary response. I remember spending a few hours searching for solutions for some languages. Still, a few hours for a special case is nothing compared to days or weeks for a simple Hello World.

نصائح أخرى

Just my 2 cents...

I think it's not really about performance or whatsoever. It's about standards. REST is a standard and IMHO has following advantages:

  • HTTP requests are straightforward to use. Everybody can quickly use a REST API. Heck, you can even open the browser and type an URL to see the data, how more interactive can you be?
  • (Almost) any programming language can use it. It's kind of a universal interface. Interfacing with SignalR from an exotic language seems less obvious.
  • It has nice tooling support, like http://petstore.swagger.wordnik.com/
  • It's a nice "interface" to debug. You can easily monitor incoming and outgoing messages directly in the browser, see the data, etc. With websockets and custom libraries, it's not as obvious, you have to explicitly log everything.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى softwareengineering.stackexchange
scroll top