Mixology App helps you curate your favorite drinks, research recipes, submit ratings, compose tasting notes and more. The app has architectural elements in place (e.g. Mongoose, Redux-Toolkit, React-Router, JSON Web Token) to help developers scale up its functionality easily. It uses third party data provided by TheCocktailDB API and the Youtube Data API.
Feel free to use or modify the codebase for your own project!
This demo utilizes the "MERN stack" which makes it possible to quickly build and easily maintain a full-stack web app, and consists of the following technologies:
- MongoDB: A document-based open source database.
- Express: A web application framework for Node.js.
- React: A JavaScript front-end library for building user interfaces.
- Node.js: JavaScript run-time environment that executes JavaScript code outside of a browser (such as a server).
src
api
- This folder holds files used by the API clientassets
- This folder holds assets such as imagescomponents
- This folder holds different components that will make up our viewsconfig
- This folder holds app configuration filescontrollers
- This folder holds controller functions used by Express.jsdb
- This folder holds database models and connection fileshooks
- This folder holds React hooks for use in functional componentslayout
- This folder holds components used for page layoutmiddleware
- This folder holds middleware used by Express.jspages
- This folder holds components organized by page level viewrouters
- This folder holds routers used by Express.jsstore
- This folder holds files used to connect to the Redux store and call actionsstyles
- This folder holds stylesheets used by the frontendutils
- This folder holds utility functionsApp.tsx
- Renders all of our browser routes and different viewscustom.d.ts
- Custom type declarations for third party packagesindex.html
- Our index.html fileindex.tsx
- Entrypoint for React appserver.ts
- Entrypoint for Node.js apptypes.ts
- Custom type declarationsvalidation.ts
- Used for form validation
.babelrc
- Configuration file for Babel.js.env.sample
- Sample file containing environment variables used by dotenv.js.gitignore
- Directories to exclude from git tracking.prettierrc.cjs
- Configuration file for Prettier.jspackage.json
- Defines npm behaviors and packagespackage-lock.json
- Tracks dependency treeseedDrinks.js
- Script for seeding drink documents in MongoDBseedDrinkVideos.js
- Script for seeding drink documents' video data in MongoDBtsconfig.json
- Configuration file for TypeScriptwebpack.common.js
- Webpack configuration file for common settingswebpack.development.js
- Webpack configuration file for development mode settingswebpack.production.js
- Webpack configuration file for production mode settingsREADME.md
- This file!
Mixology App was built using Node version 16. Please install a long-term support (LTS) version for best compatibility with other libraries.
- Node.js https://nodejs.org/en/download/
To verify that you have Node.js installed on your system, type the following command in your command line terminal (Terminal for Mac/Linux, CMD for Windows).
node -v
Before you build or run the app, create two new files called .env.development
and .env.production
at the project root. These are configuration files that will be used by dotenv.js to expose environment variables to your app at runtime.
In each file, you need to enter values for the following environment variables (refer to .env.sample
for example values):
PORT
: Port where the app will run
MONGO_HOST
: Name of the Mongo host (e.g. localhost
in development mode)
MONGO_PORT
: Mongo port (e.g. 27017
)
MONGO_DB
: Name of the Mongo database used
MONGO_PASS
: Mongo password (optional)
API_URL
: Base URL for API calls to the Node app (e.g. http://localhost:3000/api
in development mode)
THECOCKTAILDB_API_URL
: Base URL for The CocktailDB API
YOUTUBE_API_URL
: Base URL for Youtube Data API
YOUTUBE_API_KEY
: Key used for Youtube Data API calls. You need to create a free Google Developers account in order to generate this key.
JWT_SECRET_KEY
: Private key used by JSON Web Token (JWT)
JWT_EXPIRATION
: JWT token expiration (in seconds)
JWT_REFRESH_EXPIRATION
: JWT refresh token expiration (in seconds)
Mixology App works best with a local installation of MongoDB (v4.4.6), but can be used with MongoDB instances located elsewhere.
First set up a local installation of Mongo using instructions corresponding to your operating system.
Once those steps have been completed, and your MongoDB instance is up and running (typically using the command mongod
), you need to create a new database to store Mixology App data. This can be done in several ways, but most commonly with the Mongo shell CLI which comes pre-installed with MongoDB. You can start the Mongo shell from the command line using the mongo
command, then create a new Mongo database (e.g. mixologyapp_db
).
Now verify that the app can connect to your new database by starting the app in development mode.
NOTE: Make sure you've created an .env.development
and .env.production
file at the project root with the required environment variables before starting the app! See Environment Variables above.
- First install application dependencies using
npm install
. Once that is complete, start the app in development mode withnpm run dev
.
Once the workflow is complete, the following messages will appear in the terminal:
Successfully connected to MongoDB
added "user" to roles collection
added "moderator" to roles collection
added "admin" to roles collection
Verify the newly created documents in the roles
collection by inspecting your database using the Mongo shell CLI or another database management tool (e.g. Robot 3T).
Next you need to seed your database using the scripts seedDrinks.js
and seedDrinkVideos.js
. Make sure to run these scripts in order (First seedDrinks.js
then seedDrinkVideos.js
).
- Seed drink documents by running
node seedDrinks.js
This script connects to your Mongo database, makes API calls to The CocktailDB for drink data, and updates the drinks
collection in the database. Once the workflow is complete, the following messages will appear in the terminal:
Connected correctly to server
Database seeded!
- Seed drink videos data by running
node seedDrinkVideos.js
This script connects to your Mongo instance, makes API calls to the Youtube Data API for video data corresponding to documents in your drinks
collection, and updates those documents with the returned API data. If the script runs successfully, you should see a success message in the terminal.
Drink videos updated successfully!
Now you can verify the new documents in the drinks
collection of your database.
Note: Depending on your access policy, the Youtube Data API may limit the number and frequency of calls it will accept from a given client. You can set or remove this limit by updating the line .limit(20)
in seedDrinkVideos.js
. Depending on the result, you may need to run the script multiple times in order to seed every drink in your database.
To run the app in development mode, run the command npm run dev
. This triggers a Webpack workflow which lints the source code, applies formatting changes based on Prettier.js settings, builds the server.cjs
file, and serves up the frontend via in-memory assets using Webpack Dev Server. Once the workflow is complete, you should be able to see the server running in the terminal. If started correctly, the following message will appear in the terminal, Server started at http://localhost:3001
. Then try visiting http://localhost:8080
in your browser to access the frontend.
Note: Hot module reloading is turned on by default in development mode. To turn HMR off, remove hot: true
from the client
config in webpack.development.js
.
To build a production-ready bundle of the app, run the command npm run build
.
This triggers a webpack workflow which bundles the source code and static assets using Webpack and emits the results into the build
folder. Once you've verified the bundled files have been created, run npm run pm2
to start the app as a background process using the process management tool PM2. You can use any process manager of your choice, but PM2 generally works well with Node environments.
Mixology App uses JSON Web Token (JWT) for managing authentication. JWT is a popular choice for authentication in Node.js apps for several reasons:
- Fewer database queries
- Less development time
- Easier to scale up with userbase
- Better portability across services
Since the backend of the app acts as both issuer and verifier of JWT tokens, it only needs one private key for authentication purposes. This is the key designated as JWT_SECRET_KEY
in your .env.*
files.
Important: Never share sensitive information such as keys or passwords! Make sure to apply appropriate security settings to prevent exposing your files.
Each user document in your database includes a roles
field which can take on one of three values: user
, moderator
or admin
. These values aren't currently used for authorization purposes, but can be used to build out an authorization layer on top of the authentication workflow if desired.
The frontend is a single-page React app that supports client-side routing via React-Router. This enables fast navigation between views and reduces the amount of network calls initiated by the frontend.
Note: To support single-page apps in production, you may need to update the configuration of the web server used to serve your app (e.g Nginx).
Client data is stored using Redux which promotes data consistency, reduces database calls, and allows the use of Redux Devtools for development.
Redux data is also persisted to your browser's localStorage
(in the object located at localStorage.state
) for access between browser sessions. If at any point the app displays data which appears out of sync, try clearing your browser's localStorage and reloading the page.