Search code examples
djangoredisdjango-rest-frameworkdjango-redisdjango-notification

Django redis for notifications


I have build a REST API with Django REST framework. In the app there is a need for facebook-type notifications ( new friend request, new message etc. ). Currently I'm handling this using long-polling:

  • front client sends GET request
  • my REST view searches for new objects and returns them instantly if there are any, else its searching for 20 seconds and returns empty response if there are None
  • a new GET request is sent instant after the response is received ( from the front client )

NOTE: we are not using websockets, if needed please write me

I want to replace this method with django/redis since I think my long-polling method is abusing the DB a lot and I think Redis with its speed and structure can help a lot.

Are there any suggestions on how would I accomplish something like this?


Solution

  • Using a memory based key-value store, is much better suited for your current use case, since it will hugely decrease load on your database and speed up your application.

    Redis, is more than an in memory key-value store, so you can utilize it to achieve your goal easier.

    I'm writing a simple implementation of what you want down here, you can most probably build on this to achieve what you want.

    In Short

    1. We keep all notifications of a user in a HashMap in redis with the key of the HashMap being named after the user.

    2. HashMap is a mapping of notificationId to notificationData (In Json format).

    3. Metadata of the notification is kept inside the notification data body. (Things like date, read status, ...)

      from redis import StrictRedis
      import json
      
      # Function to add new notifications for user
      def add_notification(user_id, notification_id, data):
          r = StrictRedis(host='localhost', port=6379)
          r.hset('%s_notifications' % user_id, notification_id, json.dumps(data))
      
      # Function to set the notification as read, your Frontend looks at the "read" key in 
      # Notification's data to determine how to show the notification
      def set_notification_as_read(user_id, notification_id):
          r = StrictRedis(host='localhost', port=6379)
          data = json.loads(r.hget('%s_notifications' % user_id, notification_id))
          data['read'] = True
          add_notification(user_id, notification_id, data)
      
      # Gets all notifications for a user, you can sort them based on a key like "date" in Frontend
      def get_notifications(user_id):
          r = StrictRedis(host='localhost', port=6379)
          return r.hgetall('%s_notifications' % user_id)
      

    You can also build more functionality or play around with different capabilities of redis to create a near-realtime notification backend for you website/application. (I've duplicated the redis connection creation part, user_id and ... so as the answer can be clearer)

    Cheers