REST API with active push notifications from server to client
Asked Answered
L

4

32

Problem description

i am working on a Xamarin application that consumes a REST API written in Python flask.

The Xamarin application offers virtual shopping lists where user can collaborate on buying stuff they have on a shared list.

To improve the user experience, i want to be able to actively notify the user about finished items on the list.

Possible solutions:

Synchronous API polling from client side

Notifications are stored by the API in a relational database and have a flag indicating if the user received the notification already.

The API has an endpoint GET /users/:user_id/notifications/ that queries the database for notifications and returns a JSON response with those.

Advantages

  • fairly simple to implement

Problems

  • synchronous polling creates a huge amount of http requests

  • API service remains stateless, making a horizontal scaling with a loadbalancer easier

Websocket endpoint on the API

The API has an endpoint POST /users/:user_id/notifications/register which creates a websocket connection between client and API.

The connection is stored to a global array in which each entry maps a client id to a websocket connection.

When a new notification is created, the endpoint makes a lookup in the connection dictionary by comparing the owner id of the notification with the dictionary entries. The notification is sent to appropriate user through the websocket.

Notifications are stored in the database like in the first approach.

When a user calls the endpoint, a new websocket connection will be established first and upon success the API sends all unseen notifications from the database to the user.

Advantages

  • API can push notifications to clients asynchronously

Problems

  • When a user terminates the websocket connection his dictionary entry will persis
  • Retaining one websocket connection per user permanently adds additional overhead to the API
  • Horizontal scalability of the API is more difficult because the service is not stateless anymore (Websocket connection information saved in

RabbitMQ

The API uses a RabbitMQ service to send notifications to the client. Every client uses subscribes to his own notification queue to prevent the broadcasting of messages.

Advantages

  • API remains stateless

Problems

  • Notifications needs to be resend to the exchange when a user is offline

  • Amount of queues grows drastically

  • Additional costs for RabbitMQ service

  • High temporary load on the RabbitMQ service when many users come online in the same time

Final words

It would be interesting to hear the opinion of others.

I believe the active distribution of notifications from backen services to clients i a very common use case.

best, D

Leilani answered 16/1, 2019 at 19:49 Comment(4)
This is a interesting question. I am creating my own REST Service with different clients using Delphi. I need a solution for receiving data changes. I am thinking about a polling client system or a separat socket service. I want hold everything in my own hands.Nectarous
Just thinking... I need a REST solution with server push, too. Could it work to use HTTP/2 and its server push capabilities somehow?Sipes
Firebase has a push notification thing: firebase.google.com/docs/cloud-messagingFranconian
This is an architectural problem solved by the pub/sub design approach. Using an array for all connections is not the best implementation approach. Using an external pub/sub (Redis / RabbitMQ) is usually faster than implementing your own (but not always).Garofalo
R
3

I would use RabbitMQ and consume events forwarding them as push notifications. This will work while the user is not actively connected to the website and enhance the engagement with each user experience that will return to the website when notified for more information see How to setup basic web push notification functionality using a Flask backend or How to send push notifications to a browser in ASP.NET Core or Sending Notifications with Spring Boot, Angular, and Firebase Cloud Messaging this way the RabbitMQ will not wait until the user is back online. If the user is online you can forward the notification directly to the Xamarin application via WebSockets and a load balancer like NGINX that can handle many WebSockets in an optimized way. Synchronous API polling from the client-side is the less preferred way since it overloads the webserver with requests while nothing was changed.

Roentgenotherapy answered 23/10, 2021 at 22:40 Comment(0)
O
1

I don't think the scalability of WebSocket is a problem. You can scale up easily with pub/sub. The hotspot of long connections is a kind of serious problem.

For one-way communication, I would suggest Server sent event. In the end, it usually depends on what your team is confident with.

Ought answered 2/8, 2021 at 7:49 Comment(0)
R
0

i would go with installing mqtt broker on the same server as the web api and use mqtt pub sub client on the server side app and client side app for receiveing (and sending) mqtt messages.

Reinsure answered 16/4, 2023 at 16:53 Comment(0)
D
-1

I can recommend on a different approach for API that provides JSON which is called GraphQL

It supports subscriptions capabilities that are pushed by the GraphQL API Server (using web sockets)
GraphQL is considered today to be better than RESTful API since its very flexible and you can get exactly the data you need with one query.

Decane answered 29/7, 2020 at 20:10 Comment(2)
"GraphQL is considered today to be better than RESTful API" - maybe by facebook :)Sclerometer
Still GraphQL is a valid alternative and after using it I am also convonced that it is more convinient then other choicesJae

© 2022 - 2025 — McMap. All rights reserved.