4
frogstair
14d

Should I use a websocket or api on my single page application?

Comments
  • 0
    what's the use case
  • 0
    @linus-torvald admin dashboard sorta thing
  • 2
    @frogstair if it needs information in realtime, yes.
  • 1
    @nitwhiz what about instead of creating lots of api endpoints I just do websocket and rpc?
  • 1
    You consider writing it as grpc over http2 ?
  • 0
    @vane im using an existing ws implementation from gorilla and a regular ol websocket from js for frontend
  • 1
    @frogstair
    pros for rest:
    - free ack, validation and error responses,
    - easy binary data
    - easy pagination
    - lots of examples
    cons:
    - no push
    - hard to keep consistent state using multiple calls

    pros for websocket:
    - easy to track state of application and client connection status
    - push messages
    cons:
    - you need to implement ack, error messages, pagination

    if you have only single page and not much data go for websocket, otherwise consider making rest calls, keep those calls data in one place and update it over websocket

    pretty much that’s why graphql is gaining popularity, cause you have subscriptions and graph structures out of the box

    binary always over rest
  • 2
    @frogstair that's a weak point. You will still have to build handlers for messages received via the WS. So it doesn't really matter whether you register them as rest endpoints or message handlers.

    If you mostly poll for stuff and you'd benefit from an event-driven data push to the client- that's a different story and is a good place for a ws to set its roots in.

    Ftr ws is a bit harder to test
  • 1
    I would wait with using websockets before you really need em.

    If you're just gonna display some data I would start off by doing a super simple api server and a client with a simple api fetch on pageload.

    Start with that, get it done, then move on to the next step.

    I've worked a lot with ServiceWorkers, Websockets, etc.
    Most of the time when I start off a project by being too fancy and planning ahead for things like live updates - there are more recurring bugs and they are harder to debug, the development is slower - and sometimes I end up realising I didn't really need it.

    Whenever I start off with the most basic thing I always get quite far in a very short amount of time, and it's easy to refactor into something more fancy later on.
  • 0
    http2 and api is plenty good
  • 0
    @jiraTicket this. I know jack shit about web sockets, grpc and that sort of stuff but I 100% agree with starting simple. The best projects I have are the ones I started out as simple as possible, all others turned out over-engineered and a nightmare to develop, so I just stopped working on them.
  • 0
    websockets is good for Bidirectional communication, example, when server wants to send data without client asking for it. If it's an app which continuosly get updates from server, then WS should be good, else, API endpoint is much cleaner and easier to implement.
  • 1
    Good luck scaling websockets beyond a small application.
  • 1
    @junon what challenges do you have in mind?
  • 1
    @netikras Unless you're using them for stateless data (most cases I've seen use them in startups break this rule...) then session re-establishment after a connection reset is a nightmare and a half to determine where to pickup from.

    Further, when backend nodes fail, or a rebalance happens, or new resources are brought online, or anything of the sort, the balancer can't immediately migrate sessions to other modes because of TCP sessions and connection renegotiation. At least, not with any out of the box tool I've seen, and orchestrating session transfers atomically across nodes sounds like a nightmare akin to Google's live migration magic.

    They take up considerably more traffic on mobile over a longer period of time with all of the underlying keepalive noise along with the application's heartbeat on top, especially in cases where you use e.g. socket.io (that might have changed in the last year's but I doubt it).

    (1/n)
  • 1
    Also, for mobile users on e.g. a train, their phones will be constantly reconnecting. Broken routes on a connection with a low keepalive rate (more than a few seconds) means that the user might be lagging behind several seconds before realizing their connection had dropped and thus will get sporadic reconnects and questionable availability because there's no mechanism to magically detect a route has broken because they've moved from one provider's tower to another (changing their WAN address, for example - which is why the long-time rule of never trusting an IP being the same or never doing session stickiness per IP was made).

    With request-response, even though you eat the cost of the TCP connection negotiation, the response is expected in a more timely manner and the entire operation can be concluded when a response is received without any guessing or waiting.

    (2/n)
  • 1
    Since responses are expected in a timely manner, keepalive rates can be much more frequent in order to make sure the underlying connection hasn't been broken during that time. Therefore, broken routes can be detected much quicker without the long-term cost of bandwidth by checking if a relatively unused websocket route is still alive.

    This has the added benefit of simpler retry logic, too. If the HTTP request (or RPC or whatever you're using) failed due to a socket error, assume the entire request failed and try again. As long as your API can handle such retries (e.g. via idempotency or by detecting broken connections and reverting a transaction) then there's very rarely a situation where the operation will permanently fail or that you can get into a corrupt state.

    (3/x)
  • 1
    With websockets, a failure is unclear unless you're checking the write confirmation for each message you send (hint: most cases I've seen tend to do this improperly!)

    If the connection fails and you've sent a message without having yet received a confirmation, then it's not trivial what the retry logic is. A client and server thus have to either keep a stateful cursor of which events the client has seen, or negotiate some client-based cursor, etc. in order to know when to replay.

    Of course most of this isn't an issue if you're using websockets as best-effort, non-essential event updates. But I've seen websockets used as a means of API communication in places where they really "meant" request/response (RPC)-like application logic, and the whole thing comes crumbling down at the first sign of load or a node hiccups in availability.

    Just don't do it if you're not sure. Stick to HTTP. Nginx is amazing, NLBs are amazing, you'll be just fine.

    (4/4)
  • 1
    Sorry if any was unclear, I'm just waking up ._.
  • 2
    @junon Thank you. Saving your comments as a note for future reference

    things_to_consider_about_websockets.txt

    :)
  • 1
    If experiment, try we sockets, otherwise api.
    API also subdivides into normal http api, and graphql.
    Again, if experiment, try graphql, otherwise normal http api.
Add Comment