The backend repo which powers up mealternative. It mainly handles all actions related to authentication, recipe operation and user informations.
Project URL: https://mealternative.com/
- CRUD with mongoDB using mongoose
- custom auth implementation using jwt without using a fully managed service
- Multi user posting and interacting (likes, bookmarks etc)
- Pagination and randomise display recipe
- Sorting based on all sorts of different criteria
This project is not built for production usage, I've built this website maily to refresh my knowledge on the MERN stack. Some of the functionality implementation may not be best practice (like building a auth system myself..). However, this project does showcase how to effectively interact with mongoDB using mongoose, hopefully you could find something useful from this repo. Maybe also take a close look at the frontend repo.
To set this up locally, please follow the steps below
- Clone the repository
- Go into the directory where the package.json resides
- Install dependencies
npm install
- Create the required .env file with below environment variables in it. Note: you will need to use one of your existing mongoDB cluster or create a new cluster as well as a sendgrid API key. Freetier is more than enough for both of this. Detailed explanation here
cat << EOF > .env
PORT=8000
CLIENT_URL=http://localhost:3000
DATABASE=<Your mongodb connect url>
SENDGRID_API_KEY=<Your sendgrid API>
JWT_ACCOUNT_ACTIVATION=asfbb1onofnonodsnonono
JWT_SECRET=adsfasdfbbi1bibibjbdksmmmoo
JWT_RESET_PASSWORD=uuiuinjjbywyeyqwgvb
EMAIL_FROM=noreply@mealternative.com
EOF
- Start the server (server will be running in port 8000)
npm run dev
- Break Everything:)
You can use a local mongo setup, this part only demonstrate how to set up mongoDB atlas
- create a new project and then build a new cluster
- Select free tier and then create a cluster
- Select provider of your choice and a region close to you, leave the rest as default
Note: make sure to select M0 sandbox tier(It's free)
- Click connect
- Add your IP to the ip whitelist and create a mongo user for the cluster (remember the username and password)
- Select 'Connect your application'
- Make sure the Driver is Node.js and copy the mongoDB connection string with your new mongo user's username and password (created in step 5)
- Put the mongoDB connection string into the .env file
SendGrid is a fully managed fantastic email service, you get a huge amount of free tier usage as well
- Register a free account at SendGrid
- Leave everything as default, you do not need to configure anything
The backend uses the NPM package sendgrid provide
- Navigate to the API keys section
- Create a new API Key
- Copy the API key and put it in the .env file mentioned in Step4 of Usage
The frontend of this project is hosted on an AWS s3 bucket and distributed through CloudFront. Here is the custom cloudformation deployment template.
The backend of this project is hosted on AWS ec2 instance through elastic beanstalk. Here is the custom deployment cloudformation template.
Note: Backend template is intended to use with registered domain and a static frontend with the frontend template. If you are looking for deploying a nodejs backend without involvement of route53 on AWS, simply google mern stack AWS, there's so many different ways
This template demonstrate how to setup elasticbeanstalk through cloudformation, you could of course install elasticbeanstalk cli and use it differently
- Frontend template usage is here
- If you haven't use elasticbeanstalk before or don't have a elasticbeanstalk dedicated S3 bucket, run this command
aws elasticbeanstalk create-storage-location
- Zip up the entire code
git archive -v -o mealternative.zip --format=zip HEAD
- Upload the zip file to the s3 bucket created by step2
It is suggested to create a sub "folder" in s3 to hold each application, e.g. s3://elasticbeanstalk/mealternative/yourzip
aws s3 mv mealternative.zip s3://<Yourelasticbeanstalkbucket>/mealternative/mealternative.zip
- Download the backend template and modify all of this values
Change all of the {{resolve:ssm:/mealternative/XXX:1}} to the env variables in your .env file. If you have experience with AWS system manager, you could just go to system manager and create the appropriate the parameters in parameter store
- Namespace: aws:elasticbeanstalk:application:environment
OptionName: PORT
Value: <YourValue>
- Namespace: aws:elasticbeanstalk:application:environment
OptionName: CLIENT_URL
Value: <YourValue>
# And change all of the rest with {{resolve:ssm:/mealternative/XXX:1}} to your value
-
Register a SSL certificate through ACM in your region, rather than the us-east-1 mentioned in frontend template
Used for https connections between frontend and backend
-
Create a cloudformation stack with the modified template
- ApplicationName: Any name you prefer
- S3ZipKey: the path of your zip file in s3 elasticbeanstalk bucket (E.g. In this setup example, mealternative/mealternative.zip)
- KeyPair: an existing EC2 key pair, if you don't have one, create one in EC2 console
- SSLCertificateArn: ssl certificate arn from step 6
- HostedZoneId: the route53 hosted zone that hosts your domain name
- FrontendStack: reference the name of the frontend stack
-
Once the stack is created, your backend should be live