Ephemeral Chats is a TypeScript NodeJS app made with NestJS , Apollo GraphQL, RedisOM and MikroORM.
It's a real-time web app where you can build temporary chat rooms, from 5 minutes to 24 hours, to chat with your friends, or anyone you invite into the room.
@todo: Upload Video to YouTube
In terms of databases there are two main ones:
The MongoDB database is used to store the data that needs to be persisted, mainly the Users as we need them for Auth. I chose MongoDB as I wanted to save everything as a JSON Object to go with the hackathon theme Redis, but I still wanted some assurances that the data would be persisted and any database transaction wouldn't be lost, so I chose MongoDB, a NoSQL database that since version 4 has some ACID transaction features.
Since most of the data is ephemeral, we don't need to persist it, so we use Redis and RedisJSON for the rest: Chat Rooms, Profiles and Messages.
- Users are stored in MongoDB as a JSON Object, with a unique ID and a hashed password. Everytime a User Instance is accessed its stored on Redis for 24h to boost read speeds.
- Chat Rooms are stored in Redis as a RediJSON Object with a TTL (Time To Live) of 5 minutes to 24 hours.
- Profiles are stored in Redis as a RediJSON Object with TTL equal to the Chat Room's TTL.
- Messages are stored in Redis as a RediJSON Object with a TTL equal to the Chat Room's TTL.
- Most of the data is access with Redis' Search, using indexes and queries to get the data we need.
- Single users are fetched from Redis as they'll be stored there for 24h. However, multiple users will still be fetched from MongoDB.
- When fetching multiple entities, I cursor paginate them, including when using Redis' Search.
- Docker or Podman;
- Docker-compose or Podman-compose;
- NodeJS 16 with corepack enabled.
- Clone the repo.
- Install the dependencies:
$ yarn install
- Create a .env file with all the fields equal to the example.
- Start the containers:
$ podman-compose up
- Start the app once:
$ yarn start:dev
- Copy the generated MASTER_KEY that appears in the console and paste it in the .env file.
- Start the app again:
$ yarn start:dev
- Finally go to http://locahost:4000/altair to test the API or go to http://localhost:4000/ to use the example React Frontend.
- Go to DigitalOcean, Linode or Hetzner;
- Create a server running Ubuntu LTS;
- Install dokku;
- Run the following commands on your server for dokku initial set-up:
$ cat ~/.ssh/authorized_keys | dokku ssh-keys:add admin
$ dokku domains:set-global your-global-domain.com
- Create a new app and connect git:
$ dokku apps:create ephemeral-chats
- Go to redis cloud and create a new instance with RediJSON and RediSearch;
- Add the Mongo plugin to dokku, and create a new instance of MongoDB:
$ dokku mongo:create ephemeral-chasts-db
$ dokku mongo:link ephemeral-chats-db ephemeral-chats
- Add all the configurations:
$ dokku config:set ephemeral-chats REDIS_HOST=redis ...
9On your pc clone this repo and on its folder run the following commands:
$ git remote add dokku dokku@your-global-domain.com:ephemeral-chats
$ git push dokku main:master
- Finally set up SSL and a domain for your app:
$ sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
$ dokku config:set --global DOKKU_LETSENCRYPT_EMAIL=your-email@your.domain.com
$ dokku domains:set ephemeral-chats chats.your.domain.com
$ dokku letsencrypt:enable ephemeral-chats
$ dokku letsencrypt:cron-job --add
To be easily accessible, I created a simple React front-end example that interacts with this API. I have to note that the front-end is not production ready, so it's not the best way to interact with the API, however I still made it the main url for the app.
To check the API documentation and test the API itself just go to the /altair route, it uses the Altair Graphql Client to debug and test the API.
This project is MIT licensed.