Event's aggregator app using an Express backend
This is a portfolio project showcasing Nodejs in the backend. The application is an event's aggregator for developers.
The easiest way to run this backend application is by using Docker and Docker-Compose. So, you should have both installed on you machine to run this as demonstrated below.
First, you need to clone this repository to your local machine. After done cloning, change directory into it. Next, you should start the containers using the docker-compose up
command. All the steps are shown below:
git clone https://github.com/psatler/meetapp-backend.git
cd meetapp-backend
sudo docker-compose up
PS: if you have docker added to your user group, you might not need to add sudo in front of the command.
PS2: The migrations for the PostgresQL DB is set up to be run on the container start up, so we should have the database ready after the command above finishes its start up process;
After that, you should be all set with the backend.
Tips:
- you can visualize if the postgres database is running by using a GUI interface like Postbird (you can also use a CLI for that).
- you can also refer to the available commands for the sequelize-cli here.
An user can authenticate itself in the application by using an email and password.
- Authentication using JWT ☑️
- Input validation using yup ☑️
New users can registrate themselves using name, email and password. ☑️
To update the password, the user should also send a field to confirm the password. ☑️
- Users can log in and register. The user's password is encrypted when saved in the database. ☑️
There will be a route to perform upload of files. This rout ewill register the path of the file in a database table and return all the file's information. ☑️
A user can create meetups in the application's database by using a title of meetup
, description
, locatization
, date and time
and a banner image
. All of the mentioned fields are required. Also, there is a user_id
field to store the user who organizes the meetup. ☑️
It is not possible to create meetups with dates already passed. ☑️
The user can edit all the fields of a meetup that hasn't happened yet and the user is the organizer. ☑️
Create a route to list all the meetups organized by the logged user. ☑️
The user should be able to cancel meetups organized by them and that didn't happen yet. The cancelation should delete the meetup from the database. ☑️
The user should be able to register themselves in meetups not organized by them. ☑️
The user cannot register themselves in meetups that already happened. ☑️
The user cannot register themselves twice in a same meetup. ☑️
The user cannot register themselves in two different meetups that happen in the same date and time. ☑️
Whenever a user register themselves in a meetup, an email should be sent to the organizer of the meetup having pieces of information of the registered user. An email template should be created as well. ☑️
There is a route that lists the meetups with a filter by date only (not time). The results of that list should come paginated by 10 items per page. Below is an example of a request to the route for listing the meetups: ☑️
http://localhost:3333/meetups?date=2019-07-01&page=2
In the example's above, we're listing the page 2 of the meetups that will happen in the 1st of July.
In this listing, also return the organizer's information. ☑️
There is a route to list the meetups that the logged user is registered. ☑️
Only list those meetups that haven't happened yet. Also, sort the closest meetup to happen as first ones of the list. ☑️
This application was tested along with the Insomnia REST client. Below you'll find an explanation of each endpoint this backend has and also a button to download the examples/endpoints used and load them in your insomnia app.
-
Subscription
-
post (create):
/meetup/{meetupId}/subscription
- subscribe logged in user to the meetup. -
get (list):
/subscriptions
- list the user's subscriptions.
-
-
Organizer
- get (list):
/organizer
- list the meetups organized by the logged in user.
- get (list):
-
Meetups
-
get (show - display one meetup):
/meetups/{meetupId}
- get meetup information by ID. -
get (list - index):
/meetups
- list the all meetups. It can receive query parameters as date and page, becoming/meetups?date=2020-04-22&page=1
, for example. This is better explained at the Listing the meetups subsection above. -
post (create/store):
/meetups
- create a brand new meetup. -
put (update):
/meetups/{meetupId}
- update a meetup by ID. -
delete:
/meetups/{meetupId}
- delete a meetup by ID.
-
-
Files
- post (create/store):
/files
- uploads and store the banner/avatar image file in the API. The files is sent as a Multipart Form data in the body with the property named asfile
.
- post (create/store):
-
Session
- post (create/store - it's a public route):
/session
- creates the user session returning the jwt token used for authentication in the routes. The email and password credentials are sent via json in the request body.
- post (create/store - it's a public route):
-
Users
-
post (create/store - it's a public route):
/users
- creates a brand new user. The name, email and password of the new user is sent via the body of the request as json. -
put (update):
/users
- updates the pieces of information about the logged in user. The new name, email or even avatar (avatar_id
) are sent via the body of the request via json.
-
You can load the endpoints to test with the Insomnia REST client by clicking on the button below:
Then, copy the URL and in the Insomnia app, look for the Import Data button, and choose From URL to load it to your app.
- Sucrase: It's a transpiler like babel (but faster) which allow us to use ES6 features in Nodejs, like
import
syntax instead ofrequire
. - Nodemon: it's a tool that monitors files changes in nodejs based applications, relauching the application when these changes are detected.
- ESLint: A fully pluggable tool for identifying and reporting on patterns in JavaScript
- Prettier: An opinionated code formatter
- EditorConfig: It helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs.
- PostgresQL: used for data storage
- Sequelize: An ORM (Object-relational mapping) for Nodejs
- Redis: a key-value in memory storage
- Bee-Queue: for managing the emails (as jobs) to be sent when a user subscribes to the meetup
- Nodemailer: Nodejs module for sending emails
- Nodemailer Express Handlebars: A plugin for nodemailer that uses express-handlebars view engine to generate emails.
- Multer: Node.js middleware for handling multipart/form-data (primarly used for uploading files)
- Yup: Dead simple Object schema validation
- Axios: Promise based HTTP client for the browser and node.js
- Sentry for error monitoring in production
-
This backend is using docker to isolate the services used by the application. So, a container for Nodejs, another for Redis and another one for PostgresQL (there is also one for mongoDB). To perform a dump from Postgres container named 'database', you can do:
sudo docker exec -it database pg_dumpall -c -U postgres > dump_
date +%d-%m-%Y""%H%M_%S.sql
On the other hand, to restore the database, you can run:cat your_dump.sql | docker exec -i your-db-container psql -U postgres
. More on that can be found at the following stackoverflow link. -
Used docker volumes to persist database data when shutting down the containers. For Postgres image, a volume was set up for the
PGDATA
environment variable. -
Also, to save/persist the photos uploaded, it was used volumes to map to a local folder the photos uploaded to the container. To rebuild the container image after the changes, the followind command was ran:
sudo docker-compose up --build
. You might need to delete thePGDATA
folder first do be able to rebuild the image. -
To fix files according to ESLint, for example,
js
files inside the src folder:yarn eslint --fix src --ext .js
-
To create the Run in insomnia button, you can follow the instructions found at https://support.insomnia.rest/article/68-run-button or this youtube video (in Pt-BR). In summary, paste the URL (from the Raw view) of the exported json at https://insomnia.rest/create-run-button/ so that we have a markdown snippet for the button with the exported json.
This project is licensed under the terms of the MIT License © Pablo Satler 2019