Case Study for Move-X full-stack project
Overview
MoveX is a library of movements from various styles and traditions, with descriptions/cues and video sources.
It consists of a backend and two frontend clients. The backend is where the moves are stored in a database, as well as the API that allows apps to interact with the database. The frontend clients, one created with React and one with Angular provide the interface that allows user to browse the moves, view details about each move, style or source, manage their user profile and create a list of their favorite moves.
Purpose & Objective
I built this personal project in the context of a CareerFoundry course to master full-stack web development.
The goal was to create a fully functional, responsive and engaging web app to provide movers with inspiration and details about a variety of movements.
The challenge was to build an API from scratch, set up and connect a database, as well as make use of the most popular frontend JavaScript libraries/frameworks – React and Angular – to create engaging interactive user interfaces.
At the same time the project was set up to produce a great portfolio project and get used to common project requirements like user stories and user flows.
Tech Stack / Tools
MERN and MEAN stack
Backend | VS Code, NodeJS (Express, Morgan, bodyParser, mongoose, CORS, Passport, bcrypt), MongoDB, Postman, Heroku, JSDoc | GitHub |
React client | VS Code, JavaScript, React, React Redux, React Bootstrap, Parcel, PropTypes, Axios, Netlify | Live demo GitHub |
Angular client | VS Code, TypeScript, Angular, Angular-Material, GitHub-Pages, TypeDoc | Live demo GitHub |
Duration
All in all it took approximately 3 month. For sure a lot more than a project like this should take in “real life”. But since it was a study projects, there were so many things to learn and figure out. I got really absorbed in it an at the end felt ready to call myself a web developer.
Credits
Big thanks goes to my tutor Ali El Zoheiry. Without him this would have been way less instructive and fun. And of course I also thank my mentor Ramadhan Aheebwa. Thanks also to Theano Eirini Kakaziani for great feedback on this case study.
Approach
Backend
For the server side I created a RESTful API using Node.js and Express as well as a non-relational database (MongoDB). The API allows to retrieve data about the moves and users from the database through common HTTP requests and returns JSON. API and database are connected by the business logic layer, using Mongoose.
Authentication
I also implemented a login endpoint with basic HTTP authentication
returning a authorization JWT (token) to the client. This is
necessary to ensure only logged in users can access the database.
Initially the mechanisms of authentication and authorization were
quite challenging for me. But after some time and effort it became
clear and functional.
To test the endpoints I used Postman.
React client
Once the backend was set up, I created a frontend (the user interface) using React library. It is a single-page, responsive web application (SPA), built following the MVC design pattern. There are multiple views: Registration, login, main view (where all the moves are shown as cards), move view (where details about a specific move are elaborated), style view and source view (details about the style/source, as well as all the matching moves in the database) and a profile view (here the user can edit their user data and view cards for their favorite moves).
Starting with React
This was the biggest and most challenging, but also very exciting part
for me as there was a lot to learn starting off with React. Compared
to pure/classical HTML, CSS and JavaScript, it is a very different
approach to interface creation and design. There were many topics I
had to research, experiment with and figure out.
Class VS functional components
In React everything
consists of two types of components: class components (the
"traditional" way) and functional components (a modern
alternative). For the Move-X client I wrote a couple of each to
practice both. In a real-world scenario more consistency would be
advisable. In this case I would opt for mainly functional
components as I preferred to work with them and they seem more
efficient in several ways.
Redux
React-Redux added a huge level of complexity. It allows a much
more sophisticated way to share "state" (= data) between
components by storing them in a central "store". Figuring out how
that really works and how to refactor my app took me a while, but
in the end it all made a lot of sense and worked smoothly. However
in the future I would search for "updated" alternatives that allow
similar functionality with less complicated procedures.
Angular client
Later on I created another client accessing the same API and database. This time I used Angular framework. It is again a single-page, responsive web application with mostly the same functionality as the React client, just a very different technology and new layout. In this version, after registration/login, there is just one main view with a slider to display all moves. From there modals can be opened to display details about a style or source, as well as to edit the user profile.
Starting with Angular
Starting with Angular was a beast. It is a full-grown framework
(compared to React being "just" a library), which means it comes with
a lot more pre-defined structure and built-in functionality. But as
soon as I started to understand the basic structure it started to make
a lot of sense and recreating the client (with a completely different
layout) was actually quite fast.
Material design
Creating the layout, mostly following Material design, was also a
new experience. It is a complex world but in its basics also
surprisingly efficient and straight-forward. I was expecting to
get a similar user flow as in the react app, but Angulars workflow
automatically led me to create a much easier and more efficient
result.
I am clearly not an Angular expert (yet), but I got to love it for its straight forward workflow and the clear, organized structure. For small projects it would clearly be an overkill though.
Conclusion
MoveX was my first full-stack web application. Traversing from the rather abstract server code and database structures all the way to two great user interfaces was an amazing achievement.
The whole server side, with it’s security mechanisms and logic layers was quite challenging at first. But after a lot of research and some help from my tutor it all made sense.
React VS Angular
I especially found it very interesting to experience the two very
different approaches of React vs Angular and their respective
workflows.
In React I liked the flexibility of modularity and the clarity of combining layout and functionality into a component. However Redux was a bit cumbersome. But maybe it is something one needs to get used to to appreciate it.
Angular is great for its straight forward workflow and variety of great looking built-in elements. However for a small project like MoveX (in its current state) it is quite bulky and contains a lot of unnecessary features. When I continue to work with Angular I would like to dive deeper into Material design.
I couldn’t say that I like either React or Angular more than the other. They both have pros and cons and ultimately it will always depend on the scope and requirements of a specific project to choose appropriate tools.
Key takeaways
Backend
- How to set up and use NodeJS with nvm (node version manager) and npm (node package manager) to run JavaScript without a browser
- How to create API endpoints with Express and test them with Postman
- How to use middleware
- Relational and non-relational databases (usage, differences and advantages)
- Authentication and authorization (HTTP and JWT) with Passport middleware
- Data security with CORS and password hashing
- Using JSdoc for documentation
React client
- How to use Parcel built tool to convert (transpile, bundle and minify) a project from development stage to a production version
- Practical experience with React Bootstrap as a UI library for responsive styling
- Class components and functional components in React
- Using lifecycle methods and hooks to "schedule" when certain operations are executed
- Working with state and props to manage in-memory data and pass it between components
- How to work with Redux in React state management (data flow between components)
- Using different ways to store data locally (Cookies, HTML5 Web Storage, IndexedDB
Angular client
- How to work with TypeScript
- How to use Angular CLI
- Architecture of Angular Apps (component= class + template + services + metadata
- Working with Angular directives
- Data binding to coordinate the UI with the app data
- Template-driven VS reactive forms
- Routing in Angular
- Basics of Angular-Material
- Using TypeDoc for documentation
Possible further improvements
Theses are some ideas on how to further improve and develop the projects
Backend
- Currently a user who is logged in could, given he has the username of another user, edit their profile. This can be fixed by adding a check if the req.params.Username is equal to the logged in Username. But the issue is handled in the frontend.
- Data validation for the Birthday field. Currently on registration it is handled by the mongoose model (returning a string if invalid), and additionally by express-validator for the "edit user data" endpoint (return an HTML if invalid). But there is validation at the frontend as well.
React client
- Better separation of concerns by outsourcing API calls into a services file rather than inside the UI files
- Pretty modals/dialogs instead of "alert"s
- Registration view & edit profile form: Confirm password (input a second time to avoid typos)
- At registration, check if a username is already taken.
- Confirm (old) password for changing user data in ProfileView
- Confirmation dialog before account is deleted
- FloatingLabels in Forms (Seems to be a feature of react@next only…)
- A system on how new moves can be added to the database from the frontend
Angular client
- Form validation (a thorough version is implemented in the react version. The topic was neglected in the Angular version, as it is just a study project with a different focus).
- Updating user data should require a password confirmation.
- Confirmation dialog before account is deleted
- Show details about individual moves in ProfileView (favorites), StyleView and SourceView
- Mat-dialog does not seem to perfectly responsive. At least vertical scrolling did not always appear in my tests.
- A system on how new moves can be added to the database from the frontend