The text is from a programming tutorial focused on building a backend application with Node.js and related technologies. It guides the learner through creating server endpoints, handling HTTP requests (GET, POST, PUT, DELETE), and managing authentication. The tutorial covers setting up a database (SQLite and PostgreSQL), using an ORM (Prisma), and containerizing the application with Docker. Emphasis is put on building a full-stack application, managing user data, and securing endpoints using middleware and JSON Web Tokens (JWT). The process begins with a simple server and scales up to a production-ready application. Specific tasks include creating REST APIs, interacting with databases, and deploying the application in isolated environments.
Back-End Server Study Guide
Quiz
Answer each question in 2-3 sentences.
- What is a callback function in the context of the listen function for a server?
- Why is it important to kill the execution of the server during development?
- Explain the purpose of npm run dev in the context of the source material.
- What is a developer dependency, and how is it installed using npm?
- What is the significance of “localhost:8383” (or a similar address) in server development?
- Explain the difference between HTTP verbs (e.g., GET, POST, PUT, DELETE) and routes/paths in server requests.
- Explain the difference between the “require” syntax and “import” syntax used for adding a javascript package.
- What is an environment variable and why is it useful in server configuration?
- What is an ORM and why is it useful?
- What is a Docker container and what is it used for?
Quiz Answer Key
- A callback function is a function passed as an argument to another function (in this case, listen), to be executed after the first function has completed its operation. In the context of the server’s listen function, the callback is executed once the server is up and running, usually to log a message indicating that the server has started.
- Killing the server execution during development is important to reflect changes made to the server files. Without restarting the server, the changes won’t be implemented, and debugging becomes difficult.
- npm run dev is a command defined in the package.json file to start the server using a script, often involving tools like Nodemon. This automates the server startup process and can include additional commands beyond just running the server file.
- A developer dependency is a package needed only during development, not in production. It is installed using npm install –save-dev <package_name>, which adds the package to the devDependencies section of package.json.
- “localhost:8383” is the address (URL) used to access the server running on the local machine. localhost refers to the local machine’s IP address, and 8383 specifies the port number the server is listening on for incoming requests.
- HTTP verbs define the action the client wants to perform (e.g., GET to retrieve data, POST to send data to create a resource, PUT to update a resource, DELETE to remove a resource). Routes/paths are the specific locations (URLs) on the server where these actions are directed (e.g., /, /dashboard, /api/items).
- The “require” syntax is the older syntax for adding a javascript package, where you could write, const express = require(‘express’). The import syntax is more modern and you can write import express from ‘express’.
- An environment variable is a key-value pair stored outside the application code, often in an .env file or system settings, used to configure the application’s behavior. They’re useful for storing sensitive information (like API keys or database passwords) and for configuring different environments (development, production).
- An ORM is an Object Relational Mapper, a tool that allows developers to interact with a database using an object-oriented paradigm. It simplifies database interactions by mapping database tables to objects, reducing the need to write raw SQL queries.
- A Docker container is a lightweight, standalone, executable package that includes everything needed to run a piece of software, including the code, runtime, system tools, system libraries, and settings. It ensures consistency and portability across different environments.
Essay Questions
- Discuss the evolution of server setup throughout the source material. Compare and contrast using node server.js, using npm scripts, and using Nodemon. What are the advantages and disadvantages of each approach?
- Explain the role and implementation of middleware in the context of authenticating users for specific routes (e.g., to-do routes). How does the middleware intercept and process incoming requests, and what actions does it take based on the request’s authentication status?
- Describe the process of setting up and interacting with a database using SQL queries. Explain the purpose of each table, the columns within each table, and the relationships between the tables.
- Explain the process of containerization with Docker. Be sure to discuss Dockerfiles and Docker Compose, and describe the benefits of using Docker containers for application development and deployment.
- Discuss the importance of security in back-end development as illustrated in the source material. Describe the techniques used to protect user passwords and to authorize users to access certain data.
Glossary of Key Terms
- Port: A virtual communication endpoint on a device that allows different applications or services to send and receive data over a network.
- Callback Function: A function passed as an argument to another function, to be executed after the first function has completed its operation.
- npm (Node Package Manager): A package manager for Node.js that allows developers to easily install, manage, and share JavaScript packages and libraries.
- Script (package.json): A set of commands defined in the package.json file that can be executed using npm run <script_name>.
- Developer Dependency: A package required only during development, not in production, and specified using the –save-dev flag during installation.
- Localhost: The standard hostname given to the address of the local computer.
- URL (Uniform Resource Locator): A reference to a web resource that specifies its location on a computer network and a mechanism for retrieving it.
- IP Address: A numerical label assigned to each device connected to a computer network that uses the Internet Protocol for communication.
- HTTP Verb: A method used to indicate the desired action to be performed on a resource (e.g., GET, POST, PUT, DELETE).
- Route/Path: A specific location (URL) on the server that corresponds to a particular resource or function.
- Endpoint: A specific URL on the server that represents a particular function or resource, and that listens for incoming network requests.
- REST (Representational State Transfer): An architectural style for designing networked applications, based on transferring representations of resources.
- API (Application Programming Interface): A set of rules and specifications that software programs can follow to communicate with each other.
- JSON (JavaScript Object Notation): A lightweight data-interchange format that is easy for humans to read and write, and easy for machines to parse and generate.
- Environment Variable: A variable whose value is set outside the application code, often in an .env file or system settings, used to configure the application’s behavior.
- Middleware: Functions that intercept and process incoming requests before they reach the final route handler.
- bcrypt: A password-hashing function that is used to securely store passwords.
- JWT (JSON Web Token): A compact, URL-safe means of representing claims to be transferred between two parties.
- ORM (Object-Relational Mapping): A technique that lets you query and manipulate data from a database using an object-oriented paradigm.
- Docker Container: A lightweight, standalone, executable package that includes everything needed to run a piece of software, including the code, runtime, system tools, system libraries, and settings.
- Docker file: A text document that contains all the commands a user could call on the command line to assemble an image.
- Docker Compose: A tool for defining and running multi-container Docker applications.
- SQL (Structured Query Language): A standard language for accessing and manipulating databases.
Backend Development: Node, Express, PostgreSQL, and Docker
Okay, here’s a detailed briefing document summarizing the main themes and important ideas from the provided source.
Briefing Document: Backend Development Concepts and Project Setup
Overview:
This document summarizes key concepts and steps involved in setting up and developing a backend application, using Node.js, Express, and transitioning from SQLite to PostgreSQL with Prisma. It covers topics such as server initialization, routing, middleware, database management, authentication, and containerization using Docker. The main focus is on creating a to-do list application with authentication and data persistence.
Key Themes and Ideas:
- Server Initialization and Basic Routing (Chapter 2 & 3):
- The initial setup involves creating a Node.js server using Express.js to listen for incoming network requests on a specified port.
- A simple server can be created with minimal code:
- const port = 8383;
- app.listen(port, () => {
- console.log(`Server has started on Port ${port}`);
- });
- The use of npm scripts (defined in package.json) to manage server startup and development processes.
- Use of nodemon to automatically restart the server upon file changes during development, improving the development workflow.
- npm install nodemon –save-dev
- Adjust the scripts in package.json to use nodemon server.js
- Handling HTTP Requests and Responses:
- Servers need to be configured to interpret incoming requests, including HTTP verbs (GET, POST, PUT, DELETE) and routes/paths (e.g., /, /dashboard).
- The server uses a callback function for each route to handle the request and send an appropriate response.
- A 404 error indicates that the server could not find a route that matches the requested URL.
- The server can send back files, such as index.html, to serve a website to the client.
- Project Structure and Modularization:
- Organizing the project into folders like routes, middleware, public, and src for better code management and separation of concerns.
- The public folder contains static assets (CSS, HTML, JavaScript) that are served to the client.
- The routes folder contains separate files for handling different types of routes (e.g., API routes, website routes).
- Using middleware for handling authentication and other request processing tasks.
- Modular Syntax and Package Management:
- Adopting the newer JavaScript import syntax (import Express from ‘express’) instead of the older require syntax.
- Configuring the package.json file with type: “module” to enable the new syntax.
- Database Management (Chapter 3):
- Using SQLite as a simple SQL database for storing user data and to-do items.
- Creating database tables (e.g., users, to-dos) with specific columns and data types using SQL commands.
- SQL databases use “tables” like sheets for managing different data.
- Example: CREATE TABLE users (id INTEGER, username TEXT UNIQUE, password TEXT)
- The primary key is used to enable communication between tables (e.g., associating a to-do item with a user).
- Using database.execute() to execute SQL commands.
- Authentication and Security (Chapter 3):
- Implementing user registration and login functionality.
- Encrypting passwords using bcrypt to protect user data.
- “bcrypt has all the code for encrypting the passwords and creating a truly secure application”
- Generating JSON Web Tokens (JWT) for user authentication.
- Using middleware to verify JWTs and protect routes that require authentication.
- Client-Side Emulation and Testing:
- Using a REST client (e.g., VS Code extension) to emulate browser network requests and test backend endpoints.
- Defining different emulations for various functionalities, such as registering a user, logging in, creating to-dos, etc.
- Transitioning to PostgreSQL and Prisma (Chapter 4):
- Upgrading from SQLite to PostgreSQL for better scalability and reliability in a production environment.
- Using Prisma as an Object-Relational Mapper (ORM) to interact with the PostgreSQL database as if it were a JavaScript entity.
- “Prisma as an ORM to interact with our PostgreSQL database as if it were a JavaScript entity”
- Prisma simplifies database interactions and provides additional advantages.
- Dockerization (Chapter 4):
- Containerizing the backend application using Docker for easy deployment and portability.
- Using a Dockerfile to define the steps for building a Docker image for the Node.js application.
- “Docker file is essentially an instruction sheet for creating one Docker container”
- Using docker-compose.yml to orchestrate multiple Docker containers (e.g., the Node.js server and the PostgreSQL database).
- Defining environment variables and port mappings in the docker-compose.yml file.
- Using volumes to persist data and configuration settings across container restarts.
- Prisma Schema and Migrations (Chapter 4):
- Defining the database schema using Prisma’s schema language (e.g., schema.prisma).
- Using Prisma migrations to manage changes to the database schema over time.
Code Snippets and Examples:
- Creating a table in SQLite:database.execute(`
- CREATE TABLE users (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- username TEXT UNIQUE,
- password TEXT
- )
- `);
- Encrypting a password with bcrypt:const hashedPassword = bcrypt.hashSync(password, 8);
- Signing a JWT:const token = jwt.sign({ id: result.lastInsertRowID }, process.env.JWT_SECRET, {expiresIn: ’24h’});
- Verifying a JWT in middleware:jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
- // …
- });
- Docker Compose:version: “3”
- services:
- app:
- build: .
- container_name: todo-app
- environment:
- DATABASE_URL: “postgresql://postgres:password@database:5432/todos?schema=public”
- JWT_SECRET: “your_jwt_secret_here”
- NODE_ENV: development
- PORT: 5003
- ports:
- – “5003:5003”
- depends_on:
- – database
- volumes:
- – .:/app
- database:
- image: postgres:13-alpine
- container_name: postgres-db
- environment:
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: password
- POSTGRES_DB: todos
- ports:
- – “5432:5432”
- volumes:
- – db_data:/var/lib/postgresql/data
- volumes:
- db_data:
Conclusion:
The source material covers a comprehensive guide to backend development, starting from basic server setup to advanced concepts like database management, security, and containerization. The progression from SQLite to PostgreSQL with Prisma, and the introduction of Docker, represents a significant shift towards production-ready backend applications. The key takeaway is the importance of structuring code, managing dependencies, and implementing security measures to build robust and scalable backend systems.
Server-Side Development: Key Concepts and Practices
### 1. What is a port in the context of server development, and why is it important to define one?
A port is a virtual communication endpoint on a device that allows different applications to listen for and receive network requests. Defining a port is crucial because it tells the server exactly where to listen for incoming connections. Common port numbers include 3000 and 8000, but any four-digit number can be used. Without a defined port, the server wouldn’t know where to “listen” for requests, and clients wouldn’t be able to connect to it.
### 2. What is a callback function in JavaScript, and how is it used in the context of creating a server?
A callback function is a function that is passed as an argument to another function, to be executed at a later time. In server creation, a callback function is often used with the `listen` function. This callback is executed when the server is successfully started and is listening for incoming requests. It can be used to log a message to the console, indicating that the server is running and on which port.
### 3. Why is it beneficial to use `npm` scripts for running a server, and how do they work?
Using `npm` scripts, defined in the `package.json` file, offers a structured and repeatable way to run server commands. They allow you to define shortcuts for complex commands, making it easier to start, stop, or restart the server. `npm` scripts work by defining a key (e.g., “dev”) in the “scripts” section of `package.json`, and assigning a command string to that key (e.g., “node server.js”). To run the script, you use the command `npm run [key]`, which executes the associated command.
### 4. What is `nodemon`, and why is it used as a developer dependency?
`nodemon` is a tool that automatically restarts the server whenever changes are made to the code. It’s used as a developer dependency (installed with `npm install –save-dev nodemon`) because it significantly improves the development workflow by eliminating the need to manually restart the server after each code modification. It’s not needed in production because the code shouldn’t be constantly changing.
### 5. What is the difference between a URL and an IP address, and how do they relate to a server?
A URL (Uniform Resource Locator) is a human-readable address that points to a specific resource on the internet, often a server. An IP address (Internet Protocol address) is a numerical label assigned to each device connected to a computer network that uses the Internet Protocol for communication. Every URL is mapped to an IP address, allowing browsers to locate the server. A URL is easier for humans to remember, while the IP address is the actual address used for network communication.
### 6. What are HTTP verbs (methods) and routes (paths), and how are they used to handle incoming network requests?
HTTP verbs (e.g., GET, POST, PUT, DELETE) define the action a client wants to perform on a resource. Routes (or paths) specify the specific location or “endpoint” on the server that the client is trying to access (e.g., “/”, “/dashboard”, “/api/users”). The server is configured to listen for specific HTTP verbs on specific routes. When a request arrives, the server examines the verb and route to determine how to handle the request and what action to perform.
### 7. What is an environment variable, and why are they used in server-side applications?
An environment variable is a key-value pair that stores configuration information outside of the application’s code. They are used to store sensitive information like API keys, database passwords, and other settings that might vary between development, testing, and production environments. Storing these values in environment variables keeps them secure and allows you to change configurations without modifying the application’s code.
### 8. Explain the purpose and organization of the file structure created for a more sophisticated backend application (e.g., `src`, `routes`, `middleware`, `db.js`, `public`, `.env`, and `docker-compose.yaml`).
This structure aims to separate concerns and improve code organization. Here’s a breakdown:
* **`src`**: Contains the source code of the application.
* **`routes`**: Holds files that define the different API endpoints and their associated logic (e.g., `auth-routes.js`, `todo-routes.js`).
* **`middleware`**: Contains functions that intercept incoming requests and perform tasks like authentication or data validation before the request reaches the route handlers (e.g., `authMiddleware.js`).
* **`db.js`**: Contains the logic for connecting to and interacting with the database. Includes SQL queries.
* **`public`**: Stores static assets like HTML, CSS, and JavaScript files that make up the front-end of the application. These files are served directly to the client.
* **`.env`**: Stores environment variables (sensitive configuration information).
* **`docker-compose.yaml`**: Defines the configuration for running multiple Docker containers together, such as the application server and the database server.
Routes, Endpoints, and HTTP Verbs: A Server-Side Guide
Here’s a discussion of routes and endpoints, based on the provided source:
- A route can be understood as a specific path or destination within a server that is set up to listen for incoming network requests. In the context of a URL, the route is the sub-portion that directs the request to a specific area. For example, in the URL http://www.youtube.com/dashboard, /dashboard would be the route.
- HTTP verbs, also referred to as methods, describe the action that the network request intends to perform. Common HTTP verbs include:
- GET: Used to retrieve information
- POST: Used to create new data
- PUT: Used to update existing data
- DELETE: Used to delete data
- Endpoints are created within the server-side application using HTTP verbs and routes. An endpoint is a specific subregion within the server that is set up to listen to incoming network requests, and to which code can be directed to execute a body of logic and respond appropriately.
- Together, the route and the HTTP verb create the endpoint. For instance, a GET request to the /home route would define one endpoint, while a POST request to the /api/data route would define another. The method informs the nature of the request, and the route is a further subdirectory.
- Types of endpoints:Website endpoints: These send back HTML and are accessed when a user enters a URL in a browser.
- API endpoints: These do not send back a website, but rather facilitate behind-the-scenes operations, like saving data when a user clicks “save”. They might send back data in JSON format.
- Middleware can be used to handle authentication between the client and server side.
- Client emulators, such as the REST client in VS Code, can be used to emulate the process of sending out a network request and testing endpoints.
- Express.js is a framework that can be used to configure servers to listen to and interpret incoming requests.
Database Interactions: Storage, Management, and Security
Here’s a discussion of database interaction, as described in the sources:
- Databases store data from user interactions. When a user performs an action like saving data, a network request is sent to the back end, which may then send another network request to the database to persist the information.
- Backend applications are set up to listen for incoming network requests and can then interact with a database to store, retrieve, update, or delete data.
- SQL (Structured Query Language) commands are used to interact with databases. These commands can create tables, define columns, and establish relationships between tables.
- CRUD (Create, Read, Update, Delete) actions are the four basic operations that can be performed on data in a database. These actions correspond to specific HTTP verbs:
- Create corresponds to POST
- Read corresponds to GET
- Update corresponds to PUT
- Delete corresponds to DELETE
- When building an application, it is important to configure endpoints to manage authentication and to ensure data is properly saved to the database when a new user registers.
- Prepared statements can be used to safely insert values into SQL queries, preventing SQL injection vulnerabilities.
- ORMs (Object-Relational Mappers) provide an abstraction layer that allows developers to interact with databases using a more object-oriented approach.
- Migrations provide a way to manage changes to the database schema over time, ensuring that all instances of the database are updated to the most recent version.
- Docker allows containerization of databases, making it easier to deploy and manage them.
- Directly logging into the database via the command line provides the ability to modify it directly using SQL queries.
Authentication and Tokens: A Concise Guide
Here’s a discussion of authentication and tokens, based on the provided sources:
- Authentication is the process of verifying the identity of a user or client attempting to access a protected resource.
- Authentication middleware can intercept network requests to verify the token associated with the request and ensure that the user is authorized to access the requested resource.
Here are key aspects of authentication and tokens:
- Encryption: Instead of storing passwords verbatim, they are encrypted using libraries such as bcrypt. Bcrypt generates a hash for a given string, enhancing security. Encryption algorithms are deterministic, meaning that encrypting the same password using the same algorithm will always produce the same encrypted key.
- Tokens:
- After successful registration or login, the server generates a unique token (typically a JSON Web Token or JWT) and sends it back to the client.
- The client then stores this token (e.g., in local storage or cookies) and includes it in the headers of subsequent network requests.
- JSON Web Tokens (JWT) are a standard for securely transmitting information between parties as a JSON object.
- JWT Authentication: This involves the use of a JSON token as a secure password associated with a user, used to authenticate them without requiring repeated sign-ups.
- Token validation:
- When a network request is made to a protected endpoint, the server’s middleware extracts the token from the request headers.
- The server then uses a secret key to verify the authenticity and integrity of the token.
- If the token is valid, the middleware grants access to the requested resource. If the token is invalid or missing, the middleware rejects the request and returns an error response.
- Token expiration: Tokens typically have an expiration time, after which they are no longer valid and the user must re-authenticate.
- Environment variables: Secret keys used for token verification (e.g., JWT_SECRET) are stored as environment variables to prevent them from being exposed.
- Benefits of tokens: They allow a user to authenticate once and then access protected resources for a specified period without needing to re-enter their credentials.
Client Emulation: Testing Server Endpoints and Network Requests
Here’s a discussion of client emulations, based on the provided sources:
- Client emulators are tools that mimic the behavior of a client (such as a web browser) in order to test server endpoints and ensure they are functioning correctly.
- A client emulator emulates the process of sending out a network request.
- REST clients, such as the REST client in VS Code, are a commonly used type of client emulator. These tools allow developers to define and send HTTP requests to specific URLs and inspect the responses returned by the server.
- Client emulators can be used to test different types of endpoints, including website endpoints and API endpoints.
- When using a client emulator, it is possible to specify various parameters of the network request, such as the HTTP verb (e.g., GET, POST, PUT, DELETE), headers, and body.
- Client emulations can be created to mirror user actions. This is analogous to running tests in JavaScript or another programming language.
- To create a client emulation, you would specify the HTTP verb, URL, headers, and any data to be sent in the body of the request.
- Client emulators can be particularly useful when developing APIs, as they allow developers to test endpoints and verify that they are functioning correctly without having to build a full user interface.
- By predefining interactions, developers can emulate functionalities as if a user were using an application.
- The process involves thinking of everything a user could possibly do and then creating those actions programmatically. This ensures that everything is working adequately.
- Client emulations can be used to test authentication flows, such as user registration and login.
- The REST client in VS Code uses a .rest file extension to emulate browser network requests.
- The REST client separates all the template Network requests using triple pound signs (###).
- The REST client displays the response from the server, including the status code, headers, and body.
- Content type is a parameter of the network request that can be configured.
- The authorization token is encoded into the request so that middleware can intercept and interpret it, and consequently authorize the client.
Server Configuration: Back End, Ports, and Middleware
Here’s a discussion of server configuration, based on the provided sources:
- Back end requests: The back end is all of the code that goes on behind the scenes to facilitate user experience of the internet. The back end consists of external devices all around the world that communicate through a network via network requests. These network requests are encoded with all the information that allows communication to happen and for both parties to contribute to someone’s experience of the internet.
- Listening for requests: A back end application must be set up to listen to incoming Network requests; otherwise, no websites will load. The back end is just hardware running software that is connected to the internet and that listens to incoming requests to its IP address.
- Full stack interaction: The moment the network request leaves a computer and goes into the network, everything on the other end of that equation is the back end. The full stack is the front end, which is on the client side, and the back end, which happens server side.
- Ports: To tell an app to listen, one parameter that must be provided is a port, which is a subdirectory within the IP address.
- Middleware:
- Middleware is part of configuring a server.
- It is configuration that is set in between an incoming request and the interpretation of that request.
- It can be thought of as a protective layer.
- A common type of middleware is authentication middleware which handles all of the authentication between the client and the server side.
- File organization:
- The specs file contains all the specifications for a project.
- Modern project directories should contain source code, which is all the code that creates an application.
- The server should be the hub of the application.
- Node.js:
- Node.js is a Javascript runtime.
- With the experimental features available in the later versions of Node.js, the server reboots automatically when changes are saved.
- Express.js:
- Express.js is a minimalist web framework for Node.js.
- It is commonly used to build back end applications.
- Docker:
- Docker allows containerization of applications.
- Docker is an alternative to having software installed on a computer.
- Environment Variables:
- Environment variables are a storage of keys and values; the key is the lookup term, and the value is a potentially secret string of characters that needs to be referenced for the configuration of a project.
- Any top secret information is thrown in the .env file so that it can be avoided from being uploaded, for example, to GitHub.
- File types:
- .js is the Javascript file extension.
- .rest or .http are extensions used for client emulators.
- .env files are for environment variables.
- .yaml files are used to indicate instruction sheets.
- Setting up a server:
- Setting up a basic server only takes about four lines of code.
- The code must define a variable called Express and set it equal to the Express package.
- The code defines the back end application.
- The code configures the app and tells it to listen to incoming requests.
The Original Text
hello there my name is James and welcome to this backend full course where we’re going to go from being complete amateurs at backend development to Absolute Pros building all sorts of amazing backend applications for the internet now I am very excited to have this course live on the channel because I personally know how hard it can be to learn the art of backend development I went through that on my learned code journey and now I’m very excited to have this course available because ever since that experience I’ve wanted to create a course that does three things first it’s super beginner friendly which means that even if you have absolutely no experience with backend development you will be able to complete this course we’ll start from the very beginning from scratch and build up from there the second thing the course does is it teaches you all of the Core Concepts and foundational knowledge you need to know all of the best practices the latest and greatest technologies that you need to know to go off and become these Supreme wizards of backend development so that should be super cool and last but absolutely not least if you get to the end of the course you will be left with a portfolio of projects of the caliber needed to get you hired as a full stack developer backend developer software Dev you name it these projects in your GitHub will knock the socks of prospective employers your family and friends and it will just be loads of fun now the course itself is broken down into four chapters chapter one is a theory lesson where I want you to sit back and open up your brain to the universe as I share with you some theory about how the internet works what the full stack is and consequently what the backend is what we can expect from it and how we can actually go about coding out some backend infrastructure now this is not for you to sit down and memorize everything that I’m saying or take some notes it’s just an exercise and gaining some familiarity with some of the concept that we will then put into practice in the latter three chapters in Chapter 2 project number one we’re going to build a very rudimentary backend application that just demonstrates some of these Core Concepts in code form pretty simple doesn’t look the best but you know it serves a purpose as it allows us to dive into the last two projects which is super cool project number two chapter 3 is a complete complete backend application it’s kind of like a quick start backend application where we develop a very comprehensive backend server and have complimentary database interactions we’ll be using the sqlite database which is a super lightweight FAS to get up and running database very popular maybe not so much for production but if you’re just looking to get your backend application up and running it is a great choice so we’ll learn how we can develop a backend application that serves up a front end uses authentication and has database interactions and then in the last project we’ll take that code base to the next level God te mode we’re going to be using postgress for the database we’re going to be using an OM which is an object relational mapper and that’s going to be Prisma we’ll serve up a front end we’ll handle all of the authentication and database and then at the end we’ll dockerize all of these uh backend services so that we have this containerized application it should just be absolutely Wicked a brilliant code base to have on your GitHub page for once again prospective employeers to have a look at and be like yes this is the person we want to hire to develop our backend infrastructure now as for the prerequisites what do you need to know to complete the course well the list is pretty short all you need to know is some JavaScript if you’re looking for a course to brush up on your JavaScript I’ve got one Linked In the description down below but everything else you need to know in this course will be taught to you so you just need some pretty you know reasonable JavaScript skills and you will be absolutely sweet getting to the end of the course and last but not least what do you do should you get stuck at any point well I’ve got you covered there too first up we have some cheat sheet notes you can just keep these open if you want they’re available for JavaScript and they just cover all the basic JavaScript techniques that you should be aware of Linked In the description down below and as for any questions qus or queries you may have if you head over to the GitHub page for this product project that has all of my code there that you can look at and compare and with all your questions you can hit over to the issues tab click on issues and then just write your question and either myself or someone else will respond and help you understand whatever it is that you may have been struggling with so that should be absolutely Wicked finally if you want to support the channel you can obviously become a channel member and unlock the Discord where I’m super active so you could ask any questions there too at the end of today should be an absolute Wicked course I’ve been so excited to release it I’ve worked on it for ages so proud of this material and I hope you thoroughly enjoy it and with that all said if you do enjoy the course don’t forget to smash the like And subscribe button so that I can continue to feed Doug a healthy diet all right it’s time to dive into chapter one which is a theory lesson about how the internet actually works now as I said in the intro I don’t want you to take any notes I just want you to sit back get comfortable and be a sponge for the information that I am about to share with you you don’t have to memorize all of it I just want you to be familiar with some of the terms and Concepts so that when I refer back to them later in this course you can be like I know exactly what’s going on here and the first concept I’m going to introduce you to is known as the full stack now when you open up your computer load up a browser and come to YouTube essentially the programming that goes into creating that experience is known as the full stack it’s the overarching body where the C the culmination of all of these individual puzzle pieces working together to create that experience it’s kind of like a burger a burger is the end product just like you loading up youtube.com that’s the end product you experience YouTube and a burger has a whole lot of subcomponents that to to create this experience of enjoying a burger and that’s the same with YouTube a programmer or lots of programers have sat down and worked together and creating all of these puzzle pieces that come together to creating your experience of YouTube and as a collective they are referred to as the full stack it’s the full stack of things coming together to create that experience now the full stack can be broken down into two primary components one is known as the front end and the other is known as the back end obviously this is a backend course but to understand what the back end does we also have to understand what the front end is responsible for now the front end kind of is summarized in three Core Concepts one is the user you using YouTube are a user we’ve all got experience being a user the second concept is known as the client the client is the medium through which you interact with the internet in most cases says it’s a browser so Google Chrome would be the client through which you interact with the internet whether that’s entering a URL or clicking a save button on a website that’s all a client side experience because it’s happening on your device it’s on the side of the equation that is associated with the user or the client now the last term that comes together to create the front end is actually the front end itself what is the front end well at the end of the day it’s pretty much just the website so when you load up youtube.com at its core that’s some HTML CSS and Java script that your browser runs to create this visualization of the website and that is referred to as the front end so if the client is the medium through which you interact with the internet the front end is the legitimate interface that you can interact with to have this internet experience and so that is the side of the equation that is the user side it’s on the user’s device and that collectively creates the front end it’s the tangible side of this full stack experience now at the same time when you load up YouTube you’re probably connected to the internet what’s going on in the background to facilitate this experience well the answer is a lot of stuff there is so much magic going on behind the scenes to create your front-end experience that without it you just wouldn’t be able to enjoy the internet and that’s what this course is all about how can we program these systems now the way that I want to describe how the backend works is actually by step by-step explaining to you what happens when you open up your computer load up a browser and enter ww.youtube.com and in a split second get that website displaying on your screen and essentially how it actually works at a very technical level is that when you type in this URL http://www.youtube.com and hit enter your browser sends out what’s known as a network request now we can imagine that your computer doesn’t have every single website on the internet saved on it so that means that when you load these websites your browser is actually having to request these websites from an external network now there’s loads of examples of what a network could be it could be a cellular network for mobile phones it could be a Wi-Fi network or Network there’s lots of different examples of networks but essentially your browser when you type in and hit enter on this URL your browser emits this electromagnetic wave that is encoded with the information that your browser needs access to so it is encoded with the URL the network request has this URL saved into it and then it emits this network request into the network where the URL actually locates a destination now a lot of us might actually think of the internet as being this ethereal thing that exists around us and you know we magically pull the information out of the air when we type in these URLs but actually it’s slightly more complex than that the URL a lot of people might not know this but it actually is an address so when you type in http://www.youtube.com your network request is directed to an address in the network and that address doesn’t actually locate a website it actually locates another device connected to the internet now every device connected to the internet has what’s known as an IP address and that is its metaphysical address in the network so when we encode these addresses into the network request you know the network is set up to navigate and ultimately locate these devices now a URL is just a human friendly address so every device connected to the internet has an IP address not all of them have URLs but when you type in a URL that gets converted to an address via what’s known as the DNS which is the domain naming service the domain is the sub portion of the URL so in the case of http://www.youtube.com the domain is youtube.com that gets converted into an IP address which is a sequence of numbers not very easy to remember which is why we have a URL and that’s where these Network requests get directed to they get directed to these addresses these IP addresses in the network which are corresponding to another device connected to the network now that doesn’t really explain how you end up with a website on your screen but we will get there these devices at these uh IP addresses are set up to listen to incoming Network requests so when we develop servers like we will do in this course we set them up we connect them to the internet and we set them up to listen to incoming Network requests to their IP addresses now when a server receives our Network request which is asking for a website if you’ve entered the YouTube the URL ww.youtube.com it can then decode that Network request see that oh this individual is looking for the HTML code to load up the YouTube homepage and it can then go to its little database where it stored all of this code or read some files that are available on this external device and it can then encode them into a response so these Network requests that these servers receive also have a Return to sender address so they interpret the intent of the network request they do any actions that they need to and then they respond with the appropriate information data or service and that all happens in the split second that it takes to load a website like youtube.com you hit enter on that URL your browser adits the network request it’s encoded with all of this information that describes the intent of that Network request which in the case of entering a url url is to retrieve a website or gain access to a website it hits This Server and then the response is sent back across the network as literally electromagnetic uh waves whether or not it’s through a fiber optic cable or you know the air your browser receives this response that is encoded with all of the appropriate information in the case of a website it’s h2l code it then interprets the HTML code and displays it on your screen and you get the website now that is a full stack interaction where the moment the network request leaves your computer and goes into you know the ethos or the network everything on the other end of that equation is the back end the back end is all of that code that goes on behind the scenes potentially on other devices all around the world to facilitate your experience of the internet if we didn’t have backend applications set up to listen to these incoming Network requests there would be no websites to load it would just be you know you’d send out a network request into Oblivion and you would never get any response back and so that’s what we’re going to be coding in this course today there is so much you can do with backend applications and we’re going to get a really solid understanding of some of the most core operations that you can expect from backend applications now now there’s two more things I just want to throw on this Theory lesson at the very end number one is what the front end actually does I’ve talked about that entering a URL sends out this network request to gain us access to the HTML code to display the website well the website itself is typically just an interface to make sending out these Network requests even easier so when you hit save the same operation occurs to persist that data in a database a network request is sent out saying save this information to the database the server listening for these incoming Network requests receive the network request interprets that oh the user wants to save the data it then might even send out another Network request to the database with that information and that then gets persisted in the database so the backend can be you know a whole lot of separate servers interconnected to facilitate your experience of the internet and the other thing I wanted to point now is that you know nowadays we have a lot of modern solutions for developing backend applications such as Cloud infrastructure or serverless backend infrastructure all of this is just more servers running more code set up to listen to incoming Network request so at the end of the day the full stack is just the front end which is on the client side on your computer where the user interacts with it they get access to a front end and the back end is everything that happens service side where the server is all of these external devices all around the world and they communicate through a network via Network requests which are encoded with all the information that allows that communication to happen and for both parties to contribute to someone’s experience of the internet now I know that’s a lot of information to swallow once again you don’t have to remember all of it just being familiar with the concept of a backend okay it’s this external device that’s connected to the internet that’s list listening to incoming requests sent to its IP address uh a URL is just an IP address that’s written in a human friendly form the client side is everything that happens on the user’s device the client is the browser the front end is the website they are the user just being familiar with these Core Concepts will really help give you a solid foundational understanding of all of the decisions we make throughout this course and just make you that much better of a backend programmer anyway that’s the theory lesson over well done on getting to the end of chapter 1 and with that all said it’s time to get our hands dirty with some code as we dive into our first project and chapter 2 of this backend full course all righty you know what they say with the theory done the fun may now begun that’s a good one for you now it’s time to dive into chapter 2 which is our first practical introduction to backend development and at this point we’re going to quickly introduce some of the technology you will need you probably already have it installed on your device to complete this backend full course there’s three particular installations you will be needing number one is a code editor we’re going to be using a vs code on my device uh the link to download visual studio code is available in the description down below uh you can select your operating system and install it you probably used it before if you know JavaScript but this is obviously what the window looks like when you open it up something a bit resemblant of this you might have a different theme but yes you will need Visual Studio code a place to write all of the JavaScript and build out our backend infrastructure now for the second installation is going to be node.js where we have JavaScript we write JavaScript as JavaScript set of instructions we need what is known as a JavaScript runtime a runtime interprets and executes your instructions and the runtime we’re going to be using is nodejs we are going to install it on our device and the link to download is available in the description down below you can either install it via package manager or pre-built installer once again choose your operating system as for the version I’d recommend the LTS version or current version we’re going to learn how we can middle with the versions later in this course so at the end of the day it’s not that important and the last installation is going to be darker now if you’re unfamiliar with darker essentially what darker does is it allows you to containerize your applications now the reason Docker is brilliant is because the code that we write is often dependent on a particular operating system and what Docker allows you to do is containerize your application and create a set of instructions for this container which is just a virtual environment that can be consistently run across all sorts of uh systems architecture or operating systems and it just means that you don’t run into issues where one person can’t run your code you can someone else can someone else can’t or you go to deploy your code and it’s complicated because you you know are locked into a particular operating system so Docker allows you to wrap your application inside of a virtual environment and then just Define the set of instructions to configure the virtual environment and you’re absolutely sorted brilliant technology looks brilliant on a resume and this will come into play in chapter 4 our final project for this full course once again the link to install Docker is available in the description down below and when you boot it up you should end up with a window that looks a little bit like this now that we have all our installations done it’s time to jump into the code so what I’m going to do to begin is open up a blank window of Visual Studio code so here we have my blank window open and what we’re going to do from within here is Select this open but button and we’re going to come to a folder personally this is where I keep all of my coding projects and in here you’re going to create a new folder called back end- f-c course now I’ve already created my folder so I’m just going to go ahead and select it and once you have created or selected that folder then you just want to select open and that is going to open up that folder inside of Visual Studio code and this is where our projects in this course are going to go now over on the side here we can in fact confirm that we are in the correct folder directory because if we open up our Explorer here it says back in full course and I already have one folder in here it’s the chapter one folder which contains a document that is just the you know written version of the theory lesson so if you want to refer back to that at any point you can find this chapter 1 folder and download it to your project Direct or just refer to in the GitHub Reaper which is linked in the description down below so you just want to open up the chapter one directory and look for the theory. markdown file totally not necessary just if you want to have it there now the first thing we’re going to do in here is create a folder for our chapter 2 project so what I’m going to do is right click and create a new folder equally you can use these action buttons right here and I’m just going to create a folder called chapter to if I hit enter on that that is now created and it is within this folder that we are going to house our very first backend project now when we’re first getting started with a backend project using node.js and JavaScript there’s a number of ways that we can go about configuring this project now typically when you’re developing backend code inside of JavaScript we like to take advantage of what is known as the node package manager ecosystem where essentially what that is is a whole lot of different packages or code libraries that we can very easily gain access to and utilize them inside of our codebase to save us having to do everything from the very beginning super standard practice if you’re developing backend applications inside of nodejs and JavaScript and we’re going to see how to do it but essentially what it requires us to do is initialize our project as a node mpm project now to do that super simple the first thing we’re going to do is open up a terminal instance inside of our Visual Studio code I like to use the control backtick keys to toggle a terminal instance just like that now if you want to know all the key shortcuts that I use inside of vs code to speed up my coding process there is a link to a website that that explains all of them in the description down below including the key command to toggle your terminal you can also open up a terminal instance from the folder options just as equally now with this terminal instance open the first thing we note is that we are in the backend full course project directory inside of our terminal we actually want to be inside of chapter2 so the First Command we’re going to type in here is the CD or change directory command and then we’re just going to specify the folder to which we want to enter which is is the chapter2 folder directory and if I go ahead and hit enter on that we can see that our folder directory inside of our terminal has now been updated to chapter 2 so we’re officially inside of our folder directory and this is where we’re going to initialize our project now to be able to initialize a project the first thing we’re going to have to do is ensure that we have node installed on our device correctly now there’s a very easy way to check whether or not you have node installed on your device all you do is you type the node space- v the- v flag inside of your terminal and hit enter and if you have successfully installed node.js on your device you should get a version popping up right here if you receive any type of error that means your installation is either incomplete or incorrect so that’s just one thing we need to do to confirm that node is installed on our device once again you don’t have to worry about the version of node that you have installed on your computer we’re going to learn how we can mdle with the node version later in this course that will become important in chapters 3 and four so now that we’ve confirmed node is working we should also be able to access npm DV so you can run the npm – V command that will ensure that you have access to node package manager on your computer and then what we can do is run the mpm init command with the dasy flag now this command is going to initialize our nodejs backend project inside of our chapter 2 folder directory so if I go ahead and hit enter there we can see that we get an output in our terminal we get told that we wrote to a particular file the package.json file and we wrote this code to this Json to that file so now if we come over to what was originally an empty chapter 2 folder we can see that we have a file inside called our package.json file now what this file is it’s a Json file so it’s basically just a glorified string object it essentially just qualifies exactly what our project is all about it’s kind of like a Specs or specification file so up here we can see we have some Fields the name of the project the version you can modify the version when you you know publish your project to production we can give our project a description so we could say a simple backend ser Ser underneath that we have a main that’s not really relevant to us we have a scripts field this is going to be very relevant to us we’ll see exactly how later and then we just have some other fields that at the moment aren’t really that important but the morel of the story is that this file is going to contain all the specifications for our project now I’m going to go ahead and create another file inside of this folder so I’m going to select that folder create a new file and this is going to be called server. JavaScript or. JS which is the JavaScript file extension now if I go ahead and click enter on that server.js that’s going to initialize that Javascript file and we can see in here I can open it up type a whole lot of code it’s all sorts of JavaScript uh and this is where for this project we are going to create our server application our backend project now when it comes to creating server side applications or backend applications inside of node.js a common framework or package that is used available within the node package manager ecosystem is called Express now you technically don’t need Express to create a Javascript file and set it up to listen to incoming Network requests and act as a server however it is infinitely easier using a package like Express because Express is designed specifically for that purpose as we can see here it’s a fast unopinionated minimalist web framework for node.js so we’re going to be using that inside of this course it’s incredibly common you’ll find most big uh Enterprise level backend applications built out of nodejs will use express or an equivalent package to basically allow them to build these backend applications so what we need to do now that we have a server is add this package to our project and we can see that you know in this website right here for this package they tell us exactly how we go about doing that and we just run this npm install Express command inside of our terminal so if I come back over to the code specifically the terminal what I’m going to do down here is clear everything out and I’m now going to run npm install which is how we install packages from the npm or node package manager ecosystem and I’m going to install the Express package so if I hit enter on that that’s going to go ahead and download everything we need to utilize that package inside of our project so here we can see it’s added a whole lot of packages in a very short time span and we can also see that a whole bunch of files and folders have been added to our chapter 2 project directory now we obviously had the server.js and we originally had a package.json after we initial ized our nodejs project if we come into the package.json we can see that one thing has changed we now have this dependencies field and within the dependencies field we have the Express package listed this is super important because once again our specs for the project need to specify what code packages our project is dependent on hence we list Express as a dependency we also specify what version we use for our project once again it’s not too important if your version isn’t exactly equal to mine as long as they’re approximately the same the code should all be equivalent now the other reason this dependencies field is important is because if someone else downloads your code base they need to be able to install all the necessary packages to run your code just as equally if you were to publish this to a production environment a live environment for the internet when you configure that environment it needs to know what dependencies to install to get your project up and running now as for where these packages have been downloaded to everything is within the node modules file so if we go ahead and open that up that’s got a whole lot of files and folders in there we will not be touching any of them all of those packages just get thrown into the node modules file or folder and that just sits there and we don’t need to do anything about it we can see we also have this package-lock do Json that’s that’s another complicated file that we’re really just not going to be touching it’s not one that you want to Middle with the folders and files that are important to us are specifically for now this package.json and the server. JavaScript now to initialize a server inside of a node.js or JavaScript file using Express that literally only takes about four lines of code so it’s incredibly easy to get a server up and running that doesn’t mean that the server is complete but you know it’s a good start so that’s exactly what we’re going to do now so to initialize a server using Express the first thing we need to do is Define a variable called Express and set it equal to and what we set it equal to is we require in the Express package so essentially what this line of code does is it requires the Express package and we assign whatever is in that pre exis and code that package to this variable so that we can then use it all throughout our project so that basically Imports Express into our code base right here the next thing we need to do now that we have access to express is to Define our backend application and we do that very simply by defining a variable called app and setting it equal to and we invoke Express as a function so that’s going to create our backend application for us and then the last step is we say app and if you recall from our lesson from our Theory lesson the back end is just Hardware running software that is connected to the internet that listens to incoming requests to its IP address so we have this server app and we the last thing we always do this line goes at the very bottom of our code is we configure it and then we tell it to listen to incoming requests so that’s what this line does now when it comes to telling an app to listen one parameter we need to provide it is known as a port which is basically just a subdirectory within the IP address so the IP address is the address of the device and the port is a location within that device and so what we’re going to do in here is Define a port I’m going to use all uppercase as a variable and I personally like to use 8383 typically it’s a four-digit number some common ones are 3,000 8,000 so on and so forth I just like 8383 those are my lucky numbers so now we have this port what we can do is we can pass in the port as an argument to the lesson and we can say all right Mr server app I now want you to listen to incoming requests to this IP address specifically at this this port now there’s one other argument we can pass to this listen function and that is a call back function so in here I’m going to create this Arrow function and once again just a reminder if your JavaScript needs a bit of brushing up on there is a course Linked In the description down below but anyway in here we have an arrow function this is a callback function to be executed when our server is up and running and all we’re going to do in here is console.log so we’re going to log something to the console it’s going to be a template literal string and it’s just going to say server has started on and then I’m going to use the dollar sign and the curly braces to inject the port variable into this template literal string so with that all done these are the four lines of code that we need to create a server that is officially listening to incoming requests over the Internet so obviously the next thing we need to do is actually run this file now there’s a number of different ways that we could go about doing that one is very simply to tell node to read the server.js file and go ahead and execute that file so if I hit enter on that we can see that right here I get this output server has started on Port 8383 absolutely brilliant our server is up and running and one other thing to note is that we never finished the execution of that file it’s kind of stuck in limbo and that will remain to be the case Cas while our server is indefinitely listening to these incoming requests so here it’s a continued execution of this file or basically we never ended the initial execution of this file it’s still running it’s still listening to these incoming Network requests so that’s pretty neat congratulations you have officially with four lines of code created a server that is technically connected to the internet listening to these incoming requests that is a solid backend application that doesn’t actually do anything but you know it’s a start now what I’m actually going to do at this point is kill the execution of the server and I’m going to do that using the control and C keys so there I type the control and C keys and that killed the execution of the file and I now have access to my terminal once again and can write some additional commands so that’s pretty cool now in this project that’s actually not how we’re going to go about booting up our server we’re going to do everything via npm and Via this package.json basically through the specs file now in here we have a field called scripts and we’re going to go ahead and add a script where the script is just some a set of instructions to basically get our server up and running now the first thing you have to do to add a new script is give it a title or key in this case it’s going to be called Dev and then what I do is I set it equal to a string adding a comma to the end of that field to keep the Json happy and in here I’m going to insert that command so that’s going to be node server.js now that’s just the same command we ran earlier and if you were just running between these two uh boot up instances it wouldn’t really matter which one you did but it’s good to get into the practice of doing it via the package.json and the script methodology because occasionally these scripts these startup commands become a lot more intricate and complicated so now I’ve gone ahead and added this simple Dev script right here I’m going to go ahead and save that package.json file now what we can do to boot up our server is we can tell npm to run that particular script so all we do in here is we type npm we say run the dev script and that’s going to execute that line of code and we can see here it checked what the line of code to be executed was no server.js and it booted up our server once again to the same outcome now that’s still actually not the way that we’re going to go about booting up our server throughout this course and the main reason for that is because if I now come in here and change something about my server let’s say I console.log this is an extra line and save that what’s happened absolutely nothing has happened so to get that that change to be reflected in the server execution I would now have to kill my file and boot it up again and now we can see we get that extra line but if you’re regularly making changes to your files that’s super annoying to have to restart your server every single time so what we’re going to do is once more kill our server uh applica kill our server execution our server application using the contrl c key and we’re going to install one more package called npm install node Monon so n o d m o n now node Monon is going to be what’s known as a developer dependency and what that means is that it’s not something you would use in production it’s specifically for development because that’s when we’re going to be making a mass amount of modifications to our file and needing it to regularly update so we’re going to install it slightly differently we’re going to write mpm install and then use a D- save-dev flag and then name the nodemon package now when I hit enter on this command it’s going to go ahead and stall that package all that code will be added to the node modules but now when I come into the package.json we can see that it actually hasn’t added it to the dependencies field but it has added it to the developer dependencies field and that means that when we publish this code to production it’s not going to worry about installing dependencies that are specifically for quality of life improvements when you’re developing the code now what we can do with nodemon installed as a developer dependency is slightly adjust this script to instead be node Monon instead of just node it’s now nodemon server. JavaScript and then we’re going to go ahead and save the package.json file with all of that done we can now run PM run run the developer script if I hit enter on that we can see once again we’ve got this as an extra line running consoling out we can see that our server has started we can see that it’s a continued execution however now when I come in here and remove this line and save this file we can see that our server was automatically restarted to reflect the changes in the code and that is going to be in definitely more convenient than constantly restarting our server every time we make adjustments to it so that’s absolutely brilliant now we have defined the code to initialize our server and we’ve got it set up to be really easy to work on modify update you know and add all the functionality we need to it to complete this project so now that I’ve created a server that is listening for incoming requests across a network network request does that mean I have a functional server well let’s go ahead and find out now earlier in the theory lesson I mentioned that one way we interact with these servers is via their address so what that means is that right now this server that is connected to the internet has an address that we can send Network requests to so from a technical standpoint the address of This Server connected to the network is Local Host it’s HTTP SL semicolon localhost 8383 this is the address or URL that is mapped to the IP address that locates this server in the network now where this instance is the URL so if we actually just specify the address uh let’s call this one the URL now I said earlier that every URL is mapped to an IP address so the IP equivalent is uh this series of numbers right here so if we were to go to a browser and enter this URL or this IP address both of them locate our server across the local network uh and that would be valid and I think technically that would actually have to be 8383 cuz we have to specify the port within the address of the device so why don’t we actually go ahead and try this and once again if you want to copy these these are available inside of the GitHub code inside of chapter 2 the server.js so if I come over to my browser I should technically be able to copy this URL paste it in here and hit enter but now we can see uh we actually get an error response that says cannot get and what we can do from within a browser is we can rightclick on this browser click inspect and that’s going to open up the Chrome developer tools and we can come over to to the network tab now within the network tab that’s going to let us see and keep in mind that this is the client side all of this is server side all of this is client side even though technically they’re on the same device for the sake of development the client when we hit enter on that URL sends out a network request across the local network for development that reaches this backend code and then it consequently responds and so that’s something that we can track our browser actually doing from within this network tab so if I refresh this whole process and hit enter on this URL we can see right here that a network request was emitted from our client from our browser if we take a look at the headers which are basically the properties or parameters that specify the intent of the network request here we can see we have the request URL which is the address we can see that we have a method which is the verb that describes the action of the request in this case it’s typically to get a website when you enter a URL into the browser it’s typically to get access to a website and so this network request has gone out into the local network it’s found our server has told the server that it wants a website but it’s received a response that says 404 that’s a status code it describes what is actually happening in the response but at the end of the day the summary is not found cannot get that website so the question becomes what’s actually happening here now one of the keys or answers is this little slash right here in addition to the get to be fair and essentially what we have to do is we actually need to configure our server to interpret these incoming requests now some of the things we need to set it up to interpret are known as the uh HTTP verbs and the routes or paths now in this case right up here this slash is known as the path and this get is the HTTP verb as far as a URL goes if I add a slash here that slash is for the home path if I were to have a dashboard that would be to the dashboard path if I were to have an or path you know that’s obviously an or path and then we could have SL or/ dasboard so on and so forth these are all of the routes or paths and they are part of the request URL now that is like once again in addition to how the port works that’s a further subdirectory to which we need to navigate these incoming requests and then we can Define actions at each of these end points these can be referred to as end points there’s specific sub regions within our server that is listening to this incoming or all of these incoming Network requests where we can direct the code to a specific endo and execute a body of logic to respond appropriately now that’s a whole lot of words right there you’ll see how it works very shortly but the other thing we have to throw into the mix here is that obviously we have these routes now where once again by default the uh the route is the slash so we can see that gives us the exact same response the second thing we need to do is configure our routes to listen to through these or interpret these specific verbs which help us further understand the intention of the network request now just before we do that one other thing I want to point out is that if we use this IP instead of the URL that’s going to give us the exact same response and that is because the URL is then converted to an IP address so we can just skip that step and use the IP address directly but obviously that’s going to be a lot harder for a human to remember now I’ve kind of said here the next step is to add in the HTTP verbs and routes but how does that work well essentially what we need to do is configure our app for these verbs and these routes now this is kind of like you know anticipating what a user is going to do so for example I could write app and I could assume that they want to get information when a user comes to my website I can assume that they want to get something you know that’s a pretty standard response and so what we do is we invoke this get method and we configure it now the first argument that gets passed into the get method is the route so in here what I’m going to do is use the slash route because up here we’re saying we cannot get that home default slash route well now I’m going to configure our server to handle incoming get requests to this Home Route and then what we do is we Define some logic to run when we get these incoming Network requests that want to get information at the Home Route and the way that we do that is by providing a second argument to this get method that is an arrow function that has two arguments a request and a response argument now that I have access to the request and the response in here I can Define some code to be executed when our server receives incoming requests to the slome route that I get request if we look at this network request right here we can see that the method is get so just to summarize that the method informs the nature of request and the route is a further subdirectory basically we direct the request to the body of code to respond appropriately and these locations or routes are called end points so technically this is end point number one and it’s the slash route once again this might be a little bit confusing initially but as we do it more and more it will become more apparent and obvious to you so now we have some code in here for the get request the income and get request which are the HTTP verbs to describe the intent of the request a verb is an action word get is to get information and these requests are directed to the slash endpoint within our server so in here what I’m going to do is have a console.log that says yay I hit an end point and I’m just going to go ahead and save that now that noon has restarted our server what I’m then going to do is go ahead and hit enter on this network request again and we can see this time we actually got a different response we didn’t get an error immediately we will soon but we actually got a different response and we can see that that website is still loading but if we come over to our console that was from earlier that’s not from this one we have absolutely nothing inside of our client side console but if we come over to our server side code we can see that we actually executed this console.log which means that that incoming Network request Was Heard by our server and this callback function was executed so in here we can now Define a whole lot of code to handle that incoming uh request now one thing I just want to point out once again is that the app needs to be configured first and then we tell it to listen second so this line of code always needs to be down the very bottom so to summarize what I just said we said that this endpoint has officially received this request and the way that we understand exactly what its intention is is via this request argument right here and the way that we respond is using this response argument so in here what I can do is I can console.log the request. method and the method is the HTTP verb so that’s pretty straightforward that could be kind of fun and to respond what we’re going to do is we’re going to call Rez and we’re going to learn our very first response type you know some responses send back HTML codes some send Json data some send all sorts of stuff some send straight up strings we’re going to send a status code of two 200 now I’ll explain what that means in just a second so if we go ahead and save that our code restarts and now if I refresh this page we no longer get an error here if I look at the network we can see that we get a 300 response right here we can see that we do in fact get something back and we get this little text element right here that just says okay and that is brilliant we officially removed all the errors from our application and we now have a full stack uh interaction where we can send out Network requests from the client they can reach our server that is listening to these incoming Network requests at its IP address specified right here it can interpret them by interpreting the intention or verb of the incoming request and also the route or path or endpoint destination which is in this case is the uh home or slash route now as for what the status codes mean whenever you have a network request we have a bunch of codes response codes or status codes that basically are a shorthand determination of the outcome of that initial request so any response code that is 200 level so 200 to 299 basically you know suggests that it was a successful request in this case we got back in okay Roger cool absolutely sweet 300 level responses are a bit more common just like uh 100 the most common are 200 so you could have 200 2011 203 202 uh then there’s 400 level responses so we saw earlier that we had a 404 that means not found and typically what that means is that there was an error in communication so anything 400 level is kind of an error in communication so 403 means that it’s a fidden request which means that you’re not authorized to do that uh 500 level requ requ ests mean that there was an error on the server side so we received your request and something went wrong so there’s a whole lot of different status codes that we can associate with the response now this line right here doing something with this resz is absolutely critical to Define how your server is meant to respond when an incoming request hits that particular end point or this body of code so for the minute what I’m going to do is just send back a 2011 one status in this case I’m going to go ahead and hit enter on that and we can see that gave us back a created response and that’s because the 201 status code says that you have created something we can see that information right here in that Network request we can see that the headers which specify the intent of the network request were to get some information at this IP address right here we can preview it doesn’t look like anything and we can see the response which is a created status now what happens if I type in/ dashboard well we get a very similar error to before where we cannot get the slash dashboard route there’s nothing there and if we look at this error code we can see that now it’s to the/ dashboard URL or route within our entire URL and we got back a 404 status code which means that we can’t find any so the way that we would have to go about configuring our server to receive incoming requests at this URL is by telling our app to listen to these get requests at this particular route so we can do that very easily just underneath right here we can say app.get we can pass in the/ dashboard route and then we can pass in this call back function receiving the request and response arguments and in here I can say console.log ooh now I hit the slash dashboard endpoint uh and what I can also do is res. send I’m not sending a status in this case I’m just going to send the string high now just before I save that one other thing I want to point out is that here we consoled get and that’s the request. method so that’s an example of how we can interpret these requests we’re listening for these incoming requests we can see what the method is we can do all sorts of stuff to understand what exactly is contained within this incoming request anyway we’ve now defined a second endpoint it’s a get endpoint at the/ dashboard route and it’s going to console some different text and it’s just ultimately going to send back a response which is a string that says hi so if I go ahead and save that our code our server restarts and if I now rehit enter on that URL we can see that we get back the response high so that is super cool we can see that the default status code of this response was 200 so in this case we didn’t specify a status but it just defaulted to 200 cuz it was a successful request all the information is okay this is the URL that we sent it out to the headers are basically the properties or parameters of the network request we got back a 200 level response there’s loads of information in here and we can preview the response that says hi and we can look at it and it’s just a string the other cool thing you can do is you can typically uh see exactly how long it took so up here I believe that would be the length of time taken to complete that uh that response which about 40 milliseconds which is very fast and just like that we have officially defined two endpoints where both of these endpoints use the get HTTP verb and we’ve seen how we can navigate or direct these incoming requests to certain end points or routes and consequently how we can respond back to them using the express Jazz framework so that’s super cool and now the next steps are to tidy up the code that we have here so that it actually resembles a more traditional web server so one of the weird things that’s happening right here is we’re obviously sending out these Network requests where the default method when you send out a network request from the client via the URL bar is of method get now one thing I wanted to clarify up here is that HTTP verbs are the same thing as the method which is just once again the action and together these create the end point which we can think of as literally the end destination of that Network request before it’s handled and consequently responded now these are both technically speaking how we actually create the endpoints within our server side application within our node.js backend and so we create loads of different endpoints to handle all sorts of different incoming Network requests so this is uh in obviously a get endpoint to this particular route uh so on and so forth now obviously in both of these cases you know in this one I send back a status code and that’s cool and all and this one I send back a string but that still doesn’t explain how we end up with a website on our screen you know when I come to a web URL in this case it’s localhost 8383 you can imagine that’s google.com is just for local development I hit enter I send out a network request across the network to the IP address that is associated with my backend server which is this one right here where’s the website well excellent question so what we’re going to do now is learn how we can convert these to actually send back a website now obviously a website is HTML code and so in future we’re going to learn how we can send back a whole HTML file but if we just really want to simplify that whole process at its very core all we’re doing is we’re res so we’re responding and we send back and I’m going to create a string and in here I’m going to create an H1 tag which is HTML we need the corresponding closing tag and this is literally just going to say this this is actually our website uh you know in Brackets HTML code so now what I’m going to do is save that our server is going to restart and now I’m going to refresh the page and this time we actually got back HTML code if I can just move this down somehow where’s the little scrolly bar it’s gone from the world or so it would seem come on you can do it uh if I can just inspect this properly elements everything’s up there but the the moral of the story is that there’s going to be HTML code in there but I can’t get to it silly silly silly anyway the point is that this is HTML code you know I could send back after that uh an input just like that that’s the HTML code for an input and now when I refresh the page we actually get an input sent back and this is how you end up with a website on your screen we go to this URL right here it’s to get URL it’s to get a website and when it rece when it hits this endpoint when our server receives that income and request we recognize that it’s a get request it’s loc you know its destination is this particular route it hits this end point so we know that the user wants a website so we can literally just send them back a website now that’s obviously one manner of communication you know one type of network request is to get websites and this is where we need to really tidy up our server because for example this dashboard route right here if someone’s going to the dashboard route you can imagine they want the homepage for the dashboard they don’t want some silly response that says hi but sometimes we literally need to send out responses that say hi and don’t load websites so what I like to do inside of my endpoints is I like to have some uh you know web it end points just like this and then I like to have a second type of websites which is more for like AP endpoints now the difference between the two of them is that website endpoints are specifically for sending back HTML so these endpoints are for sending back HTML and they typically come when a user enters a URL in a browser like we have been API endpoints are more like what happens when you type in your username and password and you hit submit that sends out the same network request it hits the back end we locate it to an API endpoint uh except these ones obviously don’t send back a website so we kind of you know that’s where the magic happens behind the scenes and we do some different with these and the point I’m trying to make with all of this is that just here these two end points I’m going to move them into this first division of endpoint which is the website endpoint so I might actually just label this this is going to be type one website endpoints and then these are going to be type two and we’ll call these nonvisual uh API end points and so now what I’m going to do is I’m going to change this first one the response so that it’s let’s just call it uh homage so that’s what it sends back as a homepage you can just imagine this is a whole lot more HTML code that is literally the homepage for our website and then in this one right here I’m going to send back the exact same thing except except for a dashboard so in this case instead of it being homepage it’s going to be Dash board uh if I can spell that correctly so here we’re going to send back the dashboard now when I refresh the page this one’s the homepage which is what we’d expect we get the website back now if I go to the dashboard link we locate the dashboard that’s absolutely Wicked for these ones down here I’m going to Define another endpoint this is going to be a get endpoint except this one’s going to be SL API SL dat now in this case we don’t have any data but what if our website you know was for example a job board and our server has all of these job listings that a user needs to get access to while the client is going to send out that Network request to the server and request all of that data all of those job listings and because we’re not sending back you know a website or anything it’s not really going to be a URL that gets entered inside of a browser I like to start them off with this SL API endpoint because it just basically signifies that this one isn’t sending back HTML it’s more of a nonvisual behind the scenes uh network communication request it’s still exactly the same you know request response Arrow function in here we can console.log this one was for data except now what I would do is I would send back I would res do send my data now for the minute I actually don’t have any data so what I’m going to do is just up here I’m going to Define some data going to say uh let data equal an object and that object is going to have uh you know a name that is equal to James so this is our object this is our data so now we have a backend server that serves up some HTML code when people will type in those URLs what we now also have is a means for letting someone get data now the question at this point becomes you know we’ve established that this endpoint here it’s a get request they want to get data but it’s not really a website that they’re getting so it doesn’t make sense that they would type it into a URL or a navbar is to this particular route how do we go about testing this you know what what do we actually do and this is where a tool known as a client emulator becomes extremely helpful so what we’re going to do is we are going to come over to the extensions tab right here and we’re going to look up a uh an extension called the rest client now it’s the top one right up here it’s uh by [Music] haow Ma it’s got over 5 million installations it’s absolutely brilliant and you just want to hit install on that extension and once we have that extension installed within our chapter two folder we’re going to create a new file and this one is going to be called test. rest or also client is uh valid as well but we’re going with rest rest is the extension that we’ll need now what this file allows us to do is emulate the process of sending out a network request so basically emulates a browser or a user for example in here we separate all the uh template Network requests we want to send out using the triple pound and the first one you know I can actually give this one a title this is going to be to test get uh homepage website and now to actually write the code in here what I would do is I’d specify it to get request and I’m sending it to http sl/ Local Host 8383 which is the URL now we can see that if I save that we get this tiny little send request button up here and if I click on that it emulates that whole functionality of us typing in the URL here except instead of displaying the HTML code as a website in the browser we can inspect literally what the response is which is the HTML code we can see that it was a 200 level response we can see it was powered by Express we can see that we get back HTML code and that was a successful request now I can do the exact same for test get SL dashboard uh website and then here I’ll just type uh get HTTP localhost 83 83 we give the address then we give the route which is the dashboard and we have defined this endpoint so that’s all good I had send it sends that request we can see it took 7 milliseconds down here and we now get back that HTML code for the dashboard and obviously these are our website uh endpoints that we’re testing here but I can also do it for a data end point so what I could do is I could use the get method the get verb and go HTTP localhost 8383 apiata which is our most recent endpoint that we’ve added and now let’s say I wanted to test that you know a user comes onto our website we need to ensure that they can fetch all of the job postings for our job board so we run this network request it has that endpoint and now we can see we get back Json data and we also console this one was for data and so this is a client emulator it sent out a network request from this client it hit our server our server directed it to this specific endpoint it interpreted the method of the request
which is to get information it located it or navigated it to this particular route we ran this console and we responded with the data so that’s super cool it’s a different kind of endpoint it doesn’t really show up a website it’s not something you would typically type in a URL even though technically you could you know in here I can go API SL dat and it will show me the data which is Json but that is not a website so that’s just another endpoint that we have officially configured so now that we have these three end points it’s time we start looking at some of different HTTP verbs or methods now at the end of the day most of these methods all come under the umbrella term of crud actions so if we take a look at the term crud I’m actually going to write it in here crud crud stands for create read update and delete now if we think about you know these are the four actions that basically control all of data modification the read is get that’s obviously associated with a get request so to read information is to get information if we want to create the HTTP verb that’s associated with is called post you post a parcel to someone else and it creates that package in their hand if we wanted to update information we use a put because we put something in the place of something that was already existing we create that place for it with a post request and then we put something there with a put request and a delete request or the delete functionality is literally associated with the delete method so in here what this is actually doing is we have uh the method and the crud action so the method is on the left and the crud action is on the right and I actually got that around the wrong way uh it’s the crud action on the left and the method on the right so that’s pretty cool now what we’re going to do is really take this application to the next level by literally creating something that is going to display our data so in here what I’m going to do is for our homepage which we have right here I’m going to turn this into a template literal string and that’s going to allow us to inject some data so this is our template literal string I’m going to enter it onto a new line which we can do with template literal strings and we know that HTML code needs a body that’s where all the visible part of the website the visible HTML code goes within the body tags within the body opening and closing tags and in here what I’m going to do is create a paragraph opening and closing tag and within that I’m going to use the dollar sign curly braces and I’m going to Json do stringify our data so this is going to inject our data into this template literal string and send it over as the HTML code so now if I refresh this page and hit enter we can see now we get back the Json code for our data and I’m going to actually uh throw an H1 tag above that and that’s just going to be called Data uh and I’m actually going to give this a style tag the body of style tag and that’s going to be equal to background pink color uh blue that’s going to look shocking so now if I save and refresh that we can see we have a website and we have our data so that’s kind of fun we added the style tags we sent back the HTML code someone loaded the website and that’s how every website you ever go to on the internet actually works so that’s super cool now you know let’s get creative how do we actually add modify data all of that kind of stuff well that’s where we get to these funky API endpoints and that’s where we’re also going to use our client emulator so what I’m going to do in here is I’m going to create an endpoint that allows someone to add data so in this case I’m going to use the new method we talked about here which is to post so I’m going to expect that someone’s going to post some data and I’m going to ensure that it is sent to the apiata route because these are all the routes that are responsible for handling that data and and here once again I’m going to define the uh function to handle the incoming request when it hits this endpoint so that’s a request and a response as arguments and in here what I’m going to do if someone is actually sending information instead of just asking for information I actually need to take a second to investigate what they’re actually sending me which we haven’t had to do before now fortunately that’s very easy to do with Express with Express typically when people send information there’s a number of ways they can send information but most commonly it’s as Json it’s formatted as Json and so what I can do here is Define a variable called const new data or new entry and set that equal to I can access the request which is the incoming request and I can look for the body of the request now the body of the request is literally the data associated with that request and typically when you have uh the create and post methods and the update input and occasionally the deletes you can typically expect there to be a b associated with that request instead of just you know a request for information which would be um more related to the read or get request so because in this case someone wants to actually create a user wants to create a user uh let’s say for example when they click a sign up button what would happen is the user clicks the sign up button after after entering their credentials and their browser is wired up to send out a network request to the server to handle that action and that’s what this endpoint is for so let’s actually take a second to go ahead and program that from within our client emulator so here we have our get endpoint we need a new one we’re going to use the triple pound and we’re going to say data end point for adding a user now in this case as we saw inside of the server that is a post request cuz we’re creating a user so we specify the verb and now we still need the URL including the route where that request gets you know directed to when it reaches our server so this obviously locates the server with the domain and the IP address and and then this route locates specifically the endpoint within the server that contains the logic needed to handle this request now since we’re actually posting information we need to Define that information and so what we’re going to do is create a Json object just here you need to have an empty space uh Above This object for formatting and I’m going to have a name and that is going to be um gilgames because why not let’s support gilgames so that is the data formatted as Json that we want to send now when we’re sending data the one last thing we want to do is configure a parameter of the network request which is known as the content type and we just set that to application Json and that means when our server receives this request from our client emulator it knows that it’s looking for Json and it can cons consquently pass that body and you know interpret that Json and gain access to this value so now we have a post end point where we can access the body we currently haven’t defined how we want to respond to it but let’s just go ahead and send this request from our client emulator and you have to remember that this would be equivalent to you know if they had a website where it’s like submit a new account add a user add a to-do their click the button and this is what happens so we send out their request and we see that it’s just waiting indefinitely now there’s a few things to note first up that uh we’re not getting a response and that’s because we haven’t basically told this endpoint how to respond when it receives this request so that’s what we’re going to do next so I just went ahead and cancelled that request and we got nothing back now to respond respond this is where we would send the status code of 201 which if you recall was associated with the created you know outcome a user was created or added so that would be a perfect response to that so let’s go ahead and send that request and this time we get back at 2011 which says that we have created a new user so that’s pretty cool now what we’re also going to do before we respond is we’re actually going to console.log this new entry restart that and I’m going to go ahead and send this request again and we can see that even though we tried to console.log the body of the request the request. body we get undefined and that’s because up here where we configure our server there’s one last thing we have to do so I’m going to create a section in here called middleware and we just have to tell our app to use express. Json and we invoke the Json method now middleware is part of configuring your server and basically it’s configuration that you slam in between uh the incoming request and interpreting that request so request hits your server this is like a protective layer on the like a middle in between these interactions so it’s just before we actually hit these end points and this line just basically configures our server to expect Json data as an incoming request so now that we’ve added this line right here we’re telling our app that it needs to use this express. Json expect to receive this Json data now when I send that request we can see that we actually logged out the new data and we consequently our server responded to the client emulator and we got a successful Response Code now the one last thing I want to do here is actually add the data so what I’m going to do is reformat it and I’m just going to create a users field and it’s going to be an array and that’s just going to have the entry James and to be fair what I could do is uh get rid of a lot of this and just literally make it an array with the name James so now when I refresh the page we can see we get the array back James that’s the data rendered onto the screen now what I want to do is add a user so we come down to this particular endpoint where we handling this data it’s an API endpoint it’s not for rendering a website and we’re just going to say data. push and we’re going to push the uh new user here we can see that we have to access the name parameter within the new entry so we push the new entry. name field because that’s what we want gain access to that’s an object the request. body is an object uh and we access the name key within that object we push it to our data array and then we confirm that we have created that new entry so now when I save that if I refresh the page we get our singular entry inside of this array rendered as our website and now we come over to our client emulator we emulate the process of adding a new user by sending this request gilgames has been added we have confirmed that we have added gilgames and now when I refresh this page we can see that gilgames has been added to this list so that’s absolutely Wicked we can see now that you know we’re really developing a full stack interaction where we have a client where we can actually visually see all of these backend interactions that are just going on by telling our server to listen to these incom requests and defining end points that handle all sorts of different you know behaviors expectations and intentions of these requests now a big server might have a 100 different end points all for different things uh but at its very core all you’re doing is creating different destinations where each route and each verb together create the end point where each endpoint has you know a specific utility so that’s pretty cool you know if we just wanted to take this one last step we could say app. delete uh we specify the route which is/ API endpoint and we Define the arrow function to be executed when we receive an incoming request to this endpoint we give it the request and the response as arguments and in here what we do is we just say uh data. pop we’re going to to pop an entry off the end of that element we could also throw in a console.log just saying we uh we deleted I can’t remember if it pop is off the end I think it’s off the end so we’re going to say we deleted the element off the end of the array and then we just res. send the status code of 2003 for example I’m sure there’s one that’s associated with a successful delete but I’m not not sure what it is in this moment so what we could do now is emulate that request I could literally just copy and paste this code right here actually I’m not even going to do that I’m just going to create a new one so I’m going to use the triple pound and say delete endpoint uh and that’s going to be a delete request to the HTTP SL localhost SL API slata and we have to throw the port in here so that’s 8383 and then very simply I can go ahead and execute this request in this case this request does not need to contain any data because it’s not specific to an entry it just literally gets rid of the entry off the end of the uh array run that request oh and we got a 404 which means that that cannot be found and that’s because I specified the route incorrectly so here you can see that we are looking for a slash data whereas I’ve configured it for/ endpoint cuz I’m a muppet so let’s now change that to API sdata save that file reexecute that request and we get back at 203 which is definitely the wrong Response Code for this action but we have confirmed on our server side that we did in fact hit that end point and now if I refresh the page we actually got rid of both entries let’s go ahead and restart this once more that’s going to refresh everything so now we have James then we’re going to uh add an entry send that request that’s a user created now we have a new user and then we pop a value off the end of data so let’s go emulate that behavior a user clicks delete and a website it’s the same thing we’re just emulating it we delete an entry and then we refresh the page and now it’s worked appropriately so now we only have one entry on the end of our array and just like that you can really start to see our backend application coming along now the one last thing I want to do in here to really just make this feel a little bit more like a website is throw in some anchor tags that have an hre this anchor tag is going to have an hre to the/ dashboard route and that’s going to have the text dashboard and then we have to close that anchor tag and then within the dashboard I want to do the exact same thing uh so this is going to have the H1 we have to put that inside of a body tag so I’m going to change that from a quote to a template literal string throw the dashboard down on a new line put it within the body tag so let’s create the opening and closing body tag into that onto a new line just do some text formatting really quickly throw that up there and then throw in an anchor tag just here that takes a user back to the homepage and that’s just going to say home and just with these extra lines of code so on the homepage I’ve added a link to the dashboard page and on the dashboard page I’ve added a link home if I save that and refresh this page now we get that link I can click it it routes us to the dashboard page we render that HTML code and that’s going to take us home so that is really cool and you could absolutely take this to the moon for example I could add a button in here where the button actually adds a new user and instead of having to emulate that functionality that could actually be done within that HTML code I could also throw in a script in here you know I can throw in a script close the script consequently and that’s going to say console.log this is my script and now you know let’s say up here I throw in a cons cons. log user requested the homepage uh website now if I save this back in server and refresh the page we can see that on the back end we received an incoming request to this endpoint where a user is requesting the homepage website and we can see that we responded with the HTML code which I just cannot find where what if I close that there it is there’s the HTML code and then in the console we executed that script which is so cool because that was just sent back as text but our browser interpreted the HTML it executed the script and Bob’s your uncle which is absolutely Wicked now the one last thing I want to do just to demonstrate a small concept before we jump into the next project which actually looks reasonable obviously this is a whole hodg podge of stuff that doesn’t look very attractive but it demonstrates a lot of important Concepts is I just want to show you an extra feature that we can kind of amend to this response right here and essentially what we can do is we can throw in a custom status code in front of the do send and in here you know we can we can specify the status code that we want so if I did like a 500 or 599 that wouldn’t make any sense but now if I come back to that get request for for that endpoint and send that we can see that we’ve also specified that status code in addition to getting back the data and then just from within here you know I can add a new user I can rquest the data and the data has been updated and it’s super cool because this little object right here has basically been a database for us it’s obviously a very simplified version of what you’d typically find in production level environment but you know for all intents and purposes this has been a great little database that’s storing users we can access new users and all of this can just be scaled to the Moon based off the same Core Concepts so anyway that’s it for chapter 2 this is our very introductory project just to once again demonstrate how we can actually build a functional server and do some of the core things that we talked about inside of our Theory lesson it obviously doesn’t look great but that’s what chapter 3 and chapter 4 are all about they are absolutely brilliant projects they’re super exciting and it’s time that we absolutely dive into them all right we just wrapped up project number one in Chapter 2 of this back in full course it is now time for us to jump into the second project which is Chapter 3 of this back in full course now this is a really cool project we’re going to be using node.js as we did in the first example to develop our web server we’re also going to learn how we can take advantage of what are currently known as experimental features within node one specifically is the sqlite database now if you’re unfamiliar with sqlite basically it’s just a very lightweight SQL database that is very popular very common place and very easy to get up and running with and it’s now built into the latest version of node which we are going to unlock by utilizing the most recent experimental versions of node via something known as node version manager now the backend application itself that we’ll be building in this course is going to take a lot of the beginner Concepts we learned in the first project in Chapter 2 and really just extend upon them by ultimately just building out a more comprehensive backend application we’re also going to learn how we can tidy up our project directory really develop a project directory that is going to set us up for success as our projects become more complex so it should be loads of fun and the first thing on our list is to upgrade our version of node now when you download node you probably selected a version to download and we can check what that version is by typing in the node DV command in our terminal now this is just the exact same terminal we were using inside of uh chapter 2 in our last project and we can see that the node version I’m using in here is version 20.10.19 to set the minimum version we’re going to need to use these tools if these features are available in the standard node.js version then you won’t have to add any of the experimental Flags but we’ll see what that’s all about shortly but yeah should be absolutely loads of fun now to kick off this process the first thing we’re going to do is get NVM node version manager up and running on our device now to do so what I’ve done is I’ve linked node version manager in the description down below and this tells you exactly how to configure it it might look a little bit overwhelming but at its very core all you have to do is come down to the installing and updating section which we can see right here here’s the install and update and when you see this curl command you just need to copy it and paste it into a terminal instance for example the one that we have open right here so I could literally paste that command and that should theoretically install no version manager on our device once it’s installed you can check that it’s installed uh using the NVM DV command so just in here if I type in NVM DV that will tell me what version of node version manager is installed on our device and if that command’s not working for you then there’s been an issue in your installation and all of that should be covered in this guide how to basically get it up and running once again this is linked in the description down below and if you have any challenges or the documentation isn’t very clear you’re welcome to once again post them as an issue on the GitHub repo for this back and full course which is also linked in the description down below and either myself or someone else can help you overcome that hurdle lastly chat GPT can actually be pretty good at helping you get these installations up and running as well but ultimately should just be copy and PAs in this one line and then you should be able to just type the NVM – V command and that should all be good to go now once nbm is installed on your device it’s so incredibly easy to use here are some examples of the commands basically all you have to do is type NVM install or NVM use that particular node version so in the case of our project the node version we’re wanting to use is is I believe it’s 22 but once again you can use 22 or later so what we’re going to do here is we’re going to type envm install and then we’re just going to type in the version that we want to install which is going to be 22 once again if you have a version that is more recent which would result in it being a higher number then you really don’t have to worry about this part this is just if we have an older version or if you’re watching this tutorial at the time of release so if we hit install that’s going to go ahead and download the version of node that we will need for this tutorial essentially to take advantage of some of the more experimental features so now that that is installed on our computer we can just type NVM use 202 and that’s going to set us up to use that version of node now the next thing we have to do obviously we can close chapter 2 and we’re going to create a new folder which is just going to be chapter3 it’s our chapter 3 project now in here what we’re going to do is absolutely nothing cuz it’s all going to begin within our terminal I’m just going to type the clear command that’s going to clear out the terminal currently we are in the chapter 2 directory from the previous project we need to change that so first what we need to do is go up a directory level so from the chapter 2 directory to to the backend full course level and we can do that by typing the change directory or CD command and then using the double period that’s going to jump us up a level so now you can see we’re within the backend full course directory and from within here we can change directory into the chapter 3 folder and now we can go ahead and initialize our node backend project now if you remember from chapter 2 the way that we did that is by typing npm in it and then the dashy flag and if we hit enter on that command that once again creates this magical package.json file which is the specs file for our project so if I click on that once again we have a pretty rudimentary package.json file and that’s how we initialize a backend project using node.js that allows us to leverage the npm node package manager ecosystem as we learned a little bit about in Chapter 2 so now that we have this package.json file the next thing we’re going to do is actually set up our folder directories and just finish the configuration of our project so that we can then get our hands dirty with all of the code now the first thing I’m going to do is within the chapter 3 folder directory I’m going to create a file called server. javascript. JS the JavaScript file extension and hit enter on that just like we did in Chapter 2 very similar and now that we have these two files we can go ahead and set up some folder directories that are going to be used for their own sub files which is just going to help keep our code a whole lot cleaner than the example in Chapter 2 so the folders we’re going to need for this project number one is called middleware now if you remember inside of chapter 2 we only had a very brief look at middleware right here middleware exists in a lot of different shapes and forms we’re going to have some middle Weare in this chapter 3 project that is all about authenticating a user so that’s going to be super cool so we need a folder where inside that folder we can keep the files that maintain that code now the second folder we’re going to need inside of chapter 3 is called routes now obviously once again in chapter 2 we had all of our routes set up inside this file but you can see how it’s already getting kind of long and that’s not really ideal if you want to have you know a best practice implementation of a server side application so in this case what we’re going to do is we’re going to move all of our logic that sets up how all the different endpoints work into this folder called routes now after that we need another file and this one is going to be a new file in the chapter 3 directory Factory that’s called db. JS now this file is going to have all of the logic for the database which is going to be sqlite which is just a SQL database where SQL stands for structured query language and it has to be the most popular type of database used globally there’s a lot of different examples of SQL databases in this case we’re using SQL light another common one is my SQL and then there’s also postgress SQL which will be using in chapter 4 that’s going to be loads of fun but essentially this db. Javascript file is where we’re going to have all the code to configure our extra special database and then we’re going to need another folder this folder is going to be called public we’ll learn all about what the public folder is for very shortly uh and then last but not least we’re going to need two more files one is going to be another rest file which is used for for emulating the browser so that’s going to be called Todo app. rest just like that we’ll create that file and then lucky last is going to be one called Dov now EnV files are for environment variables and if you’re unfamiliar with what an environment variable is it’s essentially just a storage of keys and values the key is the lookup term and the value is potentially a secret uh string of characters that needs to be referenced for the configuration of our project so any top secret information is going to be thrown in this EnV file and that way we can avoid uploading it for example to GitHub it can stay local on our device and that means we don’t end up in a situation where we accidentally share all of our secret passwords with the world now we’ll learn more about how the EMV file Works shortly but first we’re just going to finish up with the configuration of the files for this chapter another folder that we need to create is going to be called Source now SRC stands for source and I actually made a little oopsy here all of this code that we have created so far with exception to the EnV file and the Todo app. rest needs to go inside of the source code so our server. j s is going to go into the source I’m going to drag that in there the database. JS goes into the source and then the middleware folder goes into the source and so does the routes folder so if we close the source directory we should only have the package.json the EnV and the rest file in addition to the public folder as direct Children of the chapter 3 directory within the Source folder we have this middleware folder we have a routes folder and we have the database. JS and the server.js now once again just a reminder that at any point you can compare your code to mine via the GitHub repo the link to the GitHub repo is available in the description down below and if you do go and check it out if you could star the repo love that support that would be super appreciated now we’re almost done setting up the folder directories the last things we have to do is create the files to go Within These folders now within the middleware we just have one file called orth aut middleware do JavaScript this is where we’re going to write all the JavaScript to handle the middleware and for the routes as you learned in the previous tutorial in Chapter 2 we had two kinds of routes we had API routes and then we had website routes well there can actually be you know a pleora of different types of routes and consequently API endpoints and so we’re just going to subdivide them in this project to orth routes. JavaScript and finally to do routes. JavaScript now in this project we’re going to create a full stack application from a backend application where we serve up a website where the website is essentially an authenticated protected uh to-do application looks absolutely excellent and we’ll see how we can get that up and running shortly but the two types of backend endpoints we’ll need will actually three we’ll need one to serve up our website we’ll need some logic or end points to handle all of the authentication and then we’ll need some logic or endpoints to handle all of the crud operations where we’re creating reading updating and deleting different to-dos in our to-do list and so that’s what these files are for we’re just going to have all of our auth indication routes in here and all of our to-do routes in here and with all of those files now created that is our project configuration 99% complete we’re not going to do the 1% just yet but essentially just to summarize what we’ve done within chapter 3 we have created two folders one is called public and one is called Source we also initialize this package.json via the terminal using the npm in n-y command that is the project specification for our chapter 3 project and we also defined a file a rest file which takes advantage of the uh rest client vs code extension and this file is going to be where we can emulate some browser network requests emulate the client so that’s going to be handy for when we test our endpoints later now for now the public directory is empty we’ll change that shortly and within the source directory the source code if you’re familiar with that expression the source code is basically all the code that creates our application and that is within the source folder now directly within that folder we have two files two JavaScript files one is the server that’s going to be the Hub of our application and the database. JS is going to be for all the database configuration logic and then finally we have two folders one is called middleware we’re going to learn all about the middleware very shortly but it’s essentially what it’s going to do is just handle all of the authentication between the client and the server side between the front end and the back end and that logic is going to go within the or middleware do JavaScript and finally we have two routes folders which is just going to separate all the logic out for the different types of API endpoints that we will need for this application now don’t stress if that’s a lot of information as we work with these files will all become very comfortable and familiar to you especially as we jump into chapter 4 it’s just the same thing but slightly more advanced once again but do make sure that you have configured this folder directory properly because that will be important for linking between different files as we code out this project so now that we’ve set up all the folder directories the next thing we need is to add in all of the npm packages we’re going to need for this project now the list is not actually that great but it’s not as small as it was in the first example for this project we’re going to need to install the Express package so we’re going to use the npm install Express command once again however in this case we have a couple of other packages that we want to throw in so we’re going to type them all in the one line so here we have mpm install Express that’s package number one the next one we’re going to need is called bcrypt JS just like that and that’s the library that is responsible for encrypting data specifically usernames and passwords and that is super important when you’re developing your own authentication system now in this project we use an authentication system known as JWT authentication or Json web token authentic a same thing as we get to that I’m going to explain very explicitly how that system works to create a very secure authentication system and consequently full stack application but for now all you need to know is that we will be needing a package called bt. JS specifically because we don’t want to have to write all the code to create these encryption algorithms now the last package we’ll need is called Json web token and that is once again just another package to facilitate our authentication system so now that I’ve typed out those three packages I’m going to hit enter and npm is going to add them to our project we can see that was super fast and now we have this node modules folder within the chapter 3 directory once again we’re not going to go touching any of those folders because someone else has coded them we’re just going to add them to our project so that we can Leverage that code if you wanted you could check out the documentation for all of these different packages to really understand how they work but I’m going to cover it all in this course anyway but we can also see that these packages have been added to our dependencies list within our project specs which is the package.json file now within here I’m just going to change the description of this uh project this is going to be a full stack uh to-do application that us uses a nodejs backend a seq light database and JWT authentication so that’s pretty cool and now with those packages installed you might remember in chapter 2 we installed a developer dependency called nodon well we actually don’t need that in this project because one of the experimental features that is available in the later versions of node.js is A system that essentially does the same thing automatically reboots our server when we save or create adjustments to the code base so that’s super exciting now with all of that done the last thing we need to do to boot up our application is create a script that defines exactly how npm or node package manager should start up our application now I’m going to call this the dev script and here needs a comma at the end it’s within the scripts field and essentially how this is going to work is it’s going to be node space and then we’re going to use some Flags now the first flag we’re going to need is en mv- file is equal Tov now historically to add EnV files or use environment variables which are the secret protected Keys within a noj application you used to need a package called EnV now within the later versions of node it’s built in and this is how we tell node where to look for our environment variables inside of thatv file the second flag we’re going to need is D- experimental Das strip D types once again this process is specifically if you are only using no node version 22 which is the experimental version of node as node officially releases these features you will not necessarily need these flags you’ll probably need this one but you might not need the experimental flags and then after this experimental flag we need another one this one’s going to be experimental Das seq light as I said earlier if you’re using a more recent version of node at some time in the future sqlite will probably just be built into the official release and then last but not least we need to specify the file that we want node to run and that is going to be dot slash because we have to enter the source directory and then we want it to boot up the server. Javascript file now I actually forgot one flag in here the last flag is to uh tell it to emulate the feature that nodemon used to do which is automatically restarting everything and that’s just a d-at flag now with all of these flags and this whole command set up Suddenly you can really understand why it’s beneficial to have these scripts because instead of writing that out technically I could write this out in the terminal every single time but now if I save that package.json I can just run that script using this simple command every single time and you know we can just have the magic happen so technically we can go ahead and run that command and that is absolutely completed and our application is up and running but there’s nothing currently to run so I’m going to go ahead and kill that uh that’s pretty easy uh and now we can get to the actual code so the file we’re going to start off with is our server. JavaScript and if you recall in our previous project it only took about four lines to get us up and running with a server and the very first thing we did was we imported the Express package so in this case what I’m going to do is type const Express is equal to and then I’m going to use the require command and I’m going to require the Express package and that’s going to bring it into our application or at least that’s what we would have done in Chapter 2 in this project we’re going to look at a different way of importing files and folders into our uh basically application this is a more modern synx so in the newer versions of node it’s now best practice to instead of using the old require syntax instead we just use almost a more uh logical syntax where we just import Express from the Express package so this is a slightly different syntax and this is actually one of the criticisms of node.js is that they jump between these different importing syntaxes and it’s a whole can of worms that I’m not really going to open up right here but the moral of the story is that for this project we’re going to use this slightly different importing sent TX it’s my personal preference I think it’s much easier to work with but to configure our uh node.js application to work with this new syntax we need to come to the spec file and make sure that there’s a little line inside of the spec file that basically configures our application to use this new syntax so underneath the main line right here within our package.json I’m just going to add a field that’s called type and the value associated with that is going to be called module now you might have noticed just there that there were two options actually come up one was called module and one was called commonjs commonjs is for the uh previous syntax that we were using that’s the default value if you want to use the modular syntax then you just have to specify this line right here if we save that then we’re all good to use that newer uh import syntax throughout our project so now that we’ve imported that package we can go ahead and do what we always did which was Define our app and invoke Express that’s pretty straightforward we’re going to need a port so I can define a port just here const Port is equal to and in this one I’m going to use 5,000 we’ll do something a little bit differently and the other thing I’m going to do just here is actually set the 5,000 as a backup because what I want to do is provide a value from the environment variables instead if it exists now when we Define variables Within These EnV files and we’ll see how we can do that later we can read them into our application by typing in process.env and then accessing the name of the environment variable which will be port and once again we’ll see how we can configure that shortly but essentially what this slightly improved syntax does is it just checks if there’s a port environment variable if there is we use that if there isn’t then we default to 5,000 and then lucky last we just tell our app to listen app. listen at the port and then we pass in a function to be executed if our uh server boots up adequately and so that’ll just be an arrow function where we can console.log a template literal string that just says server has started on Port semicolon dollar sign curly braces and we can inject the port just there so that’s our few lines to create the boiler plate code needed to build our entire server now with that done I can save that file and run the npm Run Dev commands and that is going to fail to boot up our application and that’s because that Port is already in use so I must have something running on my device at that Port so I’m going to change it to 5003 I would expect that that would have worked for you if it has then that’s totally sweet let me just change that backup port and now we can see that our server has started on Port 503 and we can test that that watch flag is working because if I say console.log hello world just throw that in there and save that file we can see that our server automatically restarts due to that watch flag and we print out hello world and just like that we have done everything we need to set up a more modern project directory it’s going to make it much easier to develop a more sophisticated back-end application we’ve created the code we need to configure the beginnings of our server side application and from here we can really start to flesh out all of the end points and all of the features and functionalities of our backend application starting off with serving a front end now currently as with the previous project we have started up a server on our local network at our local host on Port 50003 so you know let’s expect we can come across to our browser and look at Local Host 5003 or if you’re using Port 5000 it will be Port 5000 and just like with chapter 2 when I hit enter we get a cannot get it’s a 404 which means that the browser sent out the network request to that address and it potentially may have got there but we didn’t handle that incoming request there was no endpoint that had method get at this particular route to receive that request and consequently respond in this case with what we would expect to be a website so that’s going to be step number one is sending back a website we need to send back a front end that a user can interact with to have a full stack experience and that’s going to be our Authentication protected to-do list so that’s step one let’s send back a website now the question becomes where’s the website well I’ve got you covered I built the website in advance so the front end is completely developed all of the logic is available there I’m going to copy it across to this public directory right here within chapter 3 now for you you will need to go over to the GitHub code which is linked in the description down below check out chap three and copy across the files within the public directory and while you’re there if you could star the repo love that support that would be super appreciated so just here I’m going to copy across the three files into this public directory so there’s a fan. CSS an index.html and a styles.css now Fanta CSS is just my little uh child it’s like a design Library so that just Styles everything styles.css is is all of the layout Styles so not so much of the prettiness of the application but the functional layouts and then the index.html is just some HTML code with some scripts and uh JavaScript at the bottom to handle all of the different uh crud actions and all that good stuff so that’s super important if you want you can totally go through and have a look at the code there’s a little bit of it but at the same time there’s not an infinite amount uh I’ve commented out a lot of it so it should be uh pretty self-explained but once again you know this is a backend full course and the front end comes pre-completed so you just need to copy these files across now as for why we’re copying them into a public directory well the public directory is the canonical folder from within which we serve up everything any assets from our uh for our project so in this case we need to serve up a front-end application and consequently here is our front-end applic so now what we have to do is actually take this you know these files and when we get this network request we need to send them all back across to the browser and then the browser receives the CSS sheets and the HTML and loads that website now that should be relatively straightforward and most of that logic is going to go within our server. JavaScript now what I’m going to do is start off by getting rid of that little console log that’s going to re booot our server and the first thing we need to do is Define this endpoint the end destination for this network request that our browser emits when we go to the URL which when you deploy the application could be you know to-do app.com or whatever it might be so as we saw in the previous uh chapter defining that particular endpoint is actually pretty easy so we can see that the method or verb is a get so we type app we access our server app and we use the get method to Define that endpoint the next thing we need to provide as an argument to the get method is obviously the route and here we can see the route is the slash route so we’re just going to have the slash route and then the second argument is the call back function that’s going to be an arrow function and that receives the request and the response as arguments and now I can open that up onto a new line now we saw in the previous chapter how we can send back some code how we can send back status codes all that good stuff if we want to send some files like we do in this instance we want to send back the index.html and all that good stuff we need to res. send file now in here we need a little bit of code to basically determine or locate the files that we need to send so this might be a little bit complicated but we need to take advant vage of a JavaScript module known as path now we need to import path into our project that’s step number one and that’s native to express so we just import path from the module called path now there’s something else we have to import from this uh path module so what we’re going to do is after this path we’re going to throw in a comma and we need to destructure out this particular input so we’re going to use the curly parenthesis just here and the the uh the item we need to import is called directory name or dur name so that also needs to be imported and while we’re up here there’s one other import we need that’s also native to JavaScript so we’re just going to import and this one also needs to be destructured and it’s going to be file URL to path from a module called URL so that is super cool so these are the two Imports we need and they’re going to enable our Javascript server.js file to look for the HTML files and consequently send them back as a response so we’ve got those Imports now the next thing we have to do is just above this endpoint we need to get the file path from the URL of the current module now that’s a slightly confusing sentence but essentially it’s just a configuration line to allow us to navigate the folder directory that we have just here from within our code so we need to Define a variable called underscore uncore file name and that’s going to be equal to and we’re going to call the file URL to path and then as an argument we’re just passing uh import met. URL so that’s going to give us access to the file name and then underneath that we need to get the directory name from the file path and that’s going to basically tell our operating system okay this is the directory where the files can be found so we need a variable just in here called const and this is the double underscore once again and that’s called directory name and that’s equal to and we’re going to invoke dur name which we um imported above and we’re going to pass in the double uncore file name now this is going to come in handy in a number of places and we’ll see uh all about that just shortly but the first thing we have to do is we have to send this file and what path does all of this ultimately comes down to allowing our code to uh locate files and folders on our device or whatever device it’s running on so path allows us to construct the ultimate path to find these files and folders and so in this case this endpoint is for serving up the HTML file from the slash public directory and so this path we’re going to join the underscore directory name which is basically the directory of our project and onto that we’re going to throw the public directory and then we’re going to throw the index.html which is specifically the file name so this code essentially isolates our directory and then what we do is we join together the current directory and I think I’ve got one too many underscores right there there should only be two so I’ll just get rid of one of them two underscores it joins together the directory with the public folder and consequently the file and that’s how our body of code knows to find that file that it can then send back across the network and that’s literally all we need to do to send back the HTML file so if I now go ahead and save that our server restarts and I can refresh this page and loading that website gives us one error and we can see here this is the ultimately resolved path name and we can see that the issue is that it’s looking for the public folder within the source directory so there’s one last line we need to add and this is known as middleware which we kind of saw earlier and it’s just a bit of configuration and so we need to tell it exactly where the public directory is cuz currently it thinks that the public directory is in the same level directory as the server.js but it’s actually one above so we’re going to basically uh add a line that serves the HTML file from thepublic directory and also tells Express to serve all files from the public folder as static files so that’s what I was talking about the assets the static assets SL files now this is important because uh any requests for the CSS files will be resolved to the public directory and we’ll see exactly how that Works in just a second so we need to throw one little line in here it’s just a little bit of middle Weare it’s part of configuration for our app so we just say app.use and in this case we use an Express method so we access Express and we tell it to use the static method and basically this is saying okay where do we serve the static content from well it’s from the public directory so we call Path We join once again to create the ultimate path or the the absolute path for the public directory and we just go from theore directory name again and onto it we add the double dot /pu directory so that basically says okay you can find the public directory but it’s actually not within the source directory it’s one up and that’s why we have the double dot because that’s how we go up a level of folders so if I now go ahead and save that once again and refresh the page we can see now we actually get back the website so this is the endpoint that literally serves back the file and this is a configuration line that basically says you can find the public directory not quite where we are right now but if you go up one level that’s where it’ll be from so the express. static line basically is used to tell our code where to find the public directory and the public directory is what serves up all of our assets so that’s really cool we’ve literally actually sent back a website where in the previous chapter we just sent back some HTML code written as a string now one thing we’ll note if we right click and inspect and then come across to the network tab we can see that when I hit enter a bunch of requests are sent first is the local host and this sends back the HTML file which itself doesn’t have any Styles it’s not a styled file and so here you can see the styled equivalent of this web page and that set back is all this HTML code however at the top we have these links now when there’s a link essentially what happens is the browser goes out and fetches the information at that link so we can see there’s a SL Styles and a slant. CSS sheet so it consequently our browser went out and sent those requests out fetching the CSS files so here we have this styles.css sheet and that’s the URL at when to fetch it from and because of this line our app knows to serve up these files from our public directory and so that’s what it got back it previewed it got back all the CSS and then it could apply it and it did exactly the same for the fan. CSS sheet here and consequently we load a styled application this is the authentication page it’s super responsive looks pretty nice and neat so that’s hunky dory we now have a website a front end being served up from our backend code now the front end is super cool because when we can later authenticate it’s wired up to send out all sorts of network requests for all sorts of different interactions logging in registering a new user create read update and delete different to-dos and all that good stuff and that will just allow our browser to send out all of those Network requests that will reach the different endpoints that will’ll code throughout this tutorial that are going to go in these routes just here but this this code just for sending up this home website is uh definitely some code that we can have within our server.js now the one other line I want to add before we move on to some of these other endpoints or these routes is just one that allows our server to receive Json information when it receives Network requests that have the method of post or put potentially if you recall that’s something we did in Chapter 2 to enable our endpoints to actually interpret that Json data which could be a username it could be a to-do or anything so whenever the client is actually sending information instead of just asking for something via a get request and that’s just one other line of middleware so this is going to be the middle Weare right here this app.use and we’re just going to add one other line of middleware and that’s just going to be called app.use Express Json so that basically just configures our app to expect Json and consequently enables it to pass or interpret that information so we’re just going to throw that in there as well and I’m actually just going to move that up uh directly under the middle Weare line above this other one because this is uh specific to this line here now once again if you’re wondering how I magically mve that line around I’ve got a link to all of the vs code shortcuts that I use in the description down below there’s a website I made that uh basically tells you all about them and just like that we’re almost done with our server.js most of the code that we’re going to write from here is going to be within all these other routes so now that we’ve just about done all the logic for our server the next file I wanted to get started on is the database because we’re going to need our database up and running if we want to do any authentication if we want to have any data storage and we can get started on that by heading into the db.jpg package and the way that we do that is we import and we need to destructure out this particular import and it’s called database sync so it’s a synchronous database and we import that from node uh semicolon from the sqlite package once we have that imported we can go ahead and just like we created our app with Express we create a database by creating a variable called DB and setting it equal to and we have a new synchronous database and in here we pass in a string and that string as you can see just here in the documentation is going to be an inmemory database and so that means we don’t have to manage any external files and so we’re just going to have the semicolon and type memory now this isn’t what you would use for a production database we’ll see how we can configure that in the last project in chapter 4 but if you just want to get up and running with a SQL database then we’re just going to use memory for that and that will be more than adequate so now that we have our database the next thing we need to do is basically set up our database when we boot up our applic a now for that we need to execute uh some SQL statements from strings now the way that SQL works or structured query language is it’s you can almost think about it as an Excel spreadsheet where you have different columns and different tables where a table is kind of like an Excel sheet so you can have different sheets for managing different data now unfortunately when we first create our database none of these sheets exist or none of these tables exist the table is the literal term for it so in this case we’re going to have two different tables where each table is like a sheet one sheet is or one table is going to handle our users and then the other is going to handle all of the to-dos and for every to-do it’s going to associate them with a user now to actually make this happen within the database we write command using the SQL language and using this node package we can get our JavaScript to execute these commands and configure our database so what we’re going to do is we use the database do ex uh execute method that’s going to execute a SQL command and act it upon our uh database now that takes a template literal string as that’s going to allow us to uh write some um strings across different lines now the SQL command to create a table where once again we need two tables where each table manages different data one table is specifically for users and once again you can just think of that as like a tab as a tab as a tabular database like an Excel spreadsheet we need to actually create it so we create a table called users just like that now after we create the table we need to specify some of the different columns in our table so we have these circular parentheses and we’re going to enter the circular parentheses on some new lines now in here we enter the different columns and we specify what kind of data type they’re going to be in addition to some other information so the first field is going to be an ID now the ID is going to be of type integer so that by itself is pretty straightforward after that we’re going to have a comma and then on the next line we’re going to need the username and that’s going to be a text field and it has to be unique so we can throw the unique key onto it and then lastly we have a password field and that’s also going to be of type text so this SQL command right here is going to be executed upon our database and will configure that table so that our database is up and listing and it’s ready to accept the new users where each user has a username and a password and that gets save to the database now the second command we’re going to need is for our second table and that’s going to be for all of our to-dos so we’re going to have a database. execute and we want to execute a SQL command I’m going to open that onto a new line and this one’s going to be very similar we’re going to create another table which once again is just like a sheet and one is going to be called to-dos and then we’re going to have the circular braces where in here we’re going to specify the different columns it’s pretty straightforward the first one is also going to be a unique ID the ID is the best way for referencing different lists or different elements in the uh table and that is once again going to be an integer field then we have a comma for the next column the second one is going to be a user ID now this field is going to also be an integer field but more importantly it’s going to be the field that Associates it to do with a particular user so every user is going to have an ID right here and the user ID field is going to keep track of which user a to-do is for and that’s super important so that when someone authenticates they only receive to-dos that are specific to them now to create this level of community communication between tables we need to essentially uh configure a field to be what’s known as a primary key so what that means is that in this ID field here since I’m saying that the users table needs to be able to be referenced from other tables and we’re going to reference by the ID we need to set this key up to have superpowers and essentially create it as a primary key so we use the fields primary key right there and that’s going to set up this d as like a superpow key that can be referenced within other tables so such as the uh to-do table right here now the last element I just want to add onto this one is called Auto increment and that’s because when we create a user we’re not going to specify an ID we want it to be automatically assigned to the new user and we just want them to Auto increment so our first user is going to have the ID of one the second user is going to have an ID of two now now all of the SQL stuff will become more and more clear to you as we continue to use it and also as we actually look in the database as we create all of these interactions and finally in chapter 4 as we build out a more complex database and literally start interacting with it obviously in both of these applications using the application will save data to the database but there’s like basically uh hacker ways that you can overwrite it and work in the background and we’ll see how all of that works and it should be a really beneficial experience to help you understand exactly what’s going on but anyway the moral of the story what happened there is we have this user ID which Associates a to-do entry with a particular user but to allow that communication method we need to set up this ID to be a primary key so that it has superpowers so that we can reference it from within other tables so now we have this integer field and this one right here does not need to be a primary key because it just refers to this primary key however the ID of the to-do every to-do also has its own unique ID this actually also is going to be set up as a primary key and uh we’ll configure it so that it auto increments after the user ID filled we obviously have the task and that’s just going to be a text type uh and then we have a completed status which is going to be a Boolean yes or no so it’s either complete or it’s not complete and that’s going to track the status of it and that is going to have a default of zero which is going to be false so we’re going to use a numeric value to track the true or false state so zero is false one is going to be true and finally we have a foreign key which is going to be the user ID uh and that is just going to reference the users ID field so that’s obviously quite a few SQL commands once again this is a backend full course we’re definitely uh not giving SQL the attention it deserves the SQL ecosystem is incredibly you know
sophisticated and it’s you could spend 100 hours looking into it uh and becoming more and more competent with SQL but you know for now we just need to configure the tables and as I said earlier when we start going behind the scenes and modifying uh our SQL databases using SQL commands all of this will become much clearer and apparent to you but for now we just need to get them up and running so if we go ahead and save that that’s the code we need to create our two database tables set them up with some columns and give them the means to communicate and reference one another now the last thing we need to do from this file is export have a default export of DB and this line right here is going to allow us to interact with this database file this database variable from other folders and files such as from within our server such as our or routes our to-do routes and our middleware and as you can see it also allows us to keep a very tidy project directory because you know I’ve got 23 lines to configure an entire database which is super sleek and now I can you know quickly know where to reference that code it’s not all just jammed into one file uh everything is compartmentalized so what our database created it’s time we start setting up some endpoints to manage our authentication which is going to be step one of getting this front end working properly with our database and backend now just before we jump into our orth routs and the next section I noticed there’s one little error I made in this particular file so we’ve configured our database so that when we boot up our application it basically creates these tables where we can then save all of our data however when we reference between the two tables when we assign a user to a to-do or associate a to-do with a particular user we’re referencing the users table however we only named it user so that just needs to be pluralized and we can go and save that and that is now fixed so for the next step let’s actually come back to the application which is now being served up I refresh the page this is what loads and let’s try enter a user I like using test @gmail.com and I just do a password uh it’s a couple of digits and now let’s see what happens when I click submit having this network tab open so I click submit and I get an error showing up and if I look at the network tab we sent out a request to let’s take a look where let’s have a look at the headers section here we have the header it’s got the general information including the URL and this is the end point that we sent this network request out to from the client to the back end there’s a post request which means that it contains a payload and that’s got a username and password and that is specified as Json information and we did configure our server to pass that information with this line here we said to our server expect this Json information however even after having done that you know we got a 404 which basically said there was no response we didn’t hear anything back no idea what happened and that’s because we don’t have an endpoint set up for this particular route and that’s why we got the 404 so what we need to do now if we want to log in a user or let’s say I want to sign up instead let’s go and submit that to the registration endpoint we need to create both of these end points cuz right now we’re getting back 404s because they don’t exist we haven’t made them and they are the endpoints we’re going to be creating within this orth routes. Javascript file now obviously uh it’s super fun to use this interface to be able to send out these Network requests but we’re going to also do the exact same thing from our client emulator which is this to-do app. rest uh but we’ll see how to do that very shortly first let’s actually create the endpoints cuz there’s no point in emulating these Network requests if there’s no code to rece reive them so from within the or routes this is where we’re going to Define all of these endpoints for handling the authentication functionalities now in here we need to do a few things one is we need to import Express from the Express package two we need to import bcrypt from the bcrypt JS package now if you’re called bcrypt has all the code for encrypting the passwords and creating a truly secure application and as we come to this code and implement it I’ll explain a little bit about how the encryption algorithms work we also need to import a package called JWT from Json web token and that’s just going to allow us to create a Json token which is just uh an alpha numeric key that is essentially you know a sec password that we can associate with a user to authenticate them uh when they make future network requests but without needing them to uh sign up again so that’s going to be important and the last thing we need to import is our database and that’s going to be from our data uh our db.jpg import it into another so these are the four Imports we’re going to need the databases obviously because if we’re registering a new user we need to write that new user to the database and if we’re logging them in we need to check the database to see if that user actually exists now one New Concept we’re going to introduce here is how to configure endpoints or routes when you’re not defining them in the original file if we come back to chapter 2 just here I made a whole lot of endpoints in this server JS it was pretty straightforward we just called our app and we configured the endpoint for the method and the route and consequently wrote the logic to respond and obviously that works we’ve already done one example of that with this endpoint right here this home get endpoint that serves up our HTML website however when we’re subdividing uh or compartmentalizing our routes into these sub files we need one extra basically configuration layer and so what we’re going to do is Define something called router it’s a variable called router and that’s equal to express. router now the reason we do this is because what we do from here is we export our default router and then and it needs to be a lowercase R and our main application just in here what we can do within the server.js is we can Divi uh Define a section here called routes and instead of writing out all of our end points we just say app.use and for any authentication routes so any routes that are within this path we just use orth routes now or routes is an import that we need so we come up to the top just here we’re going to import orth routes from / routes slor routes. JavaScript so there’s a few steps there let me just go over them once again obviously we just got an issue right here cannot find this particular module uh rout slor routes we’ll get to that in a second but anyway the moral of the story is that we inside of or routes just here create this router and it’s to this router that we’re going to assign all of these methods so it’s basically like a you know a subordinate app or like a a a subsection of our app where we can create all these methods so for example I’m going to have one method that is a register method right here so it’s a post request to the register endpoint which if we look just here this is the post request to the register endpoint and we’re not throwing in this SL or throut on the front and we’ll see why in a second it’s just to the register endpoint and then just as we have been I can provide a second argument which is the request and the response and that is the function to be executed when some code hits this endpoint now when we export this router and we import it into our server ensuring that I save it and then we use this line right here it basically takes all of the routes that we Define for the or routes and It Slam them on the end of the SL or route so it combines basically the paths or the routes and so that will Define this particular endpoint so we’ve got the SL or and then all of the end points we Define within our or routes will just be these sub routes within that now we’ve got an issue just here that says we cannot find the module uh DB so that is within our orth routes and I think that just needs to be db. JS instead so let’s save that and now that’s working perfectly so what we’re going to do inside of this uh authentication routes section we’re going to create two endpoints so instead of using the app now we’re using the router and that just allows us to subdivide all of our uh endpoints and routes into these nice little files and so we’re going to have a secondary post request and this one is going to for/ login and that’s once again just going to have a call back function that receives the request and the response as an argument and this is going to contain the logic to log in a user when we hit that endpoint now when we save that these two endpoints that we’ve defined in here are added to this router which is exported from this file and then in our server.js we import all of that as orth routes and then we just slam that on the end of any slor request we tell our app to use all of these or routes when we hit end points that contain the/ oror route now the exact same thing is going to happen within the to-do route so we may as well just configure that before we actually get into the nitty-gritty of uh defining all the routes so in this uh to-do routes file we’re also going to import Express from the Express package we’ll also need our database so we’ll uh import the DB from DOD database. JS then we’ll Define the router which allows us to create these uh specific routes Within These sub files so router is equal to express. router and then we can just have a router doget method and this is going to be to get all todos for a user so this one get all todos for logged in user and then we just have the request response set that up that’s going to be an arrow function then we need another one this is going to be to create a new to-do and in here we’re going to have router. poost cuz if we’re creating a new to-do we’re not just asking for information we’re actually sending over what the new to-do is going to be that’s going to be some information entered into the front end that’s sent over the Network as a network request our back end is going to receive that post request uh and that’s going to be to the/ route and then we’re going to have the function to handle that and consequently save it to our database we’ll need one for update a to-do and so this one is going to be a put method which if you recall putting is for when the networker quest wants to put information in the place of an already existing thing so post is for creating and put is for modification so this is going to be to the slash now the route for the put is slightly more complex if you recall within the database here when we create a to-do all of them get an ID now if we’re updating a to-do the way that we do that is we update the to-do with the ID that matches the ID of the one that we’re updating so we check the database we match up the ID and then we make the modification specifically to that task so that means that when we send out this request we actually need to specify the ID now one way we could specify that ID is by posting that as Json but another way is by using a dynamic query parameter essentially what we do is we use the semicolon and then we provide the parameter where you know if I actually created the request I could use IDE of three in the place of this now we’ll see how all of that works when we go and create or uh when we create the emulations of all of these Network requests but for now this is just a dynamic ID which is going to allow us to identify exactly which to do we need to make the modifications to now in here we still have the Callback function or the function to be executed when our Network request hits that endpoint we’ll still have a body of information that is sent over is Json but we just specify the ID just here so that’s nice and neat and then the last one we need is to uh delete a to-do and that’s going to be router. delete and that is also going to be to the ID parameter or ID path and that’s going to allow us to basically say only delete the to-do entry that has this particular ID and that’s also going to have the function now with all of these endpoints done obviously we’ll come back and create the code for each of them later but I’m just going to export default the router that’s going to assign all of these end points to this router entity and then once we’ve exported it we can save this file and come into our server.js and we can import from the/ routes f older and then consequently the to-do routes.js and I’m going to import these as a variable called to-do routs now the name that I use to basically assign all of these Imports to doesn’t have to match the one that was exported from the file so in both of these cases I’ve exported a variable called router but when I’m importing them I’m importing the value and assigning it to this name essentially so to do routes and now what we can do is we can just duplicate this line right here except in this instance it’s going to uh be for routs that are to the to-dos endpoint and ultimately we can see with this configuration it’s just going to allows to have a whole lot more end points but basically uh subdivide them into their own files which is just going to keep any everything a whole lot cleaner uh so that’s super nice and neat and technically we’re actually finished with our server.js file everything from here is just uh filling out all of these routes and their functionalities now that’s actually a lie there’s one last thing we need to do uh and that is add some middle wear to the to-do routes because when we assign them we have to throw in some middleware that authenticates a user before they can actually have access to those end points so we’ll come back and make one little modification to this line later but that should do for the minute now one little error we just need to clean up real quick is uh in the server I noticed that this was not the we meant to assign the to-do routes to this/ too route so now that we have all of this code done we’re ready to go and fill out our endpoints the next thing we’re going to do is actually create the emulations for all of the functionalities now the reason we do this is because obviously when a user uses our complete application they’re going to be able to do all of it from the user interface however while we’re still developing our application it can be useful to basically predefine all of these interactions and we’ll set them up in here and that way we can emulate these functionalities as if a user was using our application and we can ensure that our backend is set up to handle everything now this process is kind of analogous to running tests in JavaScript or any particular particular programming language the testing where testing Works in a similar manner essentially you just basically think of everything a user could possibly do and then you create those actions programmatically and then you can be sure that they are working adequately so the ones that we’re going to start off with are the authentication routes is the first thing the user would come in and do they’re going to have to register user so I think that’s a good one to start off with and so what I’m going to do here is I’m just going to add in some triple pounds inside of our uh too- app. rest and they’re going to separate the different emulations now I actually lied the first one is going to be the get/ endpoint and that’s going to be to check that the website loads so when a user hits this endpoint they are sending out a get request to the HTTP localhost and then our app is on for me it’s uh port 50003 for you it’s potentially 5,000 or whatever other Port you specified and so they’re going to enter this URL and they expect to get back a website so we can now go ahead and test this endpoint and we see that we do in fact get a successful response we get a 200 response which means success excellent and we can see just here we have all of the HTML code that if we did this via a browser or if a user did it via a browser uh would then be interpreted by the browser and rendered onto the screen and all of the JavaScript would be run so that’s pretty cool that’s our first endpoint setup and it’s working we’ve created an emulation for it and we can see that uh that communication between the client emulator and the back end is successful now the next one is for registration so what I’m going to do to test exactly how the registration works is actually come over to the index. HTML and we’re going to look at how the the client or the front end actually creates this registration Network request from the browser and this is also going to be beneficial if you wanted to come and Fiddle with this front end code uh it’s pretty self-explanatory but we’re just going to uh run through it together so let’s look for the function that registers a user here it is authenticate so if we come down we see this line of code just here obviously there’s a bunch of guard Clauses up the top that basically just say if a user doesn’t have a username or password then let’s not even bother sending out a network request but we check to see if the status is is registration and if it’s true then this code right here is the code that creates that Network request via the fetch API and here we have the URL or the to which we send this network request so we can see that the Point is/ orregister API base is just up here the API base is uh the Local Host in this case it would just be slash because it matches the uh host from which we serve up this uh front end now if we look at the network request we can see that the method is post we can see that we specify the content type and we can see that we have a body which contains some Json which is originally an object and that contains a username and a password field so what we’re going to do is literally just create these three fields from within our client emulator so first up is the method it’s a post request and then we provide the URL so that’s going to be HTTP sl/ localhost 003 and then that’s to an orth route and a register route and together that creates that specific end point point and if we check our server we can see that all of our or routes go to the/ or route right here and then within our or routes we can see that we then have the register endpoint and this is the endpoint that we would expect to receive this network request so that’s the post request set up now if we’re posting information we need to actually create that information and that’s going to be a Json object right here and that has two Fields it has a username as we saw I’m just going to leave that as an empty string for a second and then we also have a password field and that is also going to be an empty string and that’s just set up like an object except we uh ensure that all keys are stringified using the double quotations now just for formatting reasons it’s important that we keep a space above the Json that we’re creating for this network request now the last thing we saw inside of our index. HTML is that we had some headers where we specify the content type to be Json so we just have to do that as well that’s what our front end would do so that’s what our emulator has to do so in here we’re just going to specify the content type parameter and that’s going to be application Json not JavaScript just like that and so now we have set up our client emulator to emulate that Network request as if it were a user actually using the front end and since we’ve created that endpoint we should be able to send this request and because within that particular endpoint which we have right here we don’t have any code to respond what will actually happen is the network request will find this endpoint the endpoint exists and it will just wait indefinitely it will wait for a response which it never gets and typically there is a timeout associated with uh receiving a response and if the timeout is reached basically we don’t get a response within a period of time then it will default fail that request and that will take a second and that’s opposed to if we hadn’t Define this endpoint we would get an instant 404 saying the endpoint itself actually doesn’t exist so now if I send that request we can see that we just sit here waiting for a response nothing’s happening and that’s because the code has hit this end point but this we don’t get a response back so we just sit waiting indefinitely now because that’s not what we actually want but we have confirmed that we’re reaching this endpoint we can cancel that little Network request and we can start defining some of the logic to register a new user so the way that this works first what I’m going to do is just comment that this is a uh a register a new user endpoint and that is the/ or SL register route and it’s obviously a post request now the first thing we need to do if we’re registering a new user is our back and receive this uh Network request we need to figure out what the username and password associated with this network request are we know they’re posting information and when we post information specifically as Json that is always contained within the request the incoming request and it’s associated with the body key now once again this particular line right here allows us to read that Json body of the incoming Network request so what we can do is we can say const body is equal to requestbody and that’s going to give us access to the Json body of the incoming request now one thing I’m actually going to do is save ourselves a step right here and instead of creating this variable variable body from within which we would have to access the username and password key I’m actually just going to destruct rure out the username and password directly and so now if I wanted to console.log the username and the password and for the second we can end this communication system and just confirm that it’s working by res. send status and we can send a 2011 which would be typical for creating a new user so we can now test the completion of this uh communication cycle from client to backend and back to the client and the reason I want to do this is I just want to confirm that I can in fact access the username and password which we will then need and I also want to confirm that we can successfully respond to the network request so let’s go ahead and save that that restarts our application and I can now emulate this request now notice just here I am printing a line but I’m not actually getting anything out of it and that’s because I’m a nump d and I haven’t Associated any values so let’s go ahead and throw in some values here let’s just say the username is Giles gmail.com I’d be so curious to see if that’s someone’s actual email and I just like doing 1 123123123 as an easy password and now uh and just before we can see that we did in fact get back a successful request but I really want to console out the username and password so I’m going to rerun that and we can see now that we do fact log from the back end in the backend uh terminal in the backend console the username and password and that implies that we can access this code inside of our or routes and save it now to register it to our uh database so that is super Nifty absolutely excellent step one complete now while we’re here I’m just going to do the exact same thing underneath this other pound key except this one is going to be for the login uh route and that is just going to mean that once we’ve created the login code login backing code we should be able to emulate the registration and then emulate the login actions that quickly as opposed to faffing around with a front end and that is actually the beauty of API API endpoints when you get more accustomed to them sometimes it can actually be convenient to cut out the front end all together and just do it programmatically via an API but obviously if you’re having a to-do application then it makes sense to have a front end to do that uh the one thing I want to do before I exit this file is just explain what these end points do so this is to register a user and that is a post to the/ orregister Route uh and I’ll do the same for the following one the triple hash key basically creates a code comment so this is going to be log in a user to the or/ login route so we’re finished our emulations for these routes let’s go and dive into the code so now that we’re ready to write the logic to register a user it’s time to get technical and let’s talk about Security in developing a full stack authentication protected application now one of the biggest oopsies companies make is they get into the habit of when a user creates you know a new account with a username and a password they save the username and the password to the database and the problem with this is that if they got hacked for any reason suddenly everyone’s password is exposed to the world now usernames aren’t as important as long as you don’t have both username and password so what we do instead of just verbatim saving people’s passwords as a string to a database is we Crypt them and the way that we’re going to do that is with this bcrypt package now the thing that becomes challenging as an outcome of encrypting every password is that when we go to login we look up the username and we check the password and we need to see if it matches the one that they’ve just entered the problem is when we look up in our database the password associated with the user we only get back the encrypted one now the problem with that you might say well why don’t we just decrypt it these encryption algorithms are one way now there’s a whole lot of technical information that explains exactly how that system works I’m not going to dive into it but the purpose is is that you can’t actually decrypt that password and that makes it so incredibly secure but it also means that we can’t match the password in the database with the password that’s just been entered or at least that’s what you might think so just to really give you an example let’s say just here we get this username and password and then we save Gilgamesh gmail.com and as the password we end up with some long series of keys like that and it just looks like mumbo jumbo and this is what we save to the database so we let’s just say we save the usern name and an irreversibly encrypted password so that’s what get puts in the database now when we log in a user we get their email and we look up the password associated with that email in the database but we get it back and see it’s encrypted which means that we cannot compare it to the one the user just used trying to log in so what we have to do is Again One Way encrypt the password the user just entered now the encryption algorithms are deterministic which means that when you encrypt a particular word using a particular key they encryption algorithms always have a key associated with them and that’s basically just a way of them to create mumbo jumbo consistently and so what we do is when a user enters a password if we encrypt that using the exact same algorithm it will get to the exact same outcome and then we can compare the two encrypted passwords and that’s how we authentic to us it now security is a whole big topic and I really just did a 5minute overview as we practice it and implement it it will become more obvious but yeah on the whole essentially what we do is we use a special key we encrypt a password we save it to the database when a user registers and we do that so if we ever get hacked the passwords are totally meaningless cuz they’re encrypted irreversibly when a user logs in we take the password they’ve just entered and we encrypt it using the same algorithm and that because it’s deterministic will produce the same encrypted key and if they’re exactly the same we know that the password the user just entered must have been the one they used when they registered their account and therefore they are equal and the user is the correct individual now the way that this works from a programming standpoint is the first step we need to do is to encrypt the part password and so what we do is we say const hashed password we create a variable called const hash password and that is equal to the bcrypt library we’re going to use it to encrypt our password and we use the synchronous and we use the hash sync method and we put in the password and we provide a secondary key which is the salt which here we can see in the prompt the salt length to generate or salt to use defaults to 10 and that’s just going to help us synchronously generate a hash for the given string so in this case we’re going to use the value 8 now we need to use that consistently as well so now we have an encrypted password and I could actually console.log the hashed password just here and remove this other uh line and now we could emulate that request and see what the hash password looks like so let’s go ahead and run that and here you can see this is the hash password that we would save the encrypted password we would associate with a user and this is irreversible so if our database was hacked no one could ever undo these encryptions and figure out what the passwords originally were and so that’s what we securely saved to the database instead of just saving the plain old string that a hacker could totally take advantage of so now that we’ve done that we can come back to our orth routes and we now have a hash password that we can save to a database now now when we’re interacting with a database in production environments typically a database is actually a separate server entity and this case we’re having it all within the same server entity and there’s nothing wrong with that it’s great for development in chapter 4 we will separate them into their own backend entities but because in production basically we’re creating a new communication uh Bridge or system so now we have frontend server and the database I like to throw this code in inside of a TR catch block where we catch the error and that’s just going to allow us to handle any errors we might encounter in this process and that’s super important for having a functional robust backend so in here I actually like to do the catch case first what we’re going to do is we’re just going to console.log the error. message if we get a message and we’re actually going to respond to the user we’re going to respond and send a status of 503 now if you remember 500 LEL codes which are between 500 and 599 mean that the server has broken down somewhere in this process and that’s exactly what would have happened if we fail to save a user to the database so let me just add a line here this is going to be to uh save the new user and hashed password to the DB so we send back the status now one important thing to note is that if we send back this status we can’t then send back another status that’s going to give you an error there can only be one status one response and so we’re going to either send back one if we bug out the code or if we successfully run this Tri block then we’ll send back a 2011 or actually we’re going to send back a token we’ll see how that works in a second so as for the logic that we need to save to the database well what we’re going to do here is actually run some more SQL queries so the first thing we’re going to do is create a variable and it’s going to be called const insert user and that’s equal to DB and we run a prepare method now the prepare method is pretty equivalent to the ex execute method right here exec where we basically just run a SQL query however the prepare method allows us to inject some values into these SQL queries so what that actually looks like is we write a SQL command right here and the SQL command to add an entry to an existing table inside of a database is we say insert into then we specify the DAT the table within the database so that’s going to be the users uh database and then we have some circular parentheses es and in here we have a username and a password those are the two columns that we want to insert into if you remember in when we configured this we had the fields uh username and password those are the two columns within the users table the ID is automatically assigned so we don’t have to worry about that so we’re going to insert into the users table specifically The Columns username and password and then we specify the values and in here that’s just some circular parentheses and for the minute that’s going to be a question mark and a question mark so that’s going to prepare the SQL command that we’re going to run and then what we do is we Define a second variable called the result and this logic is a little bit specific to the sqlite database that’s part of the node ecosystem but now what we do is we take the prepared query and we run it but we call run as a method and we pass in the values that we want to save to the database so in this case it’s the username which we destructured out of the incoming request the body of the request and the hashed password so just to summarize those two lines we first prepare a SQL query where this is just our SQL query we’re to insert data into a table that exists within the database we insert into then we spe specify the table and then we further specify the exact columns to which we want to add information so we want to add information to the username and the password columns and then we specify the values and we basically leave them as blanks until we then run that SQL command and then we provide the actual values which will be injected into these places and that will be sent into the database now one thing I like to do just in here is when we register a new user and consequently create a new user in the database I want to give them a default to-do so I actually want to create a to-do for them that will then be shown on the screen and that’s just going to basically give them you know an entry in their to-do list to prompt them to create some more and understand how the application works so now that we have a user I want to add their first t to do for them now in this case the to-do or the default to-do that I want to add is going to be called const uh default to-do and that’s equal to a string that just says hello exclamation mark and says add your first to-do and we can kind of see how that is just going to I mean technically it’s a to-do and I’m actually going to change that for a smiley face that’s technically a to-do they can complete it when it’s done and that’s just going to prompt them to create some more to-dos and now that we have that line we can create a variable called const insert too and that’s equal to database. prepare and we prepare another SQL line or command so that’s going to be the template literal string and inside here we’re just going to insert into the todos table and then inside the circular parentheses is just here we’re going to specify the columns to which we want to add information so if we come look at the schema for the database we can see right here we have the ID that’s automatic we have the completed status that’s automatically assigned as default to incomplete when we add a new to-do so the two fields we need to specify are the user ID that the to-do entry is going to be associated with and the actual text for the to do so in this case we’re going to enter information into the user ID and the task columns and those are going to have the values and once again that’s just going to be a question mark and a question mark so that’s going to prepare the SQL query and then we’re going to go ahead and run it so we’re going to just say in this case we actually don’t need uh to assign it to a variable we can just uh type insert Tod do. run and now the first entry we have to provide as an argument to this run method is the user ID and the user ID can actually be uh found from within the result of creating the first user so we can in here get the result and we can access the field called last insert row ID so what that does is when we get back the result we just check the uh ID of the last row or entry added to that table in which case it’s going to be the ID associated with the most recently entered uh new user so we get that ID that’s the ID that we want to associate the to-do with and then we just provide the value which is going to be the default to-do and that’s going to go ahead and insert the to-do and then the last thing we need to do now that we have within our database added the user to the user’s column and created their very first to do is we now create a token now the token is super important because once we log in a user they are then in a position to create new to-dos update to-dos delete to-dos but those to-dos are specifically associated with that user and we can’t let them modify everyone’s to-dos just theirs so whenever they run those actions whenever they try to add a new to-do we need to associate a special token or key with that Network request that confirms they are in fact an authenticated user so this is kind of like an API key in a sense we create a token and in this case the way that we do that is we say const token and that’s equal to Json web token. sign and in here we pass an object and the object has a key ID and that’s just the result. last insert row ID as we had just up here uh so we get the ID of the most recently added user and then the second value that we have to provide to the signing method is an environment variable and this is a secret key so what we’re going to do is we’re going to say process.env and that’s going to read the environment variables file and then we’re going to access the JWT secret key and then finally we’re going to have a third argument and that’s going to be an object and that’s just going to have a value expires in and the associated value is going to be uh 24 hours so that means that the special token that a user can attach to their Network request will expire in 24 hours at which time they’ll have to reauthenticate to gain access to a new token now as for this JWT secret we don’t have it yet now this is a secret key that only we know and because it’s a secret key our immediate first thought is to throw it in the environment variables because if people gain access to this key they’re one step closer to decrypting all of the passwords and being able to basically fraudulently act on behalf of a user so in here we’re going to create this environment variable called JWT secret the name needs to match whatever we throw on the end of process.env so that name has to match so we’re going to create this uh key inside of our environment variables and we’re going to set it equal to and in this case it can just be a string it can be any particular string so I’m just going to say your JWT secretor key you could fill it out with anything that’s going to work for us for the second now one other value I want to pass in here is a port and I just want to set that equal to 53 and that means that uh our server is actually going to use that port instead of defaulting to the 5,000 three so now that we have that done we’ve created this token we now have to send it back to the user so we just say res. Json that’s going to send back some Json as a response and in here we provide an object and we use the key value of the token so this syntax right here is going to create the key token and assign the value associated with this new token now what happens when we emulate this request we’ finished with the logic for this particular endpoint we add a new user we assign a default to-do to that user and then we create a special token that we can use later to confirm they are in fact the correct user well let’s go ahead and emulate this request so I go ahead and run that and we can see that we have now added a new user to our database and we get back the special token that looks a little bit like the hashed password we assign to the data base but it’s actually not it’s a unique token and this token contains all sorts of information and essentially what the front end does is if we look at the logic let’s close that and open up the index.html we can see here we get back some data so we receive the Json we basically pass the Json and we assign it to a value called Data now this is all within the front end and then if the data contains a field called token we save that token to the local storage which is basically a client side database it’s how all data is persisted on a front-end only system it’s kind of like a cookie if you ever get asked you know do you want to save your cookies it’s a similar concept it’s saved to local storage so that we can conf consistently access the token even if we refresh the page or reopen it a day later and then if we have that token we then fetch all the Tod do associated with that token now in this case uh if I come across to my application just here and go into the local storage we don’t yet have a token but this is eventually where that token will be saved but if we once again come across to the index.html and now we go down to the fetch todos we can see that when we fetch these to-dos which are going to come to this particular endpoint within our to-do routes we’re going to get all to-dos associated with the user that code comes right here in this fetch to-dos function within the index.html we can see the fetch API is used to send out the network request we send it to the too’s route and we assign some headers with it now in this particular fetch request I don’t specify the method but by default it’s going to be a get request cuz we’re getting information now what we do within the is is we specify for the authorization we add the token and then when this network request is sent out with the token encrypted within the network request we then receive that endpoint right here however eventually it will be intercepted by our authentication middleware which is going to basically check that the token is for a valid user and then we’ll only send them back to does associated with that particular user and that particular token now I recognize that’s probably a mountain of jargon a whole lot of new Concepts if it feels overwhelming absolutely don’t stress when we code all of these systems out and really get a good understanding of what does what and how it all works and how it comes together it will become much much clearer but anyway that is our first authentication endpoint done the login one is fairly equivalent and that’s what we’re going to jump into to now and we should be able to check that they have worked and are working successfully by from within our client emulator and we will eventually just be able to register a new user and then log in a user all right so we just finished up our registration route that’s all working we tested it with our client emulator looks absolutely excellent and what that registration route does is it creates a new user inside of the user’s table with a username and pass password so now once we have a registered user we can allow them to log in and the way this is going to work if we come into the index.html and look at our authenticate function here we have the is registration code we’re obviously not registering anymore we’re logging in so we hit this else case where we log in an account and you can see first it’s to the/ off/ login R route or path we post information as part of that Network request it’s of cont ENT type Json and we transmit a username and a password over as the body of the request now when that hits our endpoint the first thing we’re going to have to do here is destructure out the username and the password and the reason we have to do that is because we need to check our database for an existing user that matches that username and then we need to retrieve the hash password and compare the two of them see if they are valid so the first thing we’re going to do is just like we had inside of the registration route we’re going to destructure out the username and the password where if you haven’t picked up on this yet the username and the email are equivalent now they come from the requestbody which is the body of the request which is the information that is being posted with the network request now whenever we interact with the database we’re going to throw that inside of a TR catch block where we catch the error and we console.log the error. message so if we do have an error we can see what it is and in the case that we get an error we’re going to send a status we’re going to say response. send status and we’re going to send a 503 which indicates that we had an error in the back end internal server error now the tri block is going to contain the logic that is going to attempt to interact with the database and just because that can potentially be a precarious oper operation for example in the instance where our database is shut shut down you know we need to handle that potential error case anyway so it’s time to interact with the database the first thing we need to do is pull up the existing user so what we’re going to do is Define a variable called const and we’re going to get the user get user and that’s equal to database and we’re going to prepare a query that is going to read the database for this user so we’re going to go database. prepare invoke that method and in here we’re going to have a string now the SQL command we need to use to read an entry from the database is we say select and then we use an asterisk key to say we want to read every single column from the database so we read everything from the users’s database and now what we’re going to do is throw in a condition so we’re going to read in all of the data from users where the username is equal to and then we’re going to have the placeholder so this is the SQL command we need to read all of the entries from the user’s database but then actually have a condition that filters out a whole lot of them so now that we have that query prepared we can go ahead and run it so we can assign it to a variable called user and we can just say get user. getet method and we get the user that matches the the username so essentially what this command does is it’s going to inject this username and into this question mark right here and then it’s going to read everything from the users where their username matches the one that we pass in so that’s just an email lookup from a SQL database or a sqlite database so now that we have this theoretical user we need to throw in some conditional Logic for the case where no user is returned so if they try login and they don’t have an account we need to reject them out of this process so what we’re going to do is throw in an if Clause that says if not user then what we’re going to do is we’re going to return out of this function but we also need to respond to the network request telling them that we couldn’t find a user so we’re going to say res. status we’re going to throw in a 404 could not find and then we’re going to send an object that contains the key message and the associated value of user not found so if we go ahead and save that we can actually test that so what I’m going to do is come into our to-do app. rest and I’m going to restart this code so I’m going to contrl C rerun npm runev and that is going to reboot our application and the reason I’m doing that is cuz that is going to empty our database every time we restart our server it’s going to empty empty out our database now if I log in I would expect us to not find a user however since we’ve handled that case we should get an appropriate response and if we send that we can see that we do in fact get back a 404 that contains that message user not found now if I were to instead register a user we get back the token and now that has created an entry in the database and I should then be able to login and we can see that when I hit the login it actually doesn’t respond we’re just stuck waiting and that’s specifically because we haven’t handled the case in which we actually find a user we haven’t responded to it yet so I’m just going to cancel that but that confirms everything is working well for the case where we cannot find a user so if we get past this what’s known as a guard Clause cuz it guards the code or the successful code in the case where we do have a user now what we need to do is check that the password is valid so what we’re going to do is Define a variable called const password is valid and what we’re going to do is use a bcrypt method so we’re going to type bcrypt and we’re going to compare we’re going to use the compare sync method which is a synchronous comparing and we’re going to compare the password which is the one that the user has just entered with the user. password password so user. password is the second argument to this compare synchronous and essentially we can see what the method does right here it synchronously tests a string against a hash so essentially what it’s going to do is as I described earlier it’s going to Hash our password and compare it to the hashed password make sure that they are equivalent so essentially that’s going to return a Boolean where if the password is valid it’s true if it’s not if it’s incorrect correct if the comparison is not true then it’s going to return false now because we’re in the habit of using guard Clauses we’re going to first handle the case where we uh find that the password is incorrect so we’re going to say if not password is valid so if the password isn’t valid then we’re going to return out of the function break out of this code and end the execution and we’re going to respond with a status code of 401 and we’re going to send back an object that has a message key that is associated with the string uh invalid password and that can be lowercase password so now if the password is incorrect we’re going to respond and basically say nice try buddy not getting in today now if we get past this guard cause then we have a successful uh Authentication so let me just add in some comments here so uh if the password does not match return out of the function and up here this G Clause says uh if we cannot find a user associated with that username exit or return out from the function so now we can handle the case where we’ve matched the password we’ve found the user and everything looks good so what do we do well just like we did above we sign a token and we send back the token and I actually think the code is nearly equivalent so all we do is we give them back the unique token which we associate with their account which they can use to authenticate all of their crud actions and all their to-do updates and then whenever they go and make those actions we can just verify that they are in fact the correct user so first we have to get the token we’re going to Define a variable called const token and that’s going to be equal to and we’re going to use the JWT Json web token Library do sign the sign method and this takes an ID like it did just above up here we provide the ID of the user except in this case we access the ID via this little uh through the result. last inserted row ID in this case when we do have a user we can just access the ID field now what I might just do here is actually console.log the user so that we can see what we’re actually looking at when we run this request but anyway that is the first argument we need to pass into the sign method after that once again we do the process. EnV we access the environment variables file and specifically the JWT secret key and then we have one last argument which is uh an object and that contains the expires in key and that just once again expires in 24 hours so that’s going to create this token for us and then the last thing we do is we send that back we res. send or res. Json if you want to send Json and in this case we just send the token back from our endpoint and just like that we have all the logic we need to successfully handle authenticating a user so now we can actually go ahead and test that let’s once again restart our code by control cing out of it and then running the npm Run Dev command and now we’re going to log in a user which won’t exist we get back user not found now I’m going to register a user by running this register end client emulation so now we get back a token that’s super cool and then we should be able to log in a user however I’m going to use the incorrect password so now we log in we do in fact get an invalid password but now if I correct the password we should uh receive the token so that works successfully and we can see we actually consoled the database entry for that user so we can see they have an ID of one we can see their username and we can see the associated hash password now once again this is the token we’re going to use to authenticate all of our uh to-do crud actions so we’ll see how to use that in just a second but before we do any of that we have some crud end points to Now set up so we’re going to come across to the to-do routes and start filling out these end points so there’s four end points in here there’s a get for getting all of the users to do there’s a post a put and a delete now these endpoints are relatively straightforward for example if we want to get all of the uh to-dos associated with a user all we have to do is once again prepare a SQL query so we type const get todos and that is equal to we go to our database which we’ve import imported just up here and we prepare a SQL query now once again just like when we’re reading from all of the users we say select we use the asteris which ensures that we select all columns uh and we select from the to-dos database now because we only want to get to-dos associated with a particular user we just throw in a wear command and we match the user ID the user ID has to be equal to the placeholder that we will fill out shortly so just to summarize how this query works we say select all the columns from the to-do database where only where so it’s actually technically not every entry it’s just only where the user ID matches the value we’re going to pass in and now what we can do is we can say const to do is equal to and that’s just the query and in this case we’re going to use the all method cuz we want all of them and we’re just going to access the request. user ID now at this point you might say but James don’t we have to read these values from the body of the request and that would be one way of doing this however the request in this instant is slightly different because of some logic we’re going to add to the middle Weare so once again the middleware intercepts the end point receiving the network request so it gets there just first and it’s like a security layer so what we’re going to do is actually finish this endpoint assuming that our request does in fact have access to the user ID and that should be a lowercase ID and then we’re going to see how the authentication middleware works so in the case that we do fetch all the to-dos associated or where a user ID matches the one that we’ve just got from the request we can just send back Json containing the to-dos which is an object so that’s this endpoint complete but as I said we need to complete the middle Weare which is going to authenticate a user and make sure that the correct person now all of that is going to happen inside of our or middleware so we’ll save this file and head over there now the way that this middleware is going to work we’ll once again need the uh JWT package so we’re going to import JWT from Json web token now notice how I’ve been signing all of these tokens in giving the user all of these tokens and if you come back to the index.html and look at any of the fetch to-dos we can see that we then send this to-do as a network request over the Internet when a user makes any of the crud actions once they’re actually logged in so they’re logged in they have a token that authorizes them and and then that token is attached to every Network request they create while managing reading updating deleting all of their to-dos now the purpose of the middleware is we intercept that Network request and we read in the token and we verify that the token is correct for that particular user so in here what we’re going to do is Define a function called orth middleware and that is going to to uh receive some arguments it’s going to receive three arguments now the first one is the request the second is the response and the third is a parameter called Next which is new we haven’t seen that yet the request and the response are pretty standard the request is going to be super important because we’re going to need to access the token associated with that request and the response is also important because if our middleware our authentication middleware intercepts this request and finds that the user is not in fact correct then we can reject them using this response so we can basically respond before the endpoint actually receives the information we’ll see what next does very shortly anyway I’m going to go ahead and open up this code now in here the first thing we need to do is Define a variable called token and we’re going to read that from the headers of the incoming request so the way that works is we say const token is equal to the request do headers field so we access the headers of the request which once again if you remember from when we create the network request from the client we have the token inside of the headers associated with the authorization key so I’m going to copy that key because we are going to read authorization from the headers and that is going to give us access to the Token associated with the incoming Network request now if we do not have a token if we try to read the token and there’s nothing there then we can return out of this function and we can respond with res. status we send back a 401 Network request which basically says the error doesn’t have a problem actually your request is problematic and we send back a message we’re actually going to use the Json method to send back this message that’s going to be an object and that’s going to have a key message and an Associated string that says no token provided now that’s a good little gar clause and if we get past that line that guarantees that the token has been provided and now we can verify it so what we do is we use the JWT package and we use a verify method and this takes a bunch of arguments the first one is the token so that’s pretty straightforward we have to verify the token the second if you recall when we signed these tokens we signed them with a key the JWT secret key and once again this is a highly secure key and that’s why it’s in our environment variables. EnV file so we’re going to go ahead and read in from process. env. JWT secret we’re going to gain access to that secret key as the second argument and then the third argument is a call back function so essentially what this function does is we uh verify the token and then we get given some outputs and this function is run and it allows us to basically say in this case do this now this function receives two arguments one is the error in the case where something goes wrong we’re trying to verify and something goes wrong and the last one is a parameter called decoded now we’re going to go ahead and open up this Arrow function and in here if we get an error then we’re just going to return out of the function once again and we’re going to respond with a status of 401 and we’re going to provide some Json that’s going to have an object with the message key an Associated string that says invalid token so we tried to verify them and it didn’t work and so we’re sending back a response saying nice try buddy you’re not the right person or potentially just that their token has expired they need to log in again so that’s in the in case that we get an error now the decoded argument is basically going to give us access to some of the core parameters of the uh verified user and what we’re going to do is we’re going to assign them to the request so the request as much as you might think of it as a network request coming in something we can’t change well technically if we intercept it then we can modify some parameters of it before it actually hits the endpoint and it works just like an object so we’re going to say request. user ID and that is going to be equal to the decoded ID which is the ID that we found from that user and then the last thing we do is we call the next method and that basically says okay now you’re good to head to the end point so we’ve modified the request and then when we call next we say you passed this checkpoint the security checkpoint you can now reach that endpoint where if they were trying to get to-dos we can now read the to-dos from the database and since we’ve added this user ID parameter to the request we can then access it from within this uh this endpoint from this request now the reason we don’t just do this process inside of the endpoint is because with middleware we can write this function once and then slam it in front of every single authentication protected endpoint anyway so now we have this code where we basically verify the token if we find out that they are indeed the correct person then we modify the incoming request to ensure that it also contains the ID of the user since we’ve verified them and then we tell them you may carry on to that particular endpoint so that’s the uh or middleware complete now how do we actually throw it in front of the endpoints well the first thing we need to do is export a default module called or middleware so we have to export it from this file and then if we come over to our server. JavaScript and come down to this particular app. use to-do’s endpoint all we do right here is we literally slam it in front of our to-do routes so in this case we would just throw our or middleware which I’m using the Auto Imports right here we can see it’s suggesting I import it and I’m going to throw it in between the to-do routes so we can kind of think of it as like okay we hit this endp point first we encounter the middleware and then every single to-do route endpoint is blocked by this middleware and that is imported just here and that is now available and if I go ahead and save that that should make sure that all of our to-do routes are protected by our or metalware where we have to confirm the token now two small things I wanted to clarify really quickly first is uh regarding the inside the or middleware specifically what this next does this next just says okay you may now proceed
to the end point so it’s the final step before saying okay we’re done with the middleware let’s go on to the actual endpoint which is one of these to-do routes and that is you know all of them here so we hit the or middleware we call that next in the case where it’s an actual verified user and then we send it through to the to-do routes having added the ID to the request so that within the to-do routes we can read the ID from the request now as for the decoded ID if you recall when we originally create these tokens when either we register or we log in we actually create the token encoding the ID so the ID is what we associate with the user and so when we encode it into the token we can then decode it and that’s what this decoded is and consequently we can get out the ID and verify the user so those were just two small clarifications I wanted to make now we’re actually at a super cool point in our project because what we’ll do eventually is come down and write the uh client emulations for all of these endpoints but we can actually register a user log in a user and fetch all of our to-dos which for a brand new user should just be that one default entry that we uh added when they register so they get this default to-do everyone who signs up to our app and the front end should be able to fetch all of those things cuz we have created the complimentary backend endpoints to facilitate that interaction so what I’m going to do is once again restart my server completely that’s going to clean out our database and then I can now try to I can now attempt to log in let’s try a random user I go ahead and sign in it says failed to authenticate that makes sense because we don’t actually have that user saved in the database if I right click and come over to the uh in Chrome developer tools by clicking inspect we should be able to take a look at that Network request right here so if I refresh that page and we do that once more we’ll go for test gmail.com I’ll do the favorite password and submit that we can see we send out that Endo we get a 404 not found we can see here’s the payload that got sent out as part of the network request from the client and then the back end received it and then we responded with the uh Json that said use it not found so that all works perfectly however now if I try to sign up I can submit that and we can see it’s actually logged Us in and we can see a few extra Network requests were just run one was this register endpoint and we can see we got back at 200 okay we can see it was to the orregister endpoint and we can see we sent over the username and password and we got back a response containing the token now the way registration is working in this application is that it also upon uccessful registration logs in a user if we take a look at the front end code and come up to the authenticate function basically the registration and the login functionalities both serve to gain access to a token and then once we have this token if the data contains this token we save it we cach it essentially in cookies or local storage and then we load all the to-dos by calling this fetched to-dos method which if we come down sends out a network request saying okay now we have access to this token let’s send it to the/ todos endpoint it’s a get request we get all of the to-dos back the endpoint response with the to-dos it looks them up in the database once our middleware has authenticated the user via this token and then when we get the to-dos back we display them on the screen we render the to-dos and consequently we end up with a dashboard right here and that’s what it looks like it’s nice and responsive mobile responsive looks great uh and we have our first to-do right here now currently once again we can’t add to-dos we can’t edit to-dos we can’t delete to-dos cuz we haven’t finished those end points for example if I TR say done we just get a failed Network request we don’t get anything back nothing happens if we delete we also just get absolutely nothing back it’s not working so we’re going to have to program them in a second uh but we can now log in display a dashboard register a user login a user and our token is working and we can confirm that by a reloading this page if I reload this page we can see it asks us to log in again and now if I go test. gmail.com type in our password and submit we can authenticate once again and now we have this token now as for the token we can come across to our applic right here and we can see that inside of local storage we have our token saved right there so that is all hunky dory uh and that’s working brilliantly so now what I’m going to do is start to code out the rest of these end points so the first one we have to code out now is this endpoint that allows us to create a new to-do now the way that this one is going to work is not too dissimilar to this first endpoint but it is a great opportunity for us to learn some more SQL queries which is kind of fun CU at the end of the day we’re writing these SQL queries to inject the data into our database tables so what I’m going to do is once again log in we submit that that is done we’re now in the dashboard to add all of our information so if we first come into our index.html let let’s find the function for adding a to-do so just here we can see the network request from the client that tells our backend endpoint to add this new to-do to the database so we send out a network request it’s a post method which is typically for the creation of something and we post information we send information across with this network request to the to-do’s endpoint we include the content type we say that it’s Json information that we’re encoding and we authorize this request with the token so that our middleware can confirm we are the correct user and then finally we send over the task which is whatever is input into this field right here when we click this button so our backend can expect to receive the task as part of the body of the request so if we come into our post request right here for creating a new to-do the first thing we can do is is we can define a variable or better said we can destructure out the task from the requestbody once we have access to that task what we can do in here is we can Define the SQL query so we can say const insert Tod do and that is equal to database. prepare and we can now prepare the SQL query so we’re going to use the back Tex and then in here we’re going to say insert into then we’ll specify the table which is the to-dos table and then we’re going to provide the columns for which we have information which is going to be the user idore ID and the task column the user ID is going to specify what user our task should be associated with and that is going to be something that we can now access from within the request because of our middleware authenticating our user so once we specify the columns then we provide the values and those are just going to be two empty question marks as placeholders until we complete the query so now that we’ve prepared the query we can go ahead and insert too. run we can run the query and we can pass in the request. userid as the ID for the user that we want to associate the task with and then we can also pass in the task itself and that is going to insert that to-do into our database inside of the to-dos table now once we’ve inserted that to- do the last thing we need to do is res. Json we need to respond so we’re going to use the red res. Json method and in here we’re going to provide two key value pairs the first one is going to be the ID of the to-do which we can access by going to the insert to-do and we can get the last ID that’s going to give us access to the ID of the most recently added entry and then once we have that we can now also send back the task and we can send back the completed status of zero because it’s false for the minute the zero represents the false bullan State and that is because our to-do is not yet done we’ve literally just added it so we can now save that endpoint now what I want to do at this point is just actually create the client emulations for for both of these actions so the first one so obviously we’ve got three so far one is to get the homepage we’ve got a register a user and log in a user now we need to emulate the uh fetch all to-dos endpoint which is going to be a get to the slash uh to-dos endpoint a get request to the slash to’s route or path better said and I might also make a note that this one is protected and essentially how this is going to work is we very simply have a get request to http localhost uh 53 or whatever Port you’re using SL todos now first what I actually want to do since this is a get request we don’t need to provide any information as part of that request we can just send it but in its current state I haven’t provided the token to associate us with a user so if I just run this request we would expect to be blocked because we can’t our middleware can’t authenticate us so if I go ahead and run that I get back a 401 which says that I’m unauthorized and we get the message saying no token provided now the way that from this rest client we provide an authorization token is very simply by writing authorization and then a semicolon and then in here we put the token now for the minute we don’t have a token so what I’m going to do is register a user that going to create a user with these credentials and then I’m going to copy the token right here and that’s the token we’re going to use for authorizing these uh to-do crud actions so now that I’ve pasted in the token I should be able to send this request except the difference is this time when we send out the request we have encoded the authorization token into that request so that our middleware our or middleware can intercept that and interpret it and consequently authorize us so now when I send that out we can see that I do in fact get back a to-do entry it has an ID it’s the very first to do we can see that it’s associated with a user with the ID number one so that’s our first added user and here we can see we have the task and here we can see we have a completed status which is zero which is the false bullan status so that is an incomplete uh to-do now what I want to do is Define an in or a client emulation that creates a new to-do and that is a post to the slash too’s endpoint and that is also protected now that is going to be a post to the HTTP localhost 5003 SL toos now this one has a bit more information first up we once again need to authorize the user so we’re going to copy and paste that token now one thing to note is that if you’re restarting your user that token will be invalid as our database refreshes every time we reboot our server now that might seem counterintuitive but in the fourth project we will learn how we can persist that information as we create a third party database entry but for now the moral of the story is that this token is only relevant for either one login session or one registration session while that user is persisted so we use the same to token now what we need is also some Json that contains a task so we’re going to add the task field right here and also have an Associated string that says finish coding the projects now as always because we’re including Json we have to add the content type header to this request by specifying the content-type and that’s going to be application sljs so now when I save that we should be able to create this new entry because we have also created that endpoint so I’m going to go ahead and send that request and we can see that we get back our client endpoint response with the task and the completed status of zero now one thing I noticed is that we should have gotten back an ID as part of that field and I think what we’re missing just here is we have to create a variable here that’s called const result and instead of just running this command we actually have to assign the output to a variable called result and then this should actually be result do last insert row ID so now what I’m going to do is once again go ahead and run that and let’s try that once more so if I come back to the client emulator we’re going to have to run all of that again cuz our server has been restarting so we will well actually let’s try log in yeah user not found so let’s register a user we get the key we’re going to have to replace the key in all of these emulations uh so these authorization tokens are going to have to change to the new token and now I should be able to test them both so let’s get all the to-dos we can see we have one to-do just there that’s the default entry when we register a new user now we create it too and here we can see we get back the IED this time so that has worked and it’s important that we get back the ID because in these emulations when we start specifying what to-do we actually want to modify or delete we’ll do that by specifying the ID of the to-do to you know perform these actions to now if I go ahead and get them again I would expect to have two IDE two tasks inside of my database and indeed I do I have the default one and I also have the secondary one right here that we just added so that is super cool now we can go on to the put entry now for the put entry what I’m actually going to do is uh start off by creating the client emulation for that so we can understand how these Dynamic query parameters actually work so we’ve now added two to-dos so we can go ahead and modify one of the added to-dos so in here we’re going to create a new client emulation and that’s going to be called update a Todo and this is to the slash uh how how did I specify it it’s post to/ too so this one is put if I can spell that correctly put to slash todos and then it’s slash an ID which is a dynamic parameter so we throw in front the uh pound key and this is also a protected route uh and when I say ID this is just a demonstration there are 100 different uh update or modification actions you could make for example you could change what the Tod do in actually says but in this case it’s just modifying the completed field so when we click the completed button or done button just here that counts as a modification so that’s what we’re going to use to demonstrate this kind of endpoint so that is a put to the HTTP localhost uh 53 too’s endpoint however if we come to the actual endpoint we can see that now where these ones were just slash so we can’t just do SL toos it now has to be/ toos slash an ID entry so since we you know saw earlier when we sent out these requests we have an ID of one for the first to-do and an ID of two for the second request cuz they automatically increment so I’m going to go ahead and modify the second Todo entry so in here what we’re going to do is specify the second entry so we’re going to add add the slash2 on the end which is the slash ID that’s the ID of the to-do that we want to modify now we’ll still need the content type of application SL Json cuz we’re sending data and we’re also going to need the authorization token so we’ll copy that from just there and now what I’m going to do is specify the Json data and tell it that we want to change the completed field to a value of one currently it’s zero we want it to be one so that should go ahead and complete that to-do and what you could actually do since we’re running all these modifications is you could also specify the task and change the data associated with that task but we’re not going to do that we’re just going to modify its completed status so if I save that I should now be able to run that and update that entry so I go ahead and run that and we can see that nothing happens and that’s cuz we haven’t actually coded out that endpoint but the moral of the story is you can see just here how these Dynamic paths actually work so just here we can now from within our to-do routes figure out what this ID is associated with so the first thing we’re going to do in here is a we’re going to access the completed status from the requestbody so we’re going to destructure out completed from the body of the request now the second thing we’re going to need to do is access the ID now the way that we get the ID from the URL is we say const and we destructure out the ID from the request. params so that’s the parameters of the request of which the ID is now one now you can also get uh parameters from the queries of the request and and that’s just specific to the URLs and we’re actually not going to worry about that in this course but it’s just a demonstration of the different ways that we can send information via a network request we can either send it per the body or we can throw it into the actual URL what the last example would look like is uh just to show you quickly uh let’s say here we had a question mark that said uh task is equal to and this is the is the updated text or something what we could do is if we went request. queries we could access the task field where the queries come after a question mark a common example is page page is equal to four that’s a query uh that’s associated with the request and then you can access the page number and you can consequently get the value associated with that but we’re not going to worry about that well actually why don’t I just show you page is equal to four now if I go ahead and run that once again that’s going to have the exact same output uh which in this case is to weight so that determines that this URL still hits the exact same endpoint however now what we would do is inside of the to-do routes to access the page I would say const uh and destructure the page out from the request. query so now we have collectively uh demonstrated the three different ways that should you want to you can send information or parameters across via Network request from the body via the parameters or as a query entry once again this last one is not really relevant to this course it’s just good to be aware of and it’s not really going to change anything you can just throw these uh queries onto the end of the rest of the URL so we have access to the ad and we have to access to the new completed status so what we can do in here is we can now say const updated to do is equal to and prepare our SQL query so that’s database. prepare and the query here now we already have an entry inside the database so we’re not going to use the insert to create a new one we’re going to update an existing one and the way that that works is we say update to-dos we update the to-dos table and we set the completed field equal to question mark Mark now if we wanted to update the task as well what you would do is you would just say task is equal to question mark and you would comma separate them so if you wanted to you know have two different columns being modified you just throw them after the set key and you just comma separate them this is obviously the common name and this is the new value with a question mark is a placeholder for the data that we will add in a second but in this case we’re just going to modify the completed step status so we’re going to remove that and now we only want to set these new values where the ID is equal to a placeholder which is going to be this ID just up here the ID associated with that to do so now that we have that uh SQL command prepared we can say const result is equal to well actually we don’t need the result in this case cuz we don’t have to send back an ID we can just say updated to do do run and in this case we pass in the new completed status which we destructured and we also pass in the second question mark which is the ID and that’s the ID that we gained from the parameters which is part of the URL once we’ve successfully updated that we can just send back res. Json and we can send back an object with the key message and the associated string uh too completed so now if I go ahead and save that we should be able to run all of these uh emulations so first we have to register a user that gives us the token we’ll copy the token and we’ll paste it inside of the uh crud actions so first what we’re going to do is just get all of them so that’s our default entry it’s currently got a completed status of zero now we’re going to change the authorization token for adding a new entry we’re going to to add this new entry right here that is now added we get back its ID of two it is also incomplete and now we have one for updating and that is going to update the to-do with the ID of two that’s the dynamic parameter and this is the query on the end that as I said earlier anything after the question mark isn’t going to change the actual end point we hit it’s just specifying some further unimportant information in this case that’s not relevant it was just a demonstrate a point of the three different ways we can encode information into a network request via the body or via a parameter or as a query anyway so this hits the update end point have we updated the token let’s just confirm contrl v no now it is updated so we can go ahead and update this and this should change the completed status of the to-do with the ID of two to now complete that is now completed we get that success for response it’s a 200 level status code so that is perfect and now if I get them we can see that the first entry is still incomplete but the second entry is now complete and even cooler if I refresh the page and log in what are the credentials that we’re logging in with Gilgamesh gmail.com and we type in the password this should still work cuz they’re both using the same server and database we can see that we actually have two entries just here and because one is actually complete we can no longer click that complete button and it is inside of the complete column and we now have only one open to do and now if I go ahead and click done on this particular entry we can see that that Network request is sent across just here we get back at 200 level status code and our application changes so it is now two complete entries and zero open entries so everything is working perfectly and so now that that’s all done we have but left one more end point and that is the delete endpoint now what I’m going to do for the delete endpoint is once again create the emulation first now in this case what I’m going to do is actually just copy and paste this update one cuz it’s very similar and this one is just going to be delete a to-do it’s going to be a delete method and I think that should just be lowercase for consistency and in this case cuz we’re modifying a particular Tod do in this case deleting it uh we need the secondary Dynamic ID parameter now we don’t need the query in this case we’re just going to have the ID uh we still have the same authorization token and now we actually don’t need to send any information but we do have to update the method to delete and that is the emulation all done now one thing I would like to point out uh and this is just you know FYI for your information is that if you’re working in a big organization typically what we’re doing right now which is known as a hard delete is almost not recommended uh because it’s it’s permanently erased you can’t necessarily get it back very easily so what a lot of companies will do let’s say you’re managing lots of Google docs for example if we came over to where we create this database typically they will create an additional field inside the relevant table called Soft delete and that’s once again just a Boolean value where when a user deletes it you actually don’t remove the entry from the database you just change the soft delete value to true and that way it can be restored at a later date so it’s kind of just like a fake delete that’s just something interesting to be aware of we’re not necessarily going to handle that in this case we’re going to go for a Perma delete uh but I just thought I’d mention that any who so now that we have this emulation going let’s go ahead and fill out this last endpoint and wrap this project up so that we can dive into the more advanced version so this endpoint is once again relatively straightforward it’s going to delete a to-do and the first thing we need is to access the ID so we’re going to destructure the ID by saying const ID is equal to the request. prams because it’s a parameter this is a dynamic parameter so that’s going to give us access to the ID then we’re just going to prepare the SQL query so that’s going to be const delete Todo and that is equal to database. prepare now the SQL command to delete an entry is as follows we are going to delete from then we specify the table which is the to-do’s table and then all we have to do is say provide the condition essentially so we say delete from the to-dos where the ID is equal to a placeholder that we’ll fill out and a Boolean operator so both of these have to evaluate to true for it to be deleted and the user ID is equal to question mark now the reason we’re having a Boolean condition here is because we want to match both the to-do ID in addition with the user ID so that’s just basically a double secur to ensure that we’re only deleting a to-do that is associated with the correct user so now that we have prepared the query we can go ahead and run it by saying delete Todo do run and then we just pass in the ID as the first field and then the user ID as the second field and we need to get access to the user ID so we can just go ahead and destructure out the user ID uh from the request that would be one way to do it or we could literally Define a variable called user ID uh and set that equal to request. user ID so that’s going to gain us access to the user ID these values are going to be injected into this query and consequently run and that should complete our endpoint so now if I go ahead and save that it’s going to refresh our database and let’s run through this from the very beginning I’m also going to refresh our app and the other thing I’m also going to do is just uh Delete the token in here and refresh the app uh so now that we also have a blank application so first up let’s test the emulator well first what we’re going to do is we’re going to register a user that works perfectly and now that we have registered a user I can go ahead and log in the user to confirm that that’s working so now we log in a user we can see the user just down here there’s the hash password and we can copy this token now that we have the token we can run all of these authentication protected endpoints so first I’m just going to change the token and all of them and then we’ll go and have a fiddle so first what we want to do is we want to fetch all the to-dos we just get the default one that’s perfect now we’re going to go ahead and create a to-do that adds a new to do and I’m actually going to create that twice so now we have an ID of three and if I get them all again we can see that I do in fact have three Todo entries now I’m going to go ahead and run the put which is a modification and that essentially enacts to complete a to-do so if I run that that should complete the I the to-do with ID of two so this middle one so we run that and the to-do is now complete and if I go ahead and get them all again we can see that the to-do with the ID of two is in fact complete this one state represents true it’s kind of like binary and then what we can now do with our last endpoint is delete the entry with the two since we’ve completed it and that didn’t work and that’s because we forgot to respond I actually think in the context of our database that will have run because technically we will have hit the endpoint and run the logic so if I go ahead and fetch all the to-dos we’ll see that the element or the entry is missing but yeah we just need to respond inside of uh the to-do endpoint so that’s the last line that I totally forgot so in here we’ll just say res. send uh and we’ll send a message that says too deleted very simple and just like that we have officially completed project number two and chapter number three we now have a fully functional application if I once again uh come over to the dashboard and try sign in with gilgames run our password that fails so I’m going to sign up I can now submit my sign up we add that default entry to the database uh I can say that we’ve done it even though technically we haven’t that changes the tab that it’s available in I can add a new to-do let’s say uh go to the gym add that that gets put in here I can refresh the page those are fetched back for us I can say I’ve done that now that is in the complete tab we have no open to do so I can add one it says hello that is now added and I could go ahead and delete that other entry and then if I refresh the page everything is persisted and our project is complete so that is absolutely brilliant massive congratulations uh once again if you do want to support the channel be sure to St the repo love that support and with that project complete is now time to dive into chapter 4 our final project where we’re going to take this code base to the absolute Moon all righty welcome to chapter 4 of this full course where we’re going to take our back-end programming skills to the absolute Moon by building out the ultimate backend application now in this particular project we’re not going to start the same as we have started the rest of the projects where historically we’ve run that mpm in- y command and we’ve built our project up from there installing all of the modules from the npm ecosystem and creating all the files and folders instead this chapter 4 project number three is actually going to be an evolution of chapter 3 chapter 3 is like the beginner version of developing a complete backend application and chapter 4 is going to be like what you would find in a company or massive Tech organization Enterprise level absolute God tear backend infrastructure as for what exactly is being evolved well there’s two things actually three things I guess in particular that are going to change and upgrade from our previous project number one is the database in the previous project we used sqlite which is a brilliant database but if you’re going to build a big production level application then you want to go with a more reputable SQL database such as MySQL or in this case postgress SQL postgress SQL is my all-time favorite SQL database and in this project we are going to put it to good use the second core difference between chapter 3 and chapter 4 is that in this project we are no longer going to be writing out these custom SQL queries instead we’re going to use what is known as an OM or an or or an object relational mapper and what this does is it’s like a middleman between our postgress database and our JavaScript where we can now interact with our database our SQL database as if it were a JavaScript entity and that is thanks to our o the middle man and in this case we’re going to be using an RM called Prisma it’s very popular we’re going to learn how we can integrate it into our project with postgress and we’re also going to learn about all the other advantages that come with using an RM because there are many and last but absolutely not least is that we’re going to dockerize our entire project now in chapter 3 we actually had our database and our server as essentially the same entity and this project is going to be different they’re going to be two separate environments that means that our server is going to have to communicate to an external database and both of these are going to be their own independent Docker environments now this is a much better practice because if your server breaks down it doesn’t mean that your database has to completely restart itself and it also means that our database is going to be able to persist data that much more effectively so at the end of the day these are some absolutely massive changes and there’s also going to be a whole lot of other stuff that we will learn as a product of making these evolutionary changes so it should be loads of fun now as for how we’re going to kick this project off it’s not going to be like the previous chapters either where we have previously run npm inet Dy and then installed all the packages from the npm ecosystem and then built up our file directory from there in chapter 4 what we’re actually going to do is create a duplicate of chapter 3 by right clicking Hing copy and then we’re just going to paste that folder directory and we’re going to end up with a duplicate that we can then rename and we can turn it into chapter 4 so now we have our code base that we can go and rip to Pieces keep the core logic keep the server and make any necessary changes so that we can create this evolved backend project now the first thing I’m going to do inside of here is come into our package.json because I’m just going to change the name of our project and I’m also going to change the description just here so this is instead going to be a dockerized full stack application that uses no jst backend uh a postgress SQL database a Prisma RM and JWT authentication so those are going to be the core changes made in this project now as for what we’re going to start off with we’re going to install the necessary packages that we need for these new techies that we’ll be using in this project specifically we’re going to need to npm install number one is Prisma number two we can space separate different ones is Prisma SL client and number three is a package called PG and we’ll learn what that does later but essentially it’s just a client for postgress so if we hit enter that’s going to install those packages and I realize I’m a muppet we actually need to uh first change directory into our new project so I’m just going to CD into chapter4 and then run that command once again and that will install them all and now we can see inside of our package.json we have our Prisma client we have PG and we have Prisma now the second thing I’m going to do and this is where we’re going to start off making these modifications is we’re first going to create this Prisma client and the way that we kick that off is we start by typing in a command npx Prisma in net and if we hit enter on that that is going to create a Prisma folder inside of our chapter 4 uh project directory now inside of this Prisma folder directory we can see there’s a file called schema. Prisma now if you’re unfamiliar with what a schema does it basically is a folder that specifies the structure of our database so if we think about chapter 3 when we created this database. JS file we specified what we wanted our tables to look like inside of our SQL database well the schema does it in a similar way where instead of using a SQL command we create it as if it were a slightly complicated object and that’s because it’s going to allow us to interact with it as if it were some form of object and that’s just going to ensure that our code stays much much cleaner so we’re going to open up the schema. Prisma and there’s about 15 lines in here and we can just leave them all in there now there might be a couple of lines in this file that are a bit confusing but we’ll only add about 14 lines if you want to learn more you can check out the docs at this particular link and it will explain everything you need to do but you know you’ll also learn by doing in this particular case so when we create this conversion between our SQL database and JavaScript we essentially need to create a model for our JavaScript to allow to interpret these SQL tables so in this case we’re going to need two models so we say model and then we Define the name of the model which is the user and this is essentially going to be uh the structure of the model it’s kind of like predefining what the tables are actually going to look like so we’re going to create this user object and in here what we’re going to do is just like we did before we’re going to create the columns that are going to exist inside of that table so the first one is going to be an ID as we had before then I’m going to tab across and specify that it’s of integer type typ and then I’m going to tab again and in this case we’re going to have some extra parameters so the at ID is going to have an at default and that’s going to autoincrement and we’re going to call that so this just here basically says that you know this is going to be a default parameter which means that we don’t need to specify it when we create a new user and we want it to autoincrement as we add new users now the second field in here is going to be the username and that is going to be of type string and in here we’re just going to ensure that that is unique cuz we can’t have two users with the same name underneath that we have a password column and that is going to be also a string and there’s nothing special there and last we have the to-dos and this creates the relation between the two tables and this is just going to be a to-do as an array so that’s going to be our user model that we’re going to use to basically interact with our postgress SQL database using a JavaScript syntax now we’re going to Define our second model which is going to be the to-do this is what our to-do is going to look like and once again we’re almost done with this file but if you want to learn more about all of the information is in this docs for this project once we create this schema then we just initialize our database using the schema and we’re good to go so for the to-do the first parameter is going to be an pretty similar this one is going to have of type integer and it’s also going to be at ID at default uh autoincrement so that’s pretty straight forward uh the second field for that to do as per the chapter 3 project was the task and that is of type string uh underneath that we have a completed status and that is of type bull in and in here that’s going to have a default at default of false because when we add a new to-do it probably hasn’t been completed yet underneath that we’re going to have a user ID so that’s going to associate the task with a particular user that’s going to be an integer field and finally we’re going to associate this table with the users table so we’re going to have the user and that’s of type user and in here that’s going to be a relation so we’re going to type at relation and we’re going to have the fields and in here we’re going to have a user ID inside of uh the square parentheses and then we’re going to create the references and that’s going to be exactly the same just like that and this is the schema we need for our entire database we can see up here it’s already configured for a postgress SQL database and we have the client so this right here is the code we need to configure our postgress SQL database for a user or the table specifically and here we have another table a predefined template for our to-do uh table so we can go ahead and save that schema now one of the reasons why an OM is also absolutely brilliant is because of a concept known as migrations with our previous project if we were to deploy this live to the internet we create these tables suddenly if we’re in a production environment and we need to change what our database looks like that’s going to be incredibly complicated how do we go back through and make these modifications to all of the entries inside of our database you know like if you have 100 users that are using a primitive form of your database and then 100 that are using a later version essentially version control of your database becomes incredibly complicated when you have loads of users relying on it on a daily basis using something like an omm allows you to easily introduce the concept of migration so essentially what it is is it’s just a record of all the modifications that have been made to the database and when you run your migrations every instance of your database is updated to reflect these changes so it’s always the most recent version and it’s also you know supports these Legacy entries so all of the previous entities have been updated to reflect these changes so essentially what’s going to happen is eventually when we create our postgress environment our postgress SQL database we will run our very first migration and it will format our database to match the schema but we’ll see how that works in a second I know that can be a little bit confusing now the other file we’ll need for our database is a Prisma client and I’m going to create that inside of the source directory so we’re going to create a new file called the prison client.js now this file is pretty equivalent to the database without all this funny business down below we’re just going to create an entity a Prisma entity through which we can interface with our postgress SQL database so in here what we’re going to do is import the Prisma client from at Prisma client pretty straightforward then we initialize it we say const Prisma is equal to new Prisma client and we invoke that we instantiate that class and then finally we export default Prisma so that we can access this Prisma entity from anywhere inside of our project that’s that file totally complete and now that we have it we can go ahead and see how radically improved writing and interacting with our database can actually B so the database interactions that we’re going to be modifying are within these orth routes and these to-do routes and I’m going to start off with the or routes so just up here we can see this is the code that we used to do to create a new entity inside of our uh user table and then likewise with the to-dos tables where we prepare the SQL query and then we execute them well once again with Prisma it’s a little bit different so what I’m going to do is start off by deleting this insert user query and instead I’m going to say const user is equal to and I’m going to await because now that our database is a third party entry the communication between the server and the database is an asynchronous process so we have to make sure that our in points are asynchronous so now what we do is we await Prisma do user we access the user model that we have created and all we do here is we say we call the create method and we pass in an object the object has some a data field and that is an object itself and in here we provide the username and the password which is the hashed password and just like that we have created a user using a JavaScript syntax so that is super easy now the second we have to do is insert a to do I can get rid of all these SQL entries and now I can just await Prisma do too. create pass in an object as an argument and in here we have a data field that’s also an object and we just have the task which is the default too and we have a user ID field which is the user. ID it’s super simple this user right here is just what gets returned it’s essentially just that model object that we created inside of the schema and that’s all we need to do well actually there’s one more thing now we just take this user to do and replace this code just down here and we have now updated this file to instead use the OM Prisma instead of having to manually write out all of these SQL queries so that is the registration done let’s see what it looks like for the login well for the login we can get rid of these two lines right here and we can say const user is equal to we await since we’re having to await we need to make this endpoint asynchronous so we just throw an async in front of that function and then we just await Prisma the user entity and we find a unique entry that takes an object and in here we specify a where Clause so it’s kind of like the SQL logic where we say where ID is equal to ID or in this case where username uh is associated is matches the username that we have entered just here and that is literally all the code we need to find our unique user so I can now save that file and that is complete now we’re not quite ready to boot up our project just yet because we haven’t actually instantiated our postgress Docker environment just yet but we will get to that very shortly first we’re just going to update some of these to-do endpoints so that we can finish up with our Prisma omm configuration so first one first let’s get all the to-dos so we’re just going to remove this code right here and we’re just going to say const todos is equal to we’re going to await we’re going to import Prisma which we also had to make sure we did inside of this file and I actually didn’t do that so that’s me being naughty let’s make sure we import Prisma from our Prisma client save that make sure it’s imported inside of our to-do routes as well and then we can await Prisma we access the to-do table and we find many cuz we’re getting a lot of them and in here we provide an object and we just say where and we want to return the entries where the user ID matches the request. user ID now once again this needs to be changed to an asynchronous endpoint and that is all we need to do to access all of the to-dos where the user ID matches the ID present in the request super straightforward once again you can find the documentation for all of these Methods at that link inside of the Prisma client but we’re going to demonstrate how most of it works inside of these endpoints for creating a new to-do you might be starting to get the hang of this now all we’re going to do is throw in an async key right just in front of that endpoint function and now I’m just going to uh say const Todo is equal to and await Prisma do too. create and in here that’s an object and it takes a data field that’s also an object and we just provide the task and the user ID which is the request. user ID super simple and then we just return the to-do so we’re going to actually just send back the to-do we don’t even have to create all these fields it’s just manually assigned to this variable and we will get an object that represents this new to-do for the put entry once again super straightforward we can get rid of all of this logic and I’m also just going to get rid of this query as well and in here we just say const updated to do is equal to this one also needs to be made asynchronous so we throw the async key in there I’m also just going to throw that in front of the delete one while we’re down here so I don’t forget to do it and then we just say equal to we await Prisma do too. update and that just takes an object and we say where that’s also an object and we say where the ID is equal to and we’re going to pass integer so we’re going to convert it to a numeric value and we’re going to access the ID that’s the field right there and then after that we’re also going to match the user ID with the request. userid field so that’s going to make sure we update to-dos only where the to-do ID matches and also we have the correct user and then underneath that we just provide the new data which is just going to be the new completed field super straightforward and I think in this case the completed field is currently going to come through as as a numeric value so what I’m going to do is throw a double exclamation mark in front of it and that is going to convert it to a Boolean amount and then once again we can now just send back the updated to-do done and done super simple so this command just to summarize we update the to-do where all of the IDS match to confirm it’s the correct to-do we want to update and we provide the new data and we force our completed field to become a Boolean value by throwing the double exclamation in front of it that’s a little secret hack it’ll convert anything to its uh truthy or falsy state and finally we have the delete field once again pretty straightforward we get access to the user ID and in here we just uh await Prisma do too and we use the delete method that takes an object and we just specify where and that is exactly the same as this where Clause up here so I’m just going to pass that in and we are done that’s literally all it takes to use the Prisma RM super straightforward and I actually think I can uh do that and that we’ll use that value instead so it’s just so much tidier than having all these SQL commands all throughout your files and just like that we have configured all of our end points to use the Prisma omm and also to be relevant for postgress which is super important so now that we’ve done that we are now ready to dockerize our environments and actually get our postgress SQL database up and running and then the last thing we’ll do is we’ll see how we can create a composed. yaml file which essentially just configures everything so we can boot it all up in one command all right it is now time to get our hands dirty with Docker and container Miz some of our uh infrastructure so the first thing we’re going to need to do is actually boot up the docker desktop on our device if you recall we installed it earlier and the link to install Docker is available in the description down below so you can just come over to that link and hit download Docker desktop and select your operating system now when you have it open it should look something like this particular screen here where all of our environment are referred to as containers we contain our application it’s like its own mini environment where we can configure how to set it up and consequently what code to run now everything else is going to be done from the terminal uh from the command line so we can just move that to the side we don’t necessarily need it open but but we have to have the application running and there will be some advantages to having the client open later now the way that we go about containerizing our environments is by creating a doer file file now the docka file is basically just an instruction sheet on how we can create this environment so that it has everything it needs to run our little you know infrastructure backend infrastructure be that the database or our node.js server so what I’m going to do inside of chapter 4 is create a new file and it’s just going to be Docker file just like that doesn’t even have a file extension now inside here as I said a second ago it’s pretty much an instruction sheet and the first instruction we need obviously we’re running a node.js application is so we need to set up this environment to have access to nodejs so what we’re going to do I’m going to leave a comment just to walk us through these steps I’m going to say use an official node.js runtime as a parent image now I remember when I first came across this term image I was just thinking oh it’s like a picture and that’s kind of true but in this context an image is actually more like a snapshot it’s a snapshot of a separate instruction sheet so when we eventually create this Docker file and build our container what is happening is we’re creating a snapshot of that environment and then whenever we run our containers we can just run that snapshot and get us right back to where we were and we can build off pre-existing images in this case we’re going to build off the node.js official image and that’s just going to take a snapshot of the node environment that we specify and add it to our new environment that we’re creating via this Docker file so we’re just going to use the command from and we’re going to say node version 22- Alpine so that is the official node.js image we need to throw into our new containerized environment now this Docker file just here is specifically for our nojz application we’ll see how we can get our postgress SQL environment up and running very shortly so the second line we need is to Now set the working directory so we’re creating this new environment we need to specify a folder for our project so we’re going to set the working directory in the container and we do that using the work dur command and we’re just going to say slash app that’s where our working directory is going to be step three now that we’ve got that no JS Bas image and we’ve got our working directory we need to copy the files from our local project into this new environment because basically it’s like you’re setting up a new computer you need to copy all your stuff across so we’re just going to copy the package.json and the package-lock do Json files to the container and the command that we use to copy stuff from our local device into our Docker container is the copy command and the files we’re going to copy first is going to be the package.json files so we’re going to specify that we want to copy any file that has a package in it so then we’re going to use the uh little asteris so that it selects both the package-lock and the package.json and then we just want them to be the um Json file so that is from the source and then the destination we want to copy it to is the period which is going to be the current working directory which is the SL app so it’s going to copy these two files from our local device and slam them into the app of our Docker environment now that we have access to the package.json we need to install all of the necessary npm packages or dependencies that we need for our project and since we have access to the nodejs and consequently npm ecosystem we can do that very easily so we’re going to install the dependencies now traditionally we’ve typed mpm install and then we’ve specified the name of the package however if we just want to install every dependency inside of our project we can do that using the npm install command and we don’t have to specify any packages and what that will do is it will just read our dependencies list and install them all and since we have access to that file inside of our Docker environment we can just use the Run command and we can run the mpm install command inside of our Docker environment and that will install all of the dependencies now that we have the dependencies installed we’re good to copy the rest of our application across so we’re going to copy the rest of the of the application code and that is once again a copy from The Source destination which is our current file which is chapter 4 to the destination which is the uh SLA directory the period is the current file and this is the current working directory inside of our uh Docker environment and the destination so that’s going to copy all the remaining source code across now the reason we separate these commands is because the way that a Docker image is built is from the top down and if we change some of our source code when we next go to build that image it will rebuild our container from any files that have been changed if all of this stuff is exactly the same which it likely is we’re probably not going to be installing any more packages and that means all of our dependencies will remain consistent Docker is clever and so can cach all of this build information and it can just rebuild the image from the changed line so technically we could just copy everything in one go but that means that when we make changes to our source code we would then consequently have to recopy this line and reinstall all the dependencies which we can avoid if we just copy first the package.json then install the dependencies and then next time we change our source code we can just rebuild our image from this line down you don’t have to do this but if you just want to make the process of building your containers slightly more efficient this is a good way to do it so this line copies our entire source code across to the container now that we have copied all of our source code across what we need to do is expose the port that the app runs on now what this means is that when we create this Docker container and we run our application inside of it it’s essentially walled off from the rest of the world and what we need to do is open up its ports and we map an external port to an internal port and we’ll see how we can do that later but the point is we need to expose the port that we run our application on for consistency I’m going to do 53 and we can see just here this uh EXP expose command exposes the port that the container should listen on Define Network ports for this container to listen uh on a runtime so once again just to summarize this line we need to tell our environment to open up this port to incoming Network requests from whatever Source if we didn’t have this line it would be an impermeable barrier that we couldn’t send Network requests into so it’s just like opening up a wormhole between our real environment and this docker environment and then once we’ve exposed this port we are now good to boot up our application inside of this Docker container so we’re going to define the command to run your application and the way that we do that is with the command uh command CMD and in here we have an array of the strings or words needed to boot up our application now the way that we typically run a file is we say node and then in a separate command we specify where node can find the executable file which in this case is the/ source server.js file and you’ll note that that is fairly equivalent to what we see inside of our script we say node and then we specify the file but we obviously have all of this jargon in the middle now because in chapter 4 we’re using postgress and we’re not using any experimental feat feates inside of node.js we can remove all of these uh all of these different lines so that’s super handy so we can have a very simple startup script we don’t need any of these experimental features and consequently this is the command that is going to boot up our application and I actually think these are meant to be the double quotation mark not the single quotation mark so I’m just going to change that very quickly just like that so that is now happy and that is going to boot up our application inside of this container and it’s going to listen to incoming Network requests on Port 53 so that is officially the instruction sheet that our container needs to get our application up and running now this is super cool because anyone on any operating system can suddenly start up our application inside of this little environment another good example is that if you wanted to run postgress normally what you would have to do is install postgress on your device and then you can up get postgress up and running in this case at no point have we installed postgress because our postgress environment is going to run inside of its own little Docker container and so we can just actually tell Docker to create an environment with postgress installed and we can just refrain from installing it on our device so it just makes it super easy to you know deploy your code to a different environment for someone else to download your GitHub repo runner on their device uh and at the end of the day for for us just to not have any software installed on our computer aside from Docker and we can still boot up these amazing applications so Docker is super handy and it is ubiquitous which is a good word so now that we have this instruction sheet what we have to do next is actually build this container we’ve just created the instruction sheet to build this container however one thing we need to do first since we’re not running these uh experimental Flags we need to make sure that we’re not involving sqlite node sqlite anywhere inside of our project currently we still have the import line for our original sqlite database in our routes files and that means that when we boot up this container it’s going to try and execute this database as well as having a postgress database now the problem with this is that since we haven’t enabled at these experimental Flags that’s going to break our container so we don’t have to delete these files we just need to delete the imports from the or routes and the to-do routes to that database file and then it’s just going to sit there not doing anything so that is absolutely fine so we’ll just remove those two lines from our code base and now we’re almost ready to build our container the one last thing we need to do before we actually build our container is finalize our Prisma setup now the way that we’re going to do that is is from our terminal and we need to run a command that is going to generate a config file for our Prisma client now the reason we have to generate this config file is because it’s specific to our schema which is our database structure essentially and every time we change or modify this schema we need to rerun this command and the command can be found within the readme.md file if you’re looking for it later there’s a whole instruction sheet just here on how to get this up and running but essentially what we’re going to do from inside of the chapter 4 directory now that we’re finished with the schema is we’re just going to run npx Prisma generate and hit enter on that command so now that has generated that Prisma client and it saved it inside of our node modules that is all done we are almost ready to build our containers currently if we went head and build our containers we would build our Docker file for this nojz application which is brilliant however the problem is that doesn’t help us with our postgress SQL database now to configure a postgress database inside of a Docker container you essentially just need to run this first command and because it’s just one line we can actually do that from what’s known as a composed. yaml file now where a Docker file is essentially an instruction sheet for creating one Docker container when you have an application that uses potentially you know numerous or even tens of different containers or environments you need to define a configuration sheet to boot up all of these Docker environments so what we’re going to do is create a new file and that’s going to be called docker-compose yaml y ML and I’m going to hit enter on that and so where the docker file is the setup instruction sheet for a singular Docker container the docker composed. yaml is a configuration sheet for our conglomerate of docka files or individual containers it’s kind of like a glorified specs sheet now there’s a few different lines in here and I like to think of it as kind of like a bullet point specification list so we just have a bullet point and some tab indentation of all of the different specs we need to get all of our containers up and running in one Fell Swoop so in here the first uh parameter we have to specify is the version which is going to be version three that line doesn’t really mean much underneath that we have a line that means a whole lot more it’s called Services now inside of services underneath that we’re going to tab across we’re going to indent it and this is where we Define the configuration for all of our different containers the first one is going to be the app container and that is going to be the nodejs docker file that we just created so in here I’m going to use a semicolon enter and then tab across once again it’s like indentation uh instead of using bullet points now this app needs what’s known as a build line now we use the build line when we have a Docker file to build that container
and the path to that Docker file is just the period which is the current directory so it’s going to look in the same directory as this yaml file and it’s going to find the docker file and that’s the instruction sheet it’s going to use to build that container now underneath that at the same indentation we’re going to have a container name and that’s just going to be too- app underneath that we’re going to have an environment parameter now the environment parameter is for specifying the environment variables where in the previous projects we use a EnV file in this case we can do it directly from the specs file which is super handy now the first parameter we’re going to need in here is a database and this is all upper case URL now if you remember inside of this schema Prisma we had to provide a URL and this was the default code created when we created this file so this was already there and it’s looking inside of the environment variables for a database URL now in chapter 3 our server and our database were one unified entity however in this project we have one container with our database and a separate entity that has our server and so we need to provide our server with an address address to locate our database container and that is the database URL so in this case the database URL is a little bit complicated and I’m actually just going to copy it across so once again if you head over to the GitHub code you’ll be able to find this line uh just look for the docker composed. yl file and copy this line across and this is the address we need to find our database and if you do check out the GitHub be sure to St the project love that support so this will give our node server an address through which it can communicate with the database now the second environment variable We need oh I added a little um quotation mark there the second environment variable we need for this app is the JWT secret and that’s an environment variable we’re familiar with from chapter 3 and in here I’m just going to provide a random string your J wtor secret here now this string can be any string it could be a jargon string a whole bunch of random mumbo jumbo or it could be something specific to you but once again environment variables are secure they are protected and it’s something that only you should have information to so whatever string you choose to put here whatever selection of characters just make sure that it’s only available to you equally you know you could just use this uh for development as secure on your device so it’s not going to be a huge issue the third environment variable is called the nodecore EnV so that’s the node environment now typically there’s two environments sometimes there’s three one is development so when you boot up your application in development that’s going to be the development environment another example would be a production environment and a third one might be staging which is typically somewhere in between it’s the envir prior to deploying your code to production now the reason we like to specify this as an environment variable is because sometimes we have code that runs specifically in development other times we’ll have code that only runs in production and so if we specify inside of the environment variables that just allows us to have the same code base but change one line and that’s going to basically specify what environment that we’re in so in this case it’s going to be the development environment finally we’re going to specify the port environment variable which if you recall inside of our server.js we read the port for our app to listen on from the environment variables under the port key we obviously have a backup of 50003 and in this case the port for me is just going to be the same 50003 so that is our environment variables complete now underneath the next parameter we have to specify for our app is the ports now this is called Port mapping where what we do is we match an external port to an internal port and just like exposing we basically set up a configuration for an external network request to meet a port and we match that to an internal Port so in this case I like to keep them the same and that’s going to be a string and we’re just going to match 5,000 in your case or 5,000 and3 in my case to Port 53 so this is the external port on our container and this is the internal Port that we’re going to match it to or map it to underneath the ports the next parameter is going to be a depends on field now obviously our server depends on our database now we haven’t configured the database service just yet but we will do that very shortly but all we do is we just tell it that it depends on the database so one is dependent on the other and that is going to interconnect the two of them and then the last field we need is a volumes field now the volumes field essentially what it does is it creates a database or a storage or a history record of our server so if we didn’t have a volume every time we booted up our container it would be a blank slate if we do have a volume that is a place for us to save the previous state of our container so that when we shut it down and we boot it up again we can just read back from where we were so in this case the storage for basically where we’re at is going to be in this directory right here that is the volume and that is just going to persist any configuration any data any information that is available inside of our container and this would only be erased in the case where we would actually delete the container and rebuild it from scratch so it’s important to have a volume so that your app can remember essentially and that is our first app service complete now the second service which has to be at the same indentation as the app is going to be called the database now the database doesn’t have a build file because we haven’t specified a Docker file for it and as I said earlier instead what we’re going to do is just build it directly from an image now the image we need for our postgress database is the postgress version 13- Alpine and obviously this image is one tab indented from the database which is one tab indented from the file left hand side the indentation is super critical for this file so if you’re uncertain be sure once again to compare it to mine in the GitHub repo now that we have the image which is basically all the setup we need for creating that environment with postgress inside it we’re going to give the container a name so the container name is going to be the postgress database and under that we’re going to have some environment variables now these ones are going to be a little bit different essentially the first one is going to be a postgress user and this is all uppercase and the username is going to be postgress so we’re essentially just defining the login information if you wanted to be a hacker and modify the database behind the scenes so it’s just all of these security credentials for the database the postgress password password is going to also be postgress and finally the postgress uh database name is going to be called to-do app and this to-do app right here has to match this to-do app at the end of the uh database URL so they need to match perfectly now with that done we can specify the ports and the port mapping I want for our database standard practice or convention is is to match 5432 to Port 5432 so that’s just going to map Port 5432 on the outside or the external port for our container to the same port on the inside of our container and once again if we come up to our URL we can see that the port we are using for our database URL is 5432 and as I said that’s just convention and we are going to stick with it now the last thing we need and it’s arguably more important in the case of our database is to specify the volumes which is once again going to just create a data persistence for this container if we didn’t have this once again every time we rebuilt our container or reran it it would be starting from scratch and that’s not very convenient when you’re working with a database we need an environment that’s going to persist data until we literally delete that container off the face of the earth now the volumes URL where this data is going to be saved is a little bit more comp licated in this case it’s just going to be postgress ddata semicolon SLV SL lib SL postgress SQL slata that’s where all of the information is going to be persisted so that when we reboot up our container we can pick up right where we left off finally we’re going to have one more field and this is going to be at the far left hand side so no indentation and that’s just going to be called volumes and that’s going to be postgress Das data just like that and with that our specs file our composed. yaml file is complete so now that we’ve configured this specs file which basically is an instruction sheet on how Docker can boot up every container needed for our application we can actually go ahead and build these containers and finish our project now there’s a few steps required to build these containers and consequently get them up and running one such example is when we have our postgress container working we need to then go into it and make sure that the tables are created with inside that database and we’ll see how that works shortly all of the commands that I’m about to run are available within the get started section of the remy. md4 chapter 4 so you can find all the commands we’re going to be using just there it is a bit of a step-by-step process but once it’s done it’s complete and you now have This brilliant application so we’ve completed the docker compos yaml let’s go ahead and build all of these containers now with Docker open in the background the First Command we’re going to go ahead and write is called Docker space compose space build now what this is going to do is it’s going to build our containers from that composed. yaml file and here we can see it’s starting off by running all of those Docker file commands first for our app and then it also does it for our postgress database now with these containers built we are now ready to boot them up based off the images that are created or the snapshots of these completed environments and we can go ahead and run these virtual environments however before we go and run them both together we now need to make sure our database is updated to match the schema. Prisma file or essentially the tables necessary for our database now the command we’re going to use for that is a little bit complicated it’s Docker compose but instead of running build we are going to run our app and inside of the app we’re going to execute the command npx Prisma migrate Dev d-name and net now what this command is going to do is it’s going to migrate or run a migration for our database and that is going to our schema file and it’s going to create the first version history for essentially any modifications made from our database which in this case is going from a completely blank database to having the necessary tables we need for our application so I’m going to hit enter on that command and we can see what has happened is it has run our postgress container executed this command and it has created the to-do table and the user table so that is excellent we can see that it’s also created a migrations folder inside of our Prisma file this is absolutely normal and it’s not something that you want to Middle with uh it’s just the record history of any modifications made to our database so that is all done now that we have finished that line our database is set up to you know have all the tables we need for our project we can go ahead and boot up our two Docker containers and the command we use for that is Docker compose and then up now you can also specify a/d flag and what that’s going to do is it’s just going to boot them up in the background and give us access to our terminal again but I’m not going to use that in this case so if I go ahead and hit enter we can see now we are running two Services we have a container called postgress DB and another one called to-do Das app and we can see that our to-do app has actually executed that console.log that we have when we tell our app to listen on Port 5003 that is now running and even cooler if we open up Docker desktop we can see here we have chapter 4 we can click on that we have our two containers running and we have a nice log that we need for our whole project so that is absolutely brilliant you could look at the logs for each of them specifically by clicking on each one but here we have just a global log for our containers and with that done that is actually our app running inside of these two containers and so we should be able to I’m just going to clear out any um tokens that we have saved just here so that we can start from scratch so let’s refresh this page we have absolutely nothing local storage I’m going to delete that token so we have our blank application we can see that it is being served up on Port 5003 which is super cool because I’m not running this I’m not running npm run Dev you know like our application is running inside of this container and it’s serving up our application I could go ahead and try to log in and that fails to authenticate which means that our backend endpoints are working what I could also do is I could come into our client emulator right here out too app. rest and I could run this register command I could emulate this client request and we can see that that works and that registers us and it gives us back a token I could try log in again I haven’t actually registered a user inside of the application but that client emulation has created that entry inside of the database so now when I submit I’m actually logged in and we can see that we even have it to-do which means that our backend inside of this container wrote to our postgress database I could go in here and add a new to-do and I could say that this first one is complete and now I can refresh the page and we can see that this data is persisted inside of our database so that is super cool and it gets even cooler what I could do now is I could go ahead and delete this token once again refresh the page that’s going to log us out and I could create a new account and this is going to be test gmail.com here’s a basic password and I can log in and we now have a new user created and what we’re going to do now that we have made all these uh entries to the database is we’re going to see how we can log directly into the database which is a place where we can modify it directly using SQL queries so if I come up here we have all of this uh loging going on inside of our Docker container and what I’m going to do is create a new terminal instance and that’s going to keep this one running in the background but it’s also going to give us a terminal that we can run some new commands in now to log in directly to our database is a slightly complex command and it is once again available inside of the readme.md file but essentially what we do is we write Docker execute exec Das it and we specify the name of the database which is postgress – DB we specify the user which is postgress if you recall that’s what we uh specified in the environment variables and then we specify dasd and we call uh call the to-do app container now if I run this command it’s going to log us into our database uh and I realized I made a mistake just there I missed out one command just after the DB we need to have a psql which is the postgress SQL command and that is important to put in front of all these flags so if I go ahead and run that in that logs Us in directly to our database where we can go ahead and run SQL commands now the first SQL command I’m going to introduce you to is the back SL DT now if I hit enter on that that’s going to show us all the tables available inside of our database so just here we can see we have three tables one is a history of our migrations which are the modifications made to our database or the changes made over time kind of like a version history we also have a to-do table which has all of our to-dos and we have a users table and what I could do now is run the select query to read all the entries inside of a table I could say select everything from the to-do table and what we’re going to do here is just wrap to-do inside of the double quotation marks and that’s just going to match the casing which is going to be super important and when you run these commands you always have to finish them off with a semicolon so if I hit enter on that we can see here we have a table that shows all the data inside of our database we can see we have three tasks we can see the first one is go to the gym and we can see that’s true and we can see that’s currently incomplete it’s completed status is false we can see that we have hello add your first too and and that’s true if you remember I clicked complete when we added our first to-do go to the gym and we can see that both of these to-dos are associated with our first created user and then we can see we have another to-do and that’s associated with our second user and then if I wanted to exit out of this database all I do is I write the Quick Command and that gives me back access to my terminal and you could log in you could actually run a whole lot of crud actions using SQL commands directly on the database and all of these changes would be reflected in the front end but ultimately that is our backend application complete we’ve seen how we can build a server we can set it up to listen to incoming requests to its Port we can add authentication and database interactions we can serve up a front-end application that can create network requests between the front end and the back end so it’s ultimately a full stack application we’ve added middle wear to add authentic ation protection to a whole lot of our crud to-do endpoints we’ve created Docker containers for two different environments one is our server and one is our postr SQL database and we’ve seen how we can boot them up and run them as a collective application for development and this is such a cool backend project to have because a lot of the backend infrastructure you would find at almost any company is just going to be a slightly more sophisticated or equivalent version of what we have just coded here in this F course so I’m super proud of you well done for persisting to the very end congratulations you should pet yourself on the back learning back in development is you know takes a lot of time and practice but now you have an absolutely amazing codebase 2 reference as you build out some absolutely amazing backend applications in future thank you guys so much for sticking with me throughout this course I hope you’ve had a thoroughly good time and if you have enjoyed the course don’t forget to smash the like And subscribe buttons I’ll catch you guys later peace learning to code if so be sure to check out the learn to code road map or dive straight in with these videos that’s a good one

By Amjad Izhar
Contact: amjad.izhar@gmail.com
https://amjadizhar.blog
Affiliate Disclosure: This blog may contain affiliate links, which means I may earn a small commission if you click on the link and make a purchase. This comes at no additional cost to you. I only recommend products or services that I believe will add value to my readers. Your support helps keep this blog running and allows me to continue providing you with quality content. Thank you for your support!

Leave a comment