Help Making a Design Choice, AJAX vs. Websocket

I need to setup communication between VueJS & Elixir Modules. I’m told my options are AJAX & Websocket.

The app will be standalone right now, with all the Elixir processing done locally. But I foresee it will grow into an umbrella Phoenix project, with some processing done remotely.

Primary consideration is latency.

Second consideration is learning time & code complexity.

Third consideration is documentation & available tutorials/learning resources (as I’ll be teaching myself).

I’m learning as I go. Currently I do not know either. I would rather only have to learn 1.

With that in mind, would you choose Websocket or AJAX to pass variables between Elixir & VueJS?

5 Likes

If you’re learning I would recommend AJAX. There should be a lot more tutorials/resources on APIs using that than websockets.

What do you mean when you say standalone and locally by the way? Is this not going through the internet?

2 Likes

Currently, the app doesn’t require the internet. Future modules will access the net, making request/responses. So if I have to learn Websockets for that eventually, maybe best to just start with that? And use Websockets to pass variables? Or is it worth it to learn them both & use the right tool for the job, whichever it might be?

Phoenix really shines because of its websockets, not using them would be strange IMHO

1 Like

i’d still recommend AJAX. probably no external API you are going to use will be a websocket one.

but it sounds a little strange to me. how vuejs on your website communicates to your phoenix application doesn’t really have anything to do with “modules accessing the net”, so i’m a bit confused. are you not going to run the phoenix application on some server? the phoenix app and the web browser will be on the same host always?

2 Likes

The Phoenix app will run locally. The app will eventually make requests/responses to remote websites & APIs. But all processing for now, is planned to be done locally.

Eventually I can see it grow to an app that some processing is handed off to a node network. So, my primary question is should I architect it right now for that possibility? And if that’s the case is Websockets the better tool to use?

for requests to external websites and apis websockets won’t be the right tool.

for your vue app to communicate with your phoenix app, they might. using ajax with a json api will give you a lot more tutorials and best practises, though, as this is the much more common/older way of doing things.

what kind of app are you building? the case would be different for a chat app, for example. ajax has to be initiated from your vue app, which means it has to ask for new data. with websockets, the phoenix app can more easily tell your vue app that there is new data, i.e. a chat message.

I’d say it depends on the kind of information you want to send back and forth.

Neither Websockets nor AJAX are complex in their basic usage. The main difference between the two is that a websocket connection is a persistent client<->server connection, where (therefore) both sides can at any time initiate a new request to the other, whereas AJAX involves setting up (and afterwards closing again) a new connection that works client->server. This means that with AJAX, only the client can initiate contact.

If therefore your application works with data that the server creates/receives and should then send to the client quickly, then websockets are definitely better. The AJAX alternative to handle this would be short-polling or long-polling, which are basically ‘hacks’ that allow you to ‘fake’ bidirectional communication because your client will keep on asking the server the ‘do you have something new yet?’ question until the server responds with something new.

Both because AJAX involves setting up/tearing down a connection each time, as well as requiring techniques like longpolling to handle bidirectional traffic, AJAX is (significantly!) slower than using websockets.

Still, depending on what your application does exactly, having a delay of a few seconds before a new message arrives because long-polling is used might not be noticeable.

However, Phoenix (and its JS clientside websockets-wrapper) abstracts the difficulties of how websockets internally work, so I definitely would advise using them for your application.

6 Likes

@Qqwy: Good answer! I want to write something similar in my words …

Basically AJAX is good when you are only fetching data from server like using JSON REST API (for example for CMS front page).

WebSocket is required for example if you want to create fast client-server chat application.

Another good example for both Elixir and Phoenix WebSocket is update graph. Simply Elixir could have a process in background that sends event through Websocket, so after data is changed client gets info about it as soon as possible. Here I also recommend new Registry Elixir API that is awesome in combination with Phoenix WebSocket connection. I found a good example for PubSub with WebSocket using this API.

1 Like

I actually tackled the same problem as you and came to the conclusion that websockets are the best.

  1. It’s a vue app that I am in control of - no compatibility issues since it’s going to be used within the org.
  2. Vue2 got rid of $http in favor of using external libraries - this made me decide to use phoenix sockets, since either way I’m going to have to use an external library
  3. Vuex abstracts away the actual API calls - if I end up hating websockets, I can exchange the calls in my vuex actions to make AJAX calls instead
  4. sockets are vogue and hip

I implore you to check out vuex, which is just as palatable as vue. Basically what I did is in Application.vue, I set up the socket and registered the events I wanted to listen for. For the receive event, I called a vuex action that would set the state.

The websockets seemed more approachable as someone who didn’t have experience with Vue or Elixir/Phoenix.

If I get a chance, I’ll post my implementation so maybe you can get some ideas from it.

1 Like

Websockets. AJAX requires setting up and tearing down the connections on every request. Long polling can mitigate latency in ‘receiving’ a bit, but websocket is the only way to minimize latency all the time in both directions.

Phoenix Channels (it’s implementation of websockets) are so simple to use, ask if you have any questions. :slight_smile:

SImplicity of use is simplicity of documentation too. :slight_smile:

And for note, AJAX is just normal http requests using the normal http ways including all the expensive setup and all, but it can be done in a single line of javascript where channels take a couple of easy lines. If you know how to build normal web requests, you already know AJAX then, except you return JSON instead of HTML. ^.^

This.

If it is for real-time communication where latency is important then websockets blow AJAX away. And I’ve seen a few API’s use websockets via tokens without issue, usually not worth it in most languages to set up unless the real-time need is necessary, though with Elixir it is so easy to websocket there is no reason not to anyway.

If they are rare polling requests then external API’s will not. However external API’s mandate whatever they mandate, that has nothing to do what-so-ever with using websockets for their own front-end.

OhgodNo, jsonapi needs to die, if you are going to vote for that then go for GraphQL then. Speaking of, you can use GraphQL over websockets too.

Exactly what @Qqwy said! ^.^

And what @Eiji said!

5 Likes

i never said jsonapi, i said “a json api” as in an api that communicates in json.

i still believe ajax with json might be a good choice for op, as they seem to be learning. read up on best practices about building a rest api and connecting that to a frontend and you pretty much have a step by step guide.

if you want to build the websocket / channels integration, you need to invent a lot yourself. the tools are all there, but best practices not so much, i think.

technically, you are all correct. websockets / channels will outperform ajax. i was looking more at the learning and documentation side.

1 Like

Ah I see most people reference actual JSON API, sorry for the quick reaction. ^.^

In that case yeah, a simple JSON interface, or GraphQL (which returns json) would be great.

Hmmm such as? Take GraphQL over websockets, there are libraries out that simplify that trivially. Or just make the raw channel calls, which is simple json.

Thanks for all the input.

If I go down the Websocket route, is there any disadvantage to using the Sockets.io abstraction of Websockets for the VueJS side? Or am I just adding complexity? (I know nothing about either currently.)

Technically you would be using a Phoenix channel, which only uses web sockets if they are available, so you would want to stick with the Phoenix API - at least that is my understanding.

…On the Phoenix side… but I still needs something on the VueJS side, I believe??

I’ve never used nor even heard of Sockets.io, so I could not say. ^.^
The Phoenix stock javascript is dead simple to use though. :slight_smile:

Just make the calls via any normal way you would in vuejs, you could even sprinkle it around in the components directly (though putting them in another class and wrapping them lets you easily change it in the future, like to GraphQL over phoenix websockets or something). :slight_smile:

Ok, when you are using “WebSockets” - but when you are using Phoenix channels (which by default use a WebSocket) you should use phoenix.js, socket.js. (Joining Channels)

The Phoenix socket abstraction is by default backed by a WebSocket - and you get a channel from the Phoenix socket.

The default transport mechanism is via WebSockets which will fall back to LongPolling if WebSockets are not available.

.

Phoenix holds a single connection to the server and multiplexes your channel sockets over that one connection.

2 Likes

Such as “Which channel do I join”?, “What message do I send to ask for a list of data?”, “What message do I send to ask for a specific resource?”, “What message do I send to create/update a resource?”, “How do I handle validation-/authorization-/other kinds of errors?” With a basic REST API, all of that is pretty clear. You can even have phoenix generate the basics for you. With channels I’m not aware of any established best practices for that, which I think is a big, big disadvantage WHEN LEARNING.

GraphQL is really cool, I’m using it myself. However, if you’re learning Phoenix and Vue, adding GraphQL will add another new thing you need to learn. And making it work with websockets/channels is yet another non-standard thing. There’s Absinthe.Plug, but I don’t know of an out of the box solution for GraphQL over channels.

1 Like

There’s Absinthe.Plug, but I don’t know of an out of the box solution for GraphQL over channels.

I think graphql subscriptions (graphql over websocket) will be available in absinthe sometime soon [0][1]. Not sure if they are intended to complement or replace phoenix channels, though.

[0] https://github.com/absinthe-graphql/absinthe/issues/156
[1] https://github.com/absinthe-graphql/absinthe/pull/322