{"id":22185677,"url":"https://github.com/thangtran3112/chatter-backend","last_synced_at":"2026-05-05T22:40:22.999Z","repository":{"id":232070305,"uuid":"776510473","full_name":"thangtran3112/chatter-backend","owner":"thangtran3112","description":"Modern NestJs BE with both REST and GraphQL, Apollo Server with PubSub, Passport Auth, MongoDB, Redis. Deployment with Cloudfront, AWS CodePipeline and EC2","archived":false,"fork":false,"pushed_at":"2024-07-26T12:58:41.000Z","size":313,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-30T00:17:40.693Z","etag":null,"topics":["apollo-server","apollographql","aws-cloudfront","mongodb-atlas","mongoose","nest-passport","nestjs","redis-pubsub"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thangtran3112.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-23T17:55:34.000Z","updated_at":"2024-07-26T12:58:45.000Z","dependencies_parsed_at":"2024-07-26T14:37:44.195Z","dependency_job_id":null,"html_url":"https://github.com/thangtran3112/chatter-backend","commit_stats":null,"previous_names":["thangtran3112/chatter-backend"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thangtran3112%2Fchatter-backend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thangtran3112%2Fchatter-backend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thangtran3112%2Fchatter-backend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thangtran3112%2Fchatter-backend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thangtran3112","download_url":"https://codeload.github.com/thangtran3112/chatter-backend/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245342052,"owners_count":20599731,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apollo-server","apollographql","aws-cloudfront","mongodb-atlas","mongoose","nest-passport","nestjs","redis-pubsub"],"created_at":"2024-12-02T10:16:51.787Z","updated_at":"2026-05-05T22:40:17.965Z","avatar_url":"https://github.com/thangtran3112.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Chatter backend with Apollo PubSub and Redis PubSub\n\n- For Production solution, i used Redis, please see the [list event-publishing system](https://www.apollographql.com/docs/apollo-server/data/subscriptions/#production-pubsub-libraries)\n- In this solution, we are using [Redis PubSub](https://github.com/davidyaha/graphql-redis-subscriptions) for AWS Production server\n- On Local server, we are still using the normal Apollo PubSub comes with NESTJS. See `pubsub.module.ts`\n- By default, Javascript objects are serialized using the JSON.stringify and JSON.parse methods. This means that not all objects - such as Date or Regexp objects - will deserialize correctly without a custom reviver, that work out of the box with the default in-memory implementation. In our case, ObjectId, Date in `MessageDocument` will need a custom reviver.\n- Notes: The data we receive from Redis PubSub will need to be deserialized to JSON format in `message.service.ts`, before the resolvers can handle it. For this we are using [custom-reviver](https://github.com/davidyaha/graphql-redis-subscriptions?tab=readme-ov-file#using-a-custom-reviver)\n\n## Install nest config and Mongo DB connection\n\nNodeJS v20X\n`npm i @nestjs/config @nestjs/mongoose mongoose`\n`npm i joi`\n\n### Installing local Mongo DB\n\n\u003chttps://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-os-x/\u003e\n\n`brew tap mongodb/brew`\n`brew update`\n`brew install mongodb-community@7.0`\n\n### Using Mongo DB\n\n- kill MongoDB process: \u003chttps://stackoverflow.com/questions/11774887/how-to-stop-mongo-db-in-one-command\u003e\n  `mkdir -p ~/data/db`\n  `chmod 777 ~/data/db`\n  `mongod --dbpath ~/data/db`\n\n  - Normally MongoDb will be started on 127.0.0.1:27017\n  - Connection string should be `mongodb://127.0.0.1:27017/chatter`\n\n  - How to use [MongoDB Model](https://mongoosejs.com/docs/api/model.html)\n  - How to use [MongoDb method](https://www.mongodb.com/docs/manual/reference/method/)\n  - [MongoDB aggregate commands](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort/)\n\n## NestJs GraphQL\n\n- Installing: `npm i @nestjs/graphql @nestjs/apollo @apollo/server graphql`\n- Playground GraphQL server, after starting backend: `http://localhost:3001/graphql`\n- Understand NestJS GraphQL:\n  \u003chttps://docs.nestjs.com/graphql/quick-start\u003e\n\n### Running MongoDB Compass to view the MongoDB\n\n\u003chttps://www.mongodb.com/try/download/compass\u003e\n\u003chttps://www.mongodb.com/docs/compass/current/query/filter/?utm_source=compass\u0026utm_medium=product\u003e\n\n### Using `migrate-mongo` package to manage DB migration\n\n`npm i migrate-mongo`\n`npm i --save-dev @types/migrate-mongo`\n\n## Install auth module with @nest/passport\n\n`nest g module auth`\n`nest g service auth`\n\n## Decoding the retrieved Authentication cookie from jwt.io\n\n## Install common practices Field Validation and annotate email and password\n\n`npm i --save class-validator class-transformer`\n[ValidationPipe](https://docs.nestjs.com/techniques/validation)\n\n## AWS Backend deployment with self-signed SSL certificate\n\n- [Using self-signed SSL certificate (not recommended in production environment)](https://www.udemy.com/course/build-a-real-time-chat-app-with-react-nestjs-graphql/learn/lecture/41850348#overview)\n\n```\nopenssl version\nopenssl genrsa 2048 \u003e privatekey.pem\nstat privatekey.pem\n```\n\n`openssl req -new -key privatekey.pem -out csr.pem`\n\n```\nCountry Name (2 letter code) [AU]:US\nState or Province Name (full name) [Some-State]:Washington\nLocality Name (eg, city) []:Seattle\nOrganization Name (eg, company) [Internet Widgits Pty Ltd]:Example Corporation\nOrganizational Unit Name (eg, section) []:Marketing\nCommon Name (e.g. server FQDN or YOUR name) []:prod.eba-cnqkbmvr.us-west-2.elasticbeanstalk.com\nEmail Address []:thangtran3112@gmail.com\n\nPlease enter the following 'extra' attributes\nto be sent with your certificate request\nA challenge password []:sometestpassword\nAn optional company name []:\n```\n\n`openssl x509 -req -days 365 -in csr.pem -signkey privatekey.pem -out public.crt`\n\n- Upload public.crt to AWS Beanstalk with [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)\n  `brew install awscli`\n  `aws --version`\n  `aws configure`\n\n```\nAWS Access Key ID [None]: ************************\nAWS Secret Access Key [None]: *************************************\nDefault region name [None]: us-west-2\nDefault output format [None]:\n```\n\n`aws iam upload-server-certificate --server-certificate-name elastic-beanstalk-x509 --certificate-body file://public.crt --private-key file://privatekey.pem`\n\n## Enable CORS on NESTJS backend\n\n- Enable CORS in `main.ts` through `app.enableCors();`\n- Enable CORS for GraphQLModule inside `app.module.ts` through `cors: true`\n\n## Backend Setting Cookie issue\n\n- By default, AWS does not allow setting cookie with different CORS origin\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthangtran3112%2Fchatter-backend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthangtran3112%2Fchatter-backend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthangtran3112%2Fchatter-backend/lists"}