Case Study: FLIXIT

by
FlixIt Main Page
M. Mastroianni, S. Sandrelli. Divorzio all'Italiana (1961). Source: Wikipedia

Introduction

Overview

FlixIt is a web application that provides information about movies from the Golden Age of Italian Cinema (1960-1980). Users can register, login, edit their profile, search movies, and create a list of favourites.

The purpose of the project was to give visibility to a curated selection of Italian Classics that are often overlooked and underrepresented on the web and almost forgotten by the younger generations. FlixIt may serve as a valuable platform for students, movie enthusiasts, and admirers of Italian culture to rediscover and appreciate these gems from the past.

The source code is available on GitHub: the frontend and the backend

Tech Stack

Backend:

  • Node.js
  • Express
  • Passoport
  • Mongoose
  • MongoDb

Frontend:

  • TypeScript
  • React
  • React Bootstrap
  • React Router
  • React Redux

Objective

This project is part of the CareerFoundry full-stack development course. The aim is to design, create and deploy a full-stack application using the latest technologies.

Duration

The duration of this project was approximately 2 months: 1 month for the backend, 1 month for the frontend.

A Full-Stack Application

A full-stack application consists of two parts: the frontend and the backend. The frontend is the interface through which users interact while the backend handles the frontend requests, including user authentication, data validation, database connection, and data management.

The Frontend

React

React is a powerful JavaScript library developed by Meta for creating dynamic web applications. Unlike a traditional static website, a web application can produce HTML content dynamically at request time, which allows for personalised experiences for each user.

React Components

To understand how React works, let’s examine our Flixit main page from Figure 1.

FlixIt Main Page
Figure 1. Flixit main page

We can identify several visual elements, such as movie cards displaying movie information, two buttons under the movie titles and a search box in the top-left corner.

React enables us to build complex web applications by organising them into multiple components. These components can be further broken down into smaller components, making them easier to code, test, manage, and reuse.

A React component visual appearance may vary according to its data. For example, the favourite button may display a white star or with a black star (Figure 2).

FlixIt favorite button
Figure 2. Favourite button

The button appearance is determined by a special state variable called favourite. If the movie is among the user’s favourites, favourite is set to “true” and a black star icon is displayed on the button. Otherwise, the star will be white. Here is a code snippet from the StarButton component:

              
  <Button>
    {favourite ? <StarFill className="bi" /> : <Star className="bi"/>}
  </Button>
              
            

Let’s now examine the MovieCard component, which is responsible for rendering a movie card like the one in Figure 3. Inside the MovieCard component, a state variable called movie contains information about the movie poster and title, determining the appearance of the card. Two nested components, StarButton and InfoButton, are included at the bottom of the card.

FlixIt movie card
Figure 3. Movie Card

React Redux

As we already mentioned, the state variable favourite controls the appearance of the StarButton component. But how is this variable set? How do the component know if the movie on the card is a user’s favourite?

To solve the problem, the component needs access to the user’s list of favourites, which is stored in the variable user. This data is retrieved from the backend by the LoginView component when a user logs in. In React, data is typically passed from a parent component to a child component through parameters called props. In this case, however, passing the variable user from the LoginView component to the MovieCard and StarButton components can be cumbersome and error-prone, due to the length of traversal path (Figure 4).

FlixIt components diagram
Figure 4. Components Diagram

To address this issue, we can leverage React Redux. Redux is a state management technology that simplifies access to global variables for React components. With React Redux, variables are saved in a centralised store, which can be easily accessed from any component (Figure 5).

FlixIt redux diagram
Figure 5. Redux Diagram

When a user logs in, the LoginView component saves the variable user in the Redux store and redirects to the main page. Before rendering, each MovieCard component accesses the variable user, checks if the movie is a favourite and passes the result to the StarButton. The StarButton updates its state accordingly. If this value is true, a black star icon will be displayed on the button.

Backend

The data flow

In the previous section, we discussed how data may affect the frontend appearance. Now let’s examine where the data is stored and how it flows through the different parts of the application (Figure 6).

Here is a simple scenario: after a user logs in, a collection of movie cards appear on the screen. How does this process occur?

FlixIt data flow
Figure 6. Data flow

The frontend doesn’t hold any user or movie data. Instead, data is stored in a MongoDb Atlas cloud database, which is connected to a Node.js/Express backend. To access the data, the frontend sends a HTTP request to one of the backend’s API endpoints. In our scenario, to retrieve the list of all movies, the frontend sends a GET request to the following endpoint:

              
  https://<flixit-api-domain>/movies
              
            

If the request is authorised*, the backend retrieves the data from a MongoDb Atlas cloud database and includes it in the response body in JSON format. Here is an example of a JSON object containing information about a movie.

              
  {
    "title": "A Fistful of Dollars",
    "director": {
      "name": "Sergio Leone",
      "born": "1929-01-03",
      "died": "1989-04-30",
      "bio": "..."
    },
    "stars": [
      {
        "name": "Clint Eastwood",
        "born": "1930-05-31",
        "bio": "..."
      },
      {
        ...
      }
    ],
    "genre": {
      "name": "Spaghetti Western",
      "description": "..."
    }
    "year": "1964",
    "posterUrl": "...",
    "photoUrl": "..."
    ...
  }              
            
          

The frontend is now able to render the page. Each movie data is assigned to a MovieCard component which displays the relevant information. The final result is visible in Figure 1.

* The request must provide a valid security token and its origin should be allowed

Conclusions

Retrospective

Building a web application with the MERN stack (MongoDb, Express, React, Nodejs) was made relatively easy due to the abundance of libraries, resources and online documentation available.

The project presented some challenges that were overcome through valuable learning experiences. In particular:

  • Managing dependencies and finding the right combination of tools and libraries to ensure compatibility and functionality required thorough investigation and problem-solving skills. Although this aspect may not be the most thrilling, it is an essential skill for web development.
  • As the number of React components grows, maintaining a clear application flow becomes increasingly challenging. To mitigate this, organising files and folders, and categorising components based on their function proved crucial. Maintaining a tidy and structured codebase prepares the application for scalability.

Further improvements

While FlixIt currently stands as a full-fledged web application, its functionalities remain relatively basic. Here are a few ideas to enhance the user experience further:

  • Introduce Director and Genre Views to provide information about directors and genres.
  • Include a “Where to watch” section in movie details, linking online platforms for buying, renting, or streaming the movie.
  • Provide external resource links such as articles or blog posts.
  • Expand and enrich the movie selection in the database.

About this case study

The case study aimed to provide a comprehensive understanding of the Flixit app, catering to individuals with varying technical knowledge. While we have covered only a portion of the app's functionalities for the sake of simplicity, it is worth highlighting some key aspects for further discussion:

  • User Authentication leverages Passport, a powerful authentication middleware, to ensure secure user registration, login, and session management.
  • The backend effectively manages database connection and data modelling using Mongoose, a solution that simplifies data management for Node.js and MongoDb.
  • The app utilises React Router for page navigation and routing.
  • Component styling is made easier and more consistent through the use of React Bootstrap.

For more information, please refer to the GitHub repositories: the backend and the frontend.