How To Be A Web Developer - A Complete Beginner's Guide On What To Know and Where To Start
How To Be A Web Developer - A Complete Beginner's Guide On What To Know and Where To Start
Web Developer
A Complete Beginner’s Guide on
What to Know and Where to Start
―
Radu Nicoara
How to be a Web
Developer
A Complete Beginner’s
Guide on What to Know
and Where to Start
Radu Nicoara
iii
iv
vi
Index�������������������������������������������������������������������������������������������������213
vii
ix
xi
Getting Started
Introduction
Welcome to your journey into the world of web development! Since you
picked up this book, you must have some interest in the domain. That
means that you most likely have what it takes to take your first steps in the
fascinating world of programming. This chapter starts with an exploration
of what web development is, how it works, and how you can be a part of it.
I wrote this book to explain all the things that I wished I knew before I
started along the path of changing my career to web development. There
were a lot of ups and downs and hiccups along the way, but to this day
I enjoy the process and am constantly learning something new. And I
sincerely hope you will as well.
Common Misconceptions
There are a lot of things that people get wrong about programming in
general, and they revolve mostly around what a programming career
actually means. That is, what you actually do at work.
You must be a whiz at math. In fact, you do not need to be good at
math in order to be a good programmer. I myself was pretty terrible at
math, especially the more complex parts of mathematics, like calculus. You
do not need those things. The only important part is that you can think
logically.
Then, despite what many might say, programming is not boring
and it does not require you to sit in front of a screen all day. In order to
be a good programmer, maybe you just need to code. But to be a great
programmer, you need to build systems that people actually enjoy using
and find valuable. That by definition involves a lot of discussions with user
focus groups, collaboration, and generally being open and talking to other
people. Only this way can you be of great value to your project and your
company. If you do not enjoy talking to people, a programming career will
still fit you, but the extent of how far it can go, and how productive you can
become in it, will unfortunately be limited. You can’t hide in the backroom
and ignore everyone. You need your team’s help, and they need yours.
That being said, of course, you will spend a lot of time with your
headphones on, focusing on your task, as well as a lot of time working
from home and doing your job. But in order to be great, you need a decent
amount of soft skills and a healthy inclination toward human interaction.
On another note, you also do not need to memorize all the commands,
and you definitely don’t need to know everything by heart. Nobody does.
The main characteristic that makes you a developer is being able to split
complex tasks into simple structures, which you then put into if/else
statements and for loops. An example of such a logic structure, written in
plain English, is: If the user’s account is disabled, reject the login process.
Or: To each user in the database, send an email.
Imagine programming a piece of code that instructs a car to drive. You
have access to a machine that can only understand left, right, accelerate,
and break. With those four simple commands, you can take a round-the-
world trip. It is the same with when an app. You just need to know the basic
commands.
You are too old/young for this. There is no age that makes you any
better or any worse at programming. This is not sports. As long as you
have some soft skills, and you can learn a bit of coding, you are needed in
the market. That is regardless of your age, sex, religion, or anything else. I
would argue that programming is one of the most inclusive career paths,
because at the end of the day, all that matters is how good your code is,
and how much it helps your end users do the things that they want to do.
You need a degree in computer science. There is also a great need
for people who have studied other fields. You don’t need to get another
degree. Programming in itself is only a means to an end. At the end of
the day, you will build software that some people will need to perform
their jobs and hopefully will also find useful and intuitive. If you have
knowledge and experience in the field that you are building software
for, you will be almost irreplaceable. I once worked with a young lady
who, before switching to IT, worked in Human Resources. Since we were
building software exactly for this purpose, she quickly became the go-to
person on the project, and the most knowledgeable among us all. So the
more diverse your experience is, the more you can help.
The Downsides
Since I have talked about the interesting parts of the job, and the common
misconceptions, it’s only right to discuss the potential negative sides of a
programming career as well.
You will always have to learn. Programming is one of those jobs where
it is very easy to get stuck out of the loop. There are always new languages,
new frameworks, and new ways of doing things. I would say that every
two-three years you will change one of the ways in which you are working.
Whether that is the frontend, the backend, the architecture of your app, or
where and how you are deploying, programming means always staying on
top of the wave. That might get tiring at times and can have the potential to
erode your self-confidence.
This also means that you will always find somebody who is better than
you. This comparison applies to everyone in the field. IT is such a large
domain, that there cannot be a single person who knows everything.
You most likely still need some degree. Although it is not absolutely
required, web development is one of those jobs where having a degree
will open many doors for you. But the up side is, as mentioned, you do
not necessarily need to have one in computer science in order to be a
top candidate. A degree in any STEM (Science, Technology, Engineering,
Mathematics) field is usually just as good, and a degree in a more
humanistic domain will still be an advantage. And yes, it is true that you
can still be successful even without a degree. But having one will make
things significantly easier.
Other than that, don’t be afraid to try new things. We are all beginners
in something, when it comes to life in general, and programming is no
different. Every couple of years, technologies tend to change, and better
ways of doing things emerge. Therefore, all of us, no matter how senior we
are, have to learn new concepts and new languages. What makes things
easy is that all of these languages are made by humans, for humans. So if
they did a good job on their side, it is pretty easy to get the hang of things.
Other than the right attitude, to follow this book, you need:
• A computer with Internet access. It does not have to be
a good computer—an old laptop will do just fine. But
the Internet connection is a must.
• Install VSCode. This is a free text editor that you can
download from code.visualstudio.com.
• Install Node.js from nodejs.org. This will be your main
way of interacting with the code.
• Install XAMPP from apachefriends.org. You need this
for the database layer.
That is pretty much it. For most of these installations, just follow the
Next ➤ Next pattern, but if you hit any snags, a quick text search on your
favorite engine will solve most of your issues.
10
11
I do not mean to trivialize the type of requests that you will receive,
but these examples show you the types of tasks to expect at work. Of
course, the more experience you gain, the more you will be included in the
business discussions.
The purpose of this book is simply to familiarize you with the various
building blocks that will enable you to build what you need.
12
13
About once or twice a year I stumble upon an error that I cannot find
on Stack Overflow. This leaves me with two options: either I try to fix it
myself, or I post a question on Stack Overflow and wait for someone to
help me. But bumping into a new error is highly unlikely, especially at
the beginning of your career. Feel absolutely free to search away. The best
programmers are also the best online searchers.
14
JavaScript
Basically, every time that you want to access a web page, you open
your browser and type in the address that you want to visit. This will make
your browser access the server registered for that web address and perform
a so-called handshake. Then the server will take your request, bundle all
the data being sent together by your computer (such as the full URL path,
form data, your cookies, etc.) and decide based on all of these, what needs
to be done with your request.
Once the request is in the hands of the server, it will usually be handled
by the so-called backend. This is the service that is built in order to interact
with the user, usually written in a programming language like PHP, Java,
Python, and so on. If it is the case, this service will then access the database
to retrieve or store additional data (usernames and passwords) or will try
to communicate with other backend services like Google or PayPal using
the APIs provided by the vendors.
Once the backend service has finished processing your request, it will
pack everything up, usually inside an HTML response, and serve it back to
your browser. This includes the data that was requested, as well as the data
needed for display, such as styles, images, and scripts, which your browser
needs to run on your device in order to interact with you.
These scripts are almost exclusively written in JavaScript, and they
contain logic. For example, when a user clicks the Messages button, they
open a popup window and ask the server to display the latest messages for
this user.
16
<html>
<head>
<title>CRM Website</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<h1>My Website Header</h1>
</body>
</html>
Once your system loads the HTML, it will execute the next layer, which
is CSS (Cascading Style Sheets), and which holds data about how the web
page should look. This contains properties such as distances between
elements, colors, backgrounds, and so on. For example, the following code
affects all elements with the custom_element class, but you will learn more
about this in the next chapter.
.custom_element {
background-color: black;
}
However, arguably the most important layer is the logic layer itself,
which is JavaScript. It was initially built in plain JavaScript, and it was
later extended by a library called jQuery, which quickly took over as the
preferred way to develop frontend logic. The jQuery library contained a
number of prewritten functions such as hiding and showing elements,
and sending forms. Now, the most commonly used library is React, which
was initially developed by the Facebook team, and which you will learn in
this book. This framework uses JavaScript to monitor the current state of
17
the page being displayed, and once a certain trigger is activated (such as a
new notification, clicking a button, or new data coming from the server),
it calculates the easiest way to display the changes, without modifying the
entire web page.
The logic layer is responsible for all of the logic inside your page. For
example, going behind the scenes to the server and gathering data in such
a manner that your page does not need to refresh in order to show the
latest data.
The most important part of the JavaScript layer is that it can generate
the other two layers (HTML and CSS) dynamically. That means that within
the execution of your web page on your browser, different parts of the web
page being displayed by your browser will change, appear, or disappear.
Having these abilities led to the one-page applications (also known
as single-page applications or SPAs) that we currently see all over the
Internet. The following code combines HTML and JavaScript:
The backend is everything that happens within the server. Once your
browser reaches out to the server, it will start to compile the data that you
want to send back to the browser. This mostly means fetching some HTML
and JS (JavaScript) pages and serving them, or providing plain data that it has
taken from the database and processed accordingly. This book uses Node.js
as the backend language, but, as I will discuss later, any other option is just as
good. This short code example allows you to connect to the database:
18
Now the question arises: once you finish building your backend, how
do you make it available to other people? Where do you deploy it? And
what is the cloud? In order to answer that, you need to take a trip 20 years
into the past, where if you wanted to host a web page, you would either
do it directly on your computer, or if you could afford it, you would buy a
dedicated computer (server) and keep it somewhere in your basement.
However, with time, it became clear that because of economies of scale,
it made a lot more sense to pay somebody a few bucks a month to go
through this hassle for you. We now have vendors that group thousands of
computers into a single building (called a data center) and sell access to
this gigantic network. This is called the cloud. It’s just basically somebody
else’s computer.
HTML Response
Browser Server
Data JS
CSS
19
HTML Response
Browser Server
CSS JS
The most relevant part of this type of architecture was easy to see when
Facebook changed the messaging system. Before, you needed to go to a
separate tab in order to access Messenger as a standalone application.
But around 2010 they started building Messenger as an integral part of the
experience, so that you could read posts and write comments while still
20
having the Messenger open inside the same page. This was all possible
because, behind the scenes, your browser can talk to the Facebook servers
without the need for you to refresh the page in order to see the latest
messages.
21
React 40.1%
jQuery 34.4%
Angular 23.0%
Vue.js 19.0%
As you can see in Figure 1-5, the backend is where everything changes.
Because the server is completely under control of the developer, the
programming languages that you can use are endless. However, the most
commonly used languages for the backend are PHP, JavaScript, Java,
and Python.
JavaScript 67.7%
Python 44.1%
Java 40.2%
PHP 26.2%
Go 8.8%
22
Summary
A web application is made up of multiple components. The “frontend”
represents everything that runs on the visitor’s device. That is the text
being displayed, and the way the user interacts with the data being sent
back and forth. The “backend” is represented by everything that happens
on the server. That is data manipulation and storage, authentication, and
processing.
As for the languages, they do not matter that much, but you will stick
with JavaScript in this book for the sake of simplicity and of learning
languages that are valuable in the market.
23
SQL Basics
SQL is one of the most important languages when it comes to finding a
job. I have had multiple jobs where my day-to-day work involved writing
complex SQL scripts. So learning SQL means acquiring one of those skills
that takes time to master, but opens a large number of doors.
This chapter teaches you most of what you need to know about
SQL. It takes approximately 2-3 hours in total, but it should take you from
a full beginner to a mid-user level. I have been in charge of interviewing
potential candidates for SQL positions, and I will show you all that you
need to know in order to pass the technical tests.
Imagine you are building a new web app. When it comes to storing
data on your website long-term, you have to use a database. Imagine the
database as an Excel file, where you can use language to interact with the
data. SQL stands for Structured Query Language, and it is a standardized
way of manipulating and interacting with data. There are many types of
databases on the market, including MySQL, Oracle, and Microsoft’s SQL
Server. The difference between all of the offers is minimal in terms of day-
to-day use. In this project, you will use MySQL, as it is easy to install and
free to use.
SQL is a standard language, so anything that you learn about MySQL
will usually apply to any other database that you might use. MySQL
enables you to create tables, insert, update, and retrieve data, and delete
entries.
Note There are also non-SQL solutions that enable you to store
non-structured data. That means that the data being stored does
not need to adhere to a predefined structure, but instead it can hold
all types of objects, containing all types of fields. However, only
16 percent of applications use this approach, as opposed to the
79 percent that use SQL. This chapter focuses on the majority of
use cases.
Installing MySQL
MySQL comes in a bundle called XAMPP. You can download it from
apachefriends.org, and then you have to install the package. Once you
install it, the command interface will appear, where you need to start the
Apache and MySQL services, as shown in Figure 2-1.
28
Let’s look at what you see in the command interface, and what every
process that you start up does:
• Apache is a web server that enables you to interact with
the database using a user interface (UI). It basically
compiles HTML and PHP code and provides it to the
web browser. If you were to learn PHP, you would do it
using the Apache service as well.
• MySQL is a service that runs in the background. It
listens on port 3306 on your computer (this will matter
later), and you can normally interact with it using the
command line. But since that is really cumbersome,
you will be using the UI in these examples.
Once the services start, access the following URL from your browser:
http://localhost/phpmyadmin. This will bring up the UI, and from this
moment on, you can start learning SQL (see Figure 2-2).
29
30
After saving the database, the system will prompt you to start creating
tables. But before you do that, you need to create a logical data scheme for
your application. Based on that, you can create the database layer as well,
and then build the backend on top of it, and finally, the frontend.
With that in mind, this section starts with a general overview of the
types of fields you can choose for a table column. Here are the most
commonly-used ones:
• Integer. This holds whole numbers like 1,2,3… It is also
the default used for the ID that each entity receives, as
it can be auto-incremented.
• Varchar. A variable character is the data type you
use for short strings like email addresses, passwords,
and names.
• Text. You use this for long text data, like comments or
paragraphs. The upside of this type is that it can hold
a large amount of data, but the downside is that it is
difficult to search through, and as a result it should only
be used for storage.
31
Now that you have seen the most used data types, you have to adapt
them into your structure. Which begs the question—what kind of data
exactly do you want to save into your CRM system? This is exactly the point
where building the web application starts—by sketching the database and
the relationships.
I suggest that you start by having some customers—the companies
that you have contracts with. Then a few contacts will be linked to your
customers, to know exactly who to call if you need anything from one of
your customers. And finally, a place to store the users who will log into the
system, together with their data and their passwords.
This data scheme will look something like Figure 2-4.
You will have a list of users that can log in, then a list of customers, and
for each customer, a list of contacts. Also, a single contact can be assigned
to multiple customers, so this relationship goes both ways. One user
will be assigned one customer, but they will have access to see all of the
customers. Then you create a list of contacts, and then a page where you
can assign a customer to a contact.
Before you start, consider the following standards. These are highly-
used in the industry, and will make things clearer for other people using
your database. Those are as follows:
32
user customer
contact
customer_contact_join id – int(8), primary
customer_id - int(8) name – varchar(60)
contact_id - int(8) email – varchar(60)
phone - varchar(30)
createdDate – Datetime
33
34
You need to add the additional columns manually, as initially you only
have space for four of them. Or you can add them at a later point, from the
Structure tab.
Pay attention to the first column, where you need to select the
checkbox for A_I through which the column is identified as a primary
(unique) key, which also means it will auto increment. This will enable
the database to take care of the ID of each entity by auto-generating it and
checking that it is unique.
Note that the join table does not have a primary key, as it is defined by
the relationship between the two sets of data.
By the end of it, if you click the crm name on the left side of the
navigation, you should have a database looking like in Figure 2-7.
SQL Selects
You will first insert some data into the tables. In order to do that, just select
your tables and go to the Insert tab for each of them.
You need to leave the id column empty, but feel free to populate the
rest of the data. You will see that this will populate the data and generate
the SQL code that the app executes in order to insert the data into
the tables.
35
This is a good time to talk about quotes inside SQL. Note the `` back
quotes, which are used for table names and column names, and the ''
single straight quotes, which are used to represent string values. There
are also sometimes "" double quotes, which are used to assign aliases to
tables. You will learn about their functions a bit later.
Now examine the syntax of the previous script. It follows the general
syntax of an SQL query. You have an action that needs to be done, then the
table where this needs to be executed, and then the additional conditions
or values.
Now go to the SQL tab. From there, you can run your queries directly in
text format. Try this:
As you can see in Figure 2-8, the customer with the ID 1 will be
retrieved. That is the nice part about SQL. When you read a query, it is
relatively easy to understand what is happening.
36
But this brings us neatly to a question that might have already popped
into your mind. Is SQL case-sensitive? The answer is no. The code would
work in all caps, or all lowercase, and with or without the back quotes
around the table names.
However, the convention is to use CAPS for anything that has to do
with the SQL language, and use lowercase for anything that has to do with
your data. This just makes thing easier to understand.
In addition, the * (star) part tells the engine to select all columns.
For now, it wouldn’t make much of a difference if you only selected a
limited number of columns, but imagine that you have a table with 200
columns, out of which you extract 10,000 rows. The data transfer would get
overwhelming pretty quick.
Therefore, you can select only the columns you’re interested in with
this command:
As you can see in Figure 2-9, only the columns that you want have been
pulled out of the table.
37
Another skill you need to understand is how search within strings. You
can always write an SQL query like this, and it will work without any issues:
This will perform an exact match search, which in some cases might
be what you are looking for (such as when you’re searching for an email
address). However, an issue appears when you want to search for text
within the data of a column. For that, you need to use the syntax LIKE
instead of the = operator. It provides you with access to the % wildcard, as
follows.
This SELECT only pull out the customers whose names begin with the
letter V, as shown in Figure 2-10.
Similarly, you could write the following query, which searches the
customers for an address containing the country, Spain. You do not need
to select the column in order to query based on it.
This query
will return all of the customers whose addresses contain the word
Spain, at the beginning, the end, or in the middle of the string.
38
Homework
As homework, try to determine what the following queries will return:
Note that when using the AND and OR conditions in the same query, you
should use parentheses, in order to avoid unexpected behavior.
SQL Functions
Inside of an SQL query, you can operate different functions, in order to
retrieve more complex data. For example, imagine that your boss asks you
how many customers you have in the database. The following query will
return the number of rows from the table, shown in Figure 2-11.
As you can see, the name of the column is COUNT(*), which would not
help you a lot if you exported this data and give it to your boss. Therefore,
you can use an alias for the extracted column (see Figure 2-12):
39
This is indeed the place where you must use double quotes. Using
an alias simply makes your column easier to understand and a bit more
user-friendly. You don’t do this only for your users, but also for other
developers, if in a few years you (or someone else) have to go back over the
code and change something.
You can also use functions that sum up data, calculate an average
difference, and so on. For example, suppose you also stored the age of your
users inside the database. You could run the following query in order to
determine their median age:
Or, if you have a table with contracts, you could run this query to
retrieve all of your sales for 2022:
As you can see, writing SQL queries is not difficult at all. It takes a bit of
getting used to, that is true. But you will quickly be able to pull out data that
you need without even thinking twice about the code. That is the beauty of
SQL. If you can articulate it, you can put it in code just as easy.
40
SQL Joins
This might be the most complicated problem of SQL, and the part that
most people have issues understanding. Imagine you have the following
problem: You have a number of users, and each user is assigned to a
certain customer. Holidays are coming, so you ask user to send a letter
to the customer to whom they are assigned. This means that you need
to pull a list of all the users, together with the addresses of their assigned
customers.
In order to do that, you need to do a JOIN operation. This is a way in
which you can pull related data from two different tables at the same time.
First of all, you need to understand the types of joins, which are illustrated
in Figure 2-13.
The type of join basically represents the relationship between data that
is getting get pulled, and also explains which data should get excluded in
the selection. The large majority of joins are LEFT JOINS, so if you ever
don’t know which one to use, try a LEFT JOIN first.
Now for the syntax. You start with a simple SELECT statement from
the base table, and then you join into the second table, by explaining the
condition between the two tables. Therefore, the join will look like this:
SELECT * FROM
TABLE_1 LEFT JOIN TABLE_2
ON TABLE_2.COLUMN = TABLE_2.ANOTHER_COLUMN
41
Pay attention here. You always have a table on the left side of the JOIN
keyword, and always a table on the right side of the keyword. This also
means that one column of first table needs to be left of the = operation, and
one column of the second table needs to be on the right of the = operation.
That makes the query, based on the database, look like this:
SELECT * FROM
user LEFT JOIN customer
ON user.customer_id = customer.id
The query will retrieve all the data found in the first table, user, and for
each row, any data found in the second table, customer.
The LEFT JOIN operation covers a 1:M relationship, and it does this
perfectly. But then this raises the question: What do you do with a M:M
relationship? The answer is simple: you perform multiple joins.
Taking a look at Figure 2-14, you can see that the relationship between
customers and contacts is held together using a pivot table. This means
that you first have to do a JOIN operation from the customer table into the
customer_contact_join table, and then from that point on, link the pivot
table to contact (see Figure 2-15).
42
SELECT * FROM
customer LEFT JOIN customer_contact_join
ON customer.id = customer_contact_join.customer_id
LEFT JOIN contact
ON customer_contact_join.contact_id = contact.id
That is the way that you link multiple joins together. So, once again,
all you have done is one join into the pivot table, and from that point on,
another join into the contact table.
This is likely the most complicated question asked in an SQL interview.
As long as you have all of your joins mastered, you should do just fine in
any technical interview.
Indexes
Say that your business explodes in one year, and now you have over a
million customers. That means that you need to consider the performance
of the entire database.
Imagine that you are running the following query:
43
And imagine the data looking like this inside of the stored table:
ID Name Address
1 BMW Germany
2 Volvo Sweden
3 Tesla USA
4 Seat Spain
… … …
In order to execute the query, the database engine has to open the file
where the data is stored and start looking for the ID column where it is
equal to the value provided. However, since the primary key of the table
is the ID column, the data is already ordered by ID, so the search will be
incredibly fast.
But now imagine that you need to run the following query:
The database will now have to go through the table one row at a time,
and see if the name matches what you need. You can imagine that if you
have one million rows, this would take a while.
Therefore, if you could have a copy of all the rows, stored directly and
sorted alphabetically by name, this could help. That is called an index.
44
This will create a hidden table that will look like this:
Name (Sorted) ID
BMW 1
Seat 4
Tesla 3
Volvo 2
… …
Advantages Disadvantages
45
Summary
SQL is one of the fundamental parts of any web application. It allows
you to save and retrieve almost any type of data that you might need for
your particular cases. It also allows you to parse through the complex
connections that data possesses, by using JOIN statements.
Since it is one of the primary building blocks of the entire web, there
are multiple jobs that almost exclusively require SQL, such as business
analyst. Learning this skill alone will put you at an advantage in the
job market.
46
HTML
HTML is historically the way that the Internet was built. It is not technically
a programming language, but a way to store and transfer structured
data. This is because it cannot manipulate anything, and it is not
dynamic. Regardless of that, HTML (HyperText Markup Language) is the
building block of the Internet. The structure of HTML is relatively easy to
understand, as it involves two things: tags and attributes.
The language is made up of tags containing other tags. This is what
gives HTML its structure. Consider this code for example:
<exampleTag sampleAttribute="my_text"></exampleTag>
Here, you can see an opening tag called exampleTag that has an
attribute called sampleAttribute, and then a closing tag for exampleTag.
The </exampleTag> part at the end is called an “end exampleTag” because
of the slash at the beginning, and then the name of the tag.
Let’s create a simple web page. Open your VSCode application (or any
other code editor of your choosing) and create a file called index.html. In
that file, create this small website:
<html>
<head>
<title>CRM Website</title>
</head>
<body>
<h1>CRM Website</h1>
<p> Welcome to our website. You can go
<a href="www.mywebsite.com">here</a> in order to
see our big
<b>PROMOTION!</b>
</p>
</body>
</html>
The code that you just wrote will generate a web page like the one in
Figure 3-1.
Once the file is ready, you can go inside of VSCode to the upper menu,
select Run, and then select a browser. Or you can simply go inside of your
Windows Explorer and double-click the file. This will open the code and
render it.
48
Now I’ll deconstruct a bit what you are seeing here. First of all, an
HTML page will always have the <html> tag as a parent, in which you will
always find the <head> and <body> tags. These tags are mandatory, so
they will always need to be present. If you for some reason omit them, the
browser will generate them when executing the code. In the head of the
page, you will find tags like <title>, which contains meta-information
about the website, as well as links to CSS and JavaScript code. The main
role of the head tag is to provide data used by the browser, or various
scripts that read the page, like the crawlers that Google uses.
The <body> tag is where the majority of data is stored. Here is where
you find header tags such as <h1>, <h2>,… <h6>, paragraph tags (<p>) and
links, also known as anchors (<a>), and links that store a hyper-reference
attribute (href). You will also find tags used for text formatting, such as <b>
for bold, <i> for italic, <u> for underline, and so on.
There are many, many tags that can be interpreted by your browser,
and you can find a more comprehensive list at w3schools.com/html. This
section goes through a few examples of the most commonly used tags and
explains what they mean.
An image can be built like this:
Notice the / (end tag) at the end of the tag. This means that the tag is
self-contained, as some of them are. This is equivalent to writing:
Your browser will understand it just fine if you forget the ending tag
and leave it open.
Since HTML is supposed to be the way that your computer talks to the
Internet, the syntax is not as strict as in some other languages. That way,
your browser can render most anything that it comes in contact with.
49
You can create an ordered list <ol> or an unordered list <ul>, and both
will contain list items under the <li> tag.
One of the most commonly used HTML tags is the <div> element. It
simply represents a division inside the HTML block and does not render
anything special, other than a new line. But combining it with CSS and JS
makes this one of the most powerful tags:
There are two highly important attributes in web that are widely used
and that can be attached to any tag. The class is used in styling, and inside
of this attribute you can provide multiple classes, delimited by a space. The
id attribute is an identifier that needs to be unique inside of the web page.
As you can see, HTML is not a very complicated part of web
development, and you can be learn the basics in a few hours. As you
advance in your career, you might find yourself needing different tags, so
don’t be afraid to research things on your own.
CSS
Cascading Style Sheets (CSS) make up the web layer that offers, as the
name suggests, the option to provide styles to your web page. This code
generally looks like this:
50
.class {
background-color: red;
}
The language follows a pattern that can be described like this: it begins
by defining what exactly should be affected. If it starts with a dot ., it
means it will affect the class. If it starts with a hashtag #, it will be related to
the ID, and if there is no character in front of the description, it is related to
the HTML tag:
In the CSS language, you start by opening the curly brackets. You
then list a property that you want to change, then a colon, and then the
new value that you want to give it to it. Then you end each row with a
semicolon (;).
All of this should be surrounded by a <style></style> element tag
within the <head> part of the web page:
<html>
<head>
<style>
html {
background-color: #ffaaaa;
color: #ffffff;
}
.header {
font-size: 18px;
}
#some_id {
color: #00ff00;
}
51
</style>
<title>CRM Website</title>
</head>
<body>
<h1 class="header">CRM Website</h1>
<div class="custom_class" id="some_id">
This is my div
</div>
<p class="class">Why we are good?</p>
</body>
</html>
As you can see, you start by applying styles to the <html> tag. Doing
this will apply a background to the entire web page, seeing how the <html>
tag is the parent tag of the whole content.
In this case, you only played around with the colors of the web page,
but the most important part of using CSS is the layout. This will enable you
to place different elements, one into the other, and arrange the structure of
the page.
52
You will now see how to add colors to the elements, just so you can
understand this process. For your actual website, you will choose better
looking colors.
<html>
<head>
<style>
.parent_class {
background-color: #ccffcc;
text-align: center;
padding: 30px;
}
.child_class {
background-color: #ffffff;
text-align: center;
padding: 10px;
font-size: large;
font-weight: bold;
}
</style>
<title>CRM Website</title>
</head>
<body>
<div class="parent_class">
<div class="child_class">This is the child class</div>
</div>
</body>
</html
53
As you can see in Figure 3-3, there is a white border around the green
div. This happens because the <html> tag has a padding applied to it by
default.
If you want to get rid of that border, you need to add the following code
to your style:
html {
padding: 0;
}
Bootstrap
Judging from what you just learned about CSS, if you start to build a few
websites, you will easily see how, every time you start working on a new
one, you have to create the same elements over and over again. These
elements are, for example, navigation bars, alerts, styled buttons, layout
54
elements, and so on. This is why Twitter decided to build a framework that
offers prebuilt website elements, a framework that has quickly become one
of the building blocks of the entire web ecosystem.
That framework is called Bootstrap, and it is one of the most commonly
used CSS frameworks. It basically provides you with a list of preformatted
classes that you can add to your elements.
In order to start using Bootstrap, you need to go to the website,
getbootstrap.com, and see the offer of elements that they have
listed there.
The documentation states that in order to get started, you just need
to add two links to the <head> tag and you will be all set. Sounds simple
enough, so try it:
<html lang="en">
<head>
<!-- Required meta tags for mobile -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-
scale=1" />
<!-- Bootstrap CSS -->
<link
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/
css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHft
jDbrCEXSU1oBoqyl2QvZ6jIW3"
crossorigin="anonymous"
/>
55
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/
js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+
IlRH9sENBO0LRn5q+8nbTov4+1p"
crossorigin="anonymous"
></script>
</head>
<body>
<!-- Our code starts here -->
<h1>Hello, world!</h1>
</body>
</html>
The meta tags are used here to provide mobile support and proper
international characters and help for mobile devices, and the script
element is just a JavaScript library that makes the framework function, as
you can see in Figure 3-4.
Okay, this is not very impressive, so you can start to add bootstrap
elements into your web page. It is simply a matter of copying/pasting
elements from the documentation into your website. Figure 3-5 shows an
example from the documentation that they provide.
56
If you simply copy the code into your website, you get Figure 3-6.
I want to talk a bit about layouts. Bootstrap will enable you to split your
website into 12 equal columns. Out of these, you can choose if your <div>
element will take up the width of one column, multiple columns, or all 12,
so that the width will cover the entire row. You can just choose the width
by providing the appropriate class. Figure 3-7 illustrates this.
57
If you want to add three distinct columns, for example, you just have to
add this text:
<div class="container">
<div class="row">
<div class="col">1 of 3</div>
<div class="col">2 of 3</div>
<div class="col">3 of 3</div>
</div>
</div>
58
Homework
Create your own website using Bootstrap:
1. Go to w3schools.com/bootstrap/bootstrap_
templates.asp and choose a basic template for your
website.
2. Go to getbootstrap.com and choose different
components to add to your website.
3. Have fun and get creative!
Summary
HTML and CSS are the building blocks of any website. If you only need a
static website, adding Bootstrap to it might be the fastest way to achieve
what you need. The chapter only briefly touched on all of the possibilities
that using HTML and CSS bring with them, and there are entire books
covering these subjects. Trying things on your own will provide you with a
lot more insight. So this is what I encourage you to do. Try to create a static
website and just have fun.
59
GraphQL
and JavaScript
Before you move on to building your app, you need to learn a bit more
about the technologies at the core of most modern web applications. This
chapter covers JavaScript, the programming language that you will use in
your project, as well as GraphQL, which is the modern way to transfer data
through an Application Programming Interface (API).
GraphQL
GraphQL is a way in which you can communicate with the server side of
an application, in order to send and receive data. It is currently one of the
newest and most commonly used technologies for interfacing with data
between applications, and it is fundamentally the way that your frontend,
be it a browser or a mobile app, will communicate with the server side.
Before you start learning about GraphQL, this section explains how
things were done before this new technology came along, when most
APIs used the RESTful protocol for data transfer. This worked in the
following manner.
When you’d call for a certain URL, the server would provide you with
an encoded block of data in JSON format, as shown here. The content and
format of this data was decided by the server backend alone:
http://my-website.com/mydata/clients
{
totalReturned: 2;
clients: [
{ name: "Client1", id: 1 },
{ name: "Client2", address: "Park Lane 71" },
];
}
62
{
clients {
id
name
address
}
}
The server will return the data that you requested, but only the fields
that you specified:
{
"data": {
"clients": [
{
"id": "1",
"name": "Company1",
"address": null
},
63
{
"id": "2",
"name": "Company2",
"address": "Park Lane 71"
},
]
}
}
You can also provide variables to queries that you send separately,
such as:
Mutations, on the other hand, are the way that you send data to the
server. In order to, for example, create a new client in your database. They
are basically functions that you call on the server side. They may or may
not return useful data, depending on what you need them to do, but they
will throw an error if any issues pop up during execution.
mutation {
createClient(name:"Big Client", address:"Hall Alley, 54")
}
64
JavaScript
This section looks a bit at the most commonly used programming
language in web development: JavaScript. It includes a short introduction
to the language as it is, and helps you get familiar with the quirks and
specific parts of JavaScript.
So what is JavaScript, and how is it different from all the other
languages?
JavaScript is a scripting language (meaning that the code is not
precompiled) that’s derived from the Java programming language, hence
the name. It was built to be a short, easy way to make a browser do more
intelligent things than just display text. It has slowly evolved into one of the
backbones of the modern Internet.
The only downside of JavaScript, and I would also say the major
disadvantage, is that it takes some practice to get accustomed to the way it
is used. It is pretty different from all of the other major scripting languages,
like PHP and Python.
Since you have to use it in the frontend either way, because it is the
only language that browsers understand, you might as well use it on the
backend of your application as well.
65
Functional Programming
JavaScript is executed “as it comes,” so to say. That means that it is
interpreted line by line and executed. However, JavaScript also relies
heavily on functions. It does this to such an extent that most functions will
rely on accepting another function as a parameter, within the broad usage
of the language. You can see this in this example showing what a function
looks like in JavaScript:
function addNumbers(a,b){
return a + b
}
This function will take two numbers as parameters and return their
sum. It is one of the most basic functions in JavaScript.
console.log(addNumbers(2,3)) //prints 5
In order to test this code, open any browser and press F12 (or right-
click and choose Inspect) to open the developer tools. Go to the Console
tab and add this JavaScript code. The console will then output anything
that you set in the console.log() function parameters, as you can see in
Figure 4-1.
66
You can also write a function that takes another function as a parameter:
console.log(doubleFunctionResult(addNumbers, 2, 3))//prints 10
const num1 = 10
num1 = 15 //not allowed
If, however, you need to reassign a value, you need to use variables by
either using the let keyword or var, which is not recommended:
The main difference between var and let is that a let element will
only hold its name and value within the block of code that it is assigned
to, whereas a var element can “leak” through the rest of the code, possibly
leading to unpredictable behavior. As a result, you should always use the
let keyword to declare a variable.
A const is better than a variable because it will use less memory. It will
also ensure that you don’t overwrite something that you don’t want to. So
you should also try to use const whenever it makes sense.
67
Functions
There are two distinct ways to declare a function in JavaScript, each with its
own variations. They both do essentially the same thing. Consider the first
example again, which you saw earlier:
This is the classic way of declaring a function, but there is a faster way:
All of these ways of writing functions basically do the same thing, but
declaring a function as a constant is currently the preferred way, mostly for
consistency.
Shorthand if Statements
You can write an if statement in JavaScript, just as you can do in any other
language.
68
if (message.includes("error")) {
return " There is an error"
} else {
return "ALL OK"
}
A
rrays
JavaScript goes through collections (arrays) of various data structures. Or
better said, it parses them. This is because most of the data that will come
from the database layer will be in the form of arrays (also known as lists).
Imagine you have a collection of customers:
const customerArray = [
{
id: 1,
name: "Factory Sky",
},
{
id: 2,
name: "Gel Producer",
},
69
{
id: 3,
name: "Distribution",
},
];
You can now access each customer by referencing the index within the
array, starting with 0. Arrays always start from the index 0:
However, imagine that you need an array of all the customer names
alone. You can write a function in the “normal” way to do that. It would be
the same block in JavaScript, Java, Python, PHP, or any other language:
An even shorter version enables you to rename the variable from the
function:
70
the function passed as a parameter to the map function. If, however, you
just want to loop though some data and execute code, but not return
anything, you will use the forEach function in exactly the same way:
customerArray.forEach((customer) => {
console.log(customer.name + " - " + customer.id);
});
This is equivalent to the for loop that you built previously. The
forEach function does not necessarily need to return anything, as it
will loop though each customer and execute the function provided as
a parameter, which in this case just logs the name and ID. But this also
means that no new array is generated and returned, so you cannot assign
the outcome of the forEach function to anything.
71
Destructuring works in exactly the same way for arrays as for objects.
You just replace the parentheses with square brackets.
The spread operator can be seen as the sibling operator of the
destructuring process. The spread operator spreads the properties of an
object. If you create a new customer like this:
const customer = {
name: "Customer1",
address: "Parkway Avenue 71",
id: 1,
};
const newCustomer = {
...customer,
id:2,
balance:100
}
This will make your new customer look like the following code. You
can see that the spread operator enables you to add new properties and
reassign existing ones.
newCustomer : {
name: "Customer1", //previous properties will be transferred
address: "Parkway Avenue 71",
id: 2, //new values will also be here
balance:100 //new properties
};
72
Promises
A promise in JavaScript is a way to tell the code to execute a piece of code
asynchronously. That means that the execution will not stop and wait
for the code to finish, but will continue to run other things in parallel.
You then need to tell the script what to do, once the promise has been
completed or has errored out.
Imagine, for example, that you have a piece of code with a function that
needs to retrieve some customer data from the server: getCustomerData().
Suppose that this call takes four seconds.
If you write a piece of synchronous code, the execution will stop until
the data is returned:
With that in mind, it is easy to see why you would not like for your code
to stop executing just because something is loading. That would mean that
buttons will no longer work, and generally, the page would freeze.
There is a different way. You can create the function to be
asynchronous and tell JavaScript not to wait for it:
getCustomerData().then((customerData) => {
console.log(customerData); //would run after 4 seconds
});
allowUserToSeePhotos(); //would run immediately
The then() part means that you want this code to execute once the
promise is returned from the other function. If needed, you can chain
then() statements together, to execute them in a certain order. You can
also chain into the promise a way to catch errors, and a code to execute at
the end, regardless of whether the code ran successfully or failed.
73
getCustomerData()
.then((customerData) => {
console.log(customerData);
})
.then((customerData) => { //runs after the first 'then' block
getCreditCardInformation(customerData.emailAddress)
})
.catch((err) => console.error(err.message))//print Error
.finally(() => { //always runs at the end
connection.close()
});
Summary
JavaScript is a complicated language. Everybody knows that. We all
struggle with JavaScript, from beginners to senior developers. It is because
it is so versatile and has so much history that it looks complicated. But with
enough experience, I promise you that it all starts to make sense. You just
need to have the patience to get over the first few challenges.
74
The Backend
The backend is the part of the application that happens entirely inside of
the server. This is the part that holds the information needed to run the
website, the part that processes it, and that displays it for the users. The
backend is the system that remembers your data, even if you log in from
a different machine, and that informs you about your friend’s updates on
your feed page, about new job postings, or about events around your area.
Although, honestly, this project would not look that different using plain
JavaScript. Modern-day web development requires TypeScript for almost
all large applications, so I think it is a good idea to get accustomed to
TypeScript directly, where you can.
You will be building the backend part of your application using Node.
js. As a result, the first step is to install Node.js. To do that, go to nodejs.
org and download the package from the Download section, which you
should then install.
Once that is done, create a new project by following these steps:
1. Open a console by going into Windows. In the
search at the bottom left, type cmd.
76
"scripts": {
"start": "ts-node index.ts",
"build": "tsc"
},
This will enable you to type npm start into your console, and that will
run your program.
Since TypeScript needs some configuration of its own, you now need
to create a file called tsconfig.json and add the following to it:
{
"compilerOptions": {
"lib": ["es5", "es6", "DOM"],
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"outDir": "./build",
"emitDecoratorMetadata": true,
77
"experimentalDecorators": true,
"sourceMap": true,
"types": ["node"]
}
}
Once again, do not worry too much at the moment about what all
that these commands do. They are part of the documentation, and to be
honestly, I myself could not tell you without searching for them.
Now that you are done with the platform setup, it is time to start
building your app. In the backend folder, create a file called index.ts,
which will hold the following code:
app.use(
"/graphql", // the URL that we will access
graphqlHTTP({
schema, // the place where we will define our queries and
mutations
graphiql: true, // automatically provide us with a UI
})
);
app.listen(3000, () => {
console.log("Server is running at port 3000");
});
Running this code will start an application, open a port, and enable
you to connect to the GraphQL endpoint. As you can see in Figure 5-1, this
is just the basic configuration of what should be accessible.
78
After you are done with the initial application, you create a folder
called schema and, inside the folder, create a file called schema.ts. This is
where you will define your queries and mutations, and how exactly they
are going to behave. You also need to define what the objects that you are
returning look like, and how they link to each other.
79
You can now go into your console and start the GraphQL server:
npm start
80
Homework
Set up your own backend:
81
82
Now you can write the query, and it will retrieve the data that you
provided (see Figure 5-3).
You can later use this data in the frontend to display a list of customers.
You will develop that part of the application in the next chapter.
Note When calling a query, the part at the beginning that surrounds
the query code (query getCustomers) is placed in that location
so you can reference the query later. You can name that part of the
query anything you want, as it enables you to have multiple queries
running into the same backend point.
83
connection.manager.find(Customer)
{
"type": "mysql",
"host": "localhost",
"port": 3306,
"username": "root",
84
"password": "",
"database": "crm",
"entities": ["entity/*.ts"], //what our files look like
"cli": {
"entitiesDir": "entity" //name of the ORM folder
}
}
In the next step, you need to define the data model. You need to tell
the ORM which tables it needs to connect to, and what data to pull out
of them.
Inside of the backend folder, create a new folder called entity, as
you defined in the last rows of your configuration file. You will add all
of your entities to this folder. These entities will mostly map one-to-one
to the tables (one entity per table). In this folder, create a new file called
customer.ts:
@Entity("customer")
export class Customer {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
address: string;
85
Note the decorator (the part that starts with an @ symbol) before every
property, which tells the ORM which parts map to what.
Now that you have set up the connection to the database and the entity
mapping into the table, it is time to create a function that will retrieve the
data and feed it into your GraphQL framework.
Inside the backend folder, create a new folder called service. In the
service folder, create a file called characterService.ts.
Note It’s a good idea to put all of the application logic in what is
called the service layer. This is the part of the application that will
connect to the DB layer and process the data, before serving it to the
GraphQL presenter. All of the files that contain such logic will be held
in the service folder.
import "reflect-metadata";
import { createConnection, SimpleConsoleLogger } from
"typeorm";
import { Customer } from "../entity/customer";
return customers;
})
.catch((error) => console.log(error)); // log an error if
we find one
}
86
Note the async definition inside of the functions. This is the major
advantage of using Node.js, which is that while the process waits for the
database to fetch the data, it does not stop execution, but allows other
processes to run at the same time. This type of parallelism makes Node.js
a great choice for large software applications with lots of users accessing
them at the same time.
You now need to restart the application, so the new code will be
compiled and executed. Running the query again, you will see that the
data that you receive is different from what you had before:
npm start
As a result of these changes, you now have data pulling directly from
the database and offering you a list of all the customers that you added to
the database (see Figure 5-4).
87
Figure 5-4. Running the first program that connects to the database
Homework
Set up your own backend to interact with the database:
This is relatively easy to do, since you have it all set up. Open the
.schema/schema.ts file and add the following code:
...
const RootMutation = new GraphQLObjectType({
name: "RootMutationType",
fields: {
createCustomer: {
type: CustomerType, //return the newly created customer
args: { name: { type: GraphQLString }, address: { type:
GraphQLString } }, //we take the name and address as
arguments/inputs
resolve(parent, args) {
return createCustomer(args.name, args.address);
},
},
},
});
89
await connection.manager.save(customer);
connection.close();
return customer;
})
.catch((error) => console.log(error)); //catch any error
}
That is mostly it. When you call the mutation, you will create a new
Customer object, and then you will set the fields that you are interested in,
save them using the ORM, and return the object, together with the ID that
you just inserted in the database.
90
You simply need to restart Node.js using npm start and you’ll be
finished (see Figure 5-6).
Homework
Set up your own backend to interact with the database:
91
Summary
This chapter explained how to the set up and develop the backend section
of your application. You also read an overview of the various components
that make up a modern backend application. In addition to this, you
learned about the way that data flows in and out of the system, using
GraphQL queries and mutations.
There are, of course, a large number of features, tests, and
configurations that involve making such a system production-ready. But
the aim of this chapter is to give you enough information and examples,
so that you can continue to explore the beautiful world of backend
development on your own.
92
The Frontend
The frontend is the part of an application that simply brings it to life. It is
the interface through which the users interact with all of the functionalities
being offered to them. It is no secret that for me personally, the frontend is
my favorite part of web development. There are so many things to build in
the frontend and so many to improve—so many tiny design decisions that
are instantly visible to the end users and so many user experience concepts
that can be implemented. Because of its high visibility, the frontend is also
the part that needs the most maintenance.
For any application, a backend that is ten years old, if initially built
correctly, will most likely continuously work without needing to be
touched. But designs change every two-three years, so that means that
your frontend needs to stay in line with the times.
Frontend development as a concept can seem contradictory. On the
one hand, it is the part of web development that is the most complicated.
It always needs new frameworks and new libraries, and it is generally
cumbersome and has a steep learning curve.
But do not let that fool you! The frontend is also the part that feels
the least like programming. You constantly have to talk to the users and
representatives, brainstorm for designs, gather feedback, and generally be
prepared to do all types of adjacent tasks in relation to programming. This
chapter looks at what exactly the frontend is in a modern application.
94
95
There is no need, at the current time and for your current application,
to set up a complicated project, so that you can validate it with your users.
A short sketch will do just fine, for now. But note the design that you just
made, as you will learn to implement it in React in the following chapters.
The Setup
You will be building your frontend application using React, so the first step
is to set up the project. In order to do that, go to the command line and
navigate to the crm folder. Then you just run the command to create a new
React project. This command will also create a new folder:
Then, if you change the directory to the new frontend folder, you can
see all of your files (see Figure 6-2).
96
97
import './App.css';
function App() {
return (
<div>
</div>
);
}
Then, inside of this file, add a header as the title and a div containing
the details related to your clients.
function App() {
return (
<div>
<h2>Clients</h2>
<div className="client_border">
<p>
Name: <b>Client1</b>
</p>
<p>
Address: <b>Park Avenue 71</b>
</p>
<p>
Date Created: <b>01-Dec-2022</b>
</p>
</div>
</div>
);
}
98
Note that in React, the word class is reserved, so use the keyword
className as an attribute, in order to provide a rendered element with
a class.
Then go into the App.css file and delete everything, so that you can
add the CSS for your app:
.client_border {
border: 1px solid black;
}
If you open your browser now, you can see how the app currently looks
when it’s being accessed (see Figure 6-4).
99
If you now look at your Figma design, you can see that you have two
columns. One for the clients and one for the button. The current design
only holds each element to have 100 percent width. This is a perfect
moment to bring Bootstrap into the picture.
Bootstrap enables you to add better CSS to everything and provides
you with access to a large number of prebuilt React components.
Head to react-bootstrap.github.io and install the node library
according to the instructions there. It is as easy as simply running the npm
install react-bootstrap bootstrap command and then restarting your
frontend server. (The URL will have a large number of examples in the
documentation.)
Now, going to the documentation, you can see that you need to simply
add a <row> and <col> element to achieve your layout (see Figure 6-5).
100
You can also go into the documentation to find a button that you can
use to create the customer.
This now brings you to the following code for your ./frontend/
src/App.js:
import "./App.css";
import "bootstrap/dist/css/bootstrap.min.css"; // Imports CSS
import { Container, Col, Row, Button } from "react-bootstrap";
// Imports bootstrap elements
function App() {
return (
<Container>
<h2>Clients</h2>
<Row>
<Col xs={10}>
<div className="client_border">
<p>
Name: <b>Client1</b>
</p>
<p>
Address: <b>Park Avenue 71</b>
</p>
<p>
Date Created: <b>01-Dec-2022</b>
</p>
</div>
</Col>
<Col>
<Button variant="primary">Create New</Button>
</Col>
101
</Row>
</Container>
);
}
As you can see, the page does not contain any dynamic text, meaning
that you cannot currently influence the way the page looks just by the code
(see Figure 6-6). You will add this functionality a bit later.
102
The only problem is that you need to know when to display the modal
and when not to. Since you cannot have the modal always on, you need
to know when the button was clicked, and when the modal should be
closed. This brings me neatly to the moment where I need to introduce
React states.
This is likely the most complicated part of React, and it is what makes
this framework different than anything else. So what exactly are states?
How do they work, and how are they different?
States are variables that are controlled by the framework. They can
only be set or changed by using the setter functions, and whenever you
change them, the change is asynchronous, meaning it will not happen
instantly, but at a certain point in the future.
The first step to using a state is to import the function from the
framework:
103
This means that you will have a variable called isModalVisible and a
function called setIsModalVisible. The default value of the variable will
be false because that is the value provided as a parameter to the useState
function.
Now, just to test your code, you can write a paragraph that will be
displayed only if this variable is set to true.
This means that the module called react exports a list of multiple
properties, out of which you only need the useState one.
Using a variable and the && sign means that if the variable resolves as
true, continue reading the code, but if it is false, stop the execution and
move on. It is basically a short, condensed if/else.
Now it is time to return to the popup modal:
import "./App.css";
import "bootstrap/dist/css/bootstrap.min.css"; // Imports CSS
for bootstrap
import { Container, Col, Row, Button, Modal } from "react-
bootstrap"; // Imports bootstrap elements
104
function App() {
const [isModalVisible, setIsModalVisible] = useState(false);
return (
<Container>
<h2>Clients</h2>
<Row>
<Col xs={10}>
<div className="client_border">
<p>
Name: <b>Client1</b>
</p>
<p>
Address: <b>Park Avenue 71</b>
</p>
<p>
Date Created: <b>01-Dec-2022</b>
</p>
</div>
</Col>
<Col>
<Button variant="primary" onClick={() =>
setIsModalVisible(true)}>
Create New
</Button>
</Col>
</Row>
105
<Modal
show={isModalVisible}
onHide={() => {
// we simply call the setter with the new value, when
closing the modal
setIsModalVisible(false);
}}
>
<Modal.Header closeButton>
<Modal.Title>Create New Customer</Modal.Title>
</Modal.Header>
<Modal.Body>
<p>Modal body text goes here.</p>
</Modal.Body>
<Modal.Footer>
<Button
variant="secondary"
onClick={() => {
setIsModalVisible(false);
}}
>
Close
</Button>
<Button variant="primary">Save changes</Button>
</Modal.Footer>
</Modal>
</Container>
);
}
106
After you click the Create New button, your application will look like
Figure 6-8.
The best part of using states in React is that when a state is updated,
the framework will calculate what type of changes need to be made, in
order for the web page to be brought to the new state. Then React will only
perform those minimal changes.
This is the reason that, by using React, you can start building single
page applications. Because you won’t need to refresh the page every time
you need to pull some new data in. You don’t redirect users to new pages;
instead you display everything on a single page.
107
108
<Modal.Body>
<p>Modal body text goes here.</p>
</Modal.Body>
<Modal.Footer>
<Button
variant="secondary"
onClick={() => {
setIsModalVisible(false);
}}
>
Close
</Button>
<Button variant="primary">Save changes</Button>
</Modal.Footer>
</Modal>
}
Now, you just need to go into the App.js and import the new
component in the head.
Then call it with the proper parameters, replacing the previous modal
code, which is now found in the new file.
<CreateCustomer
isModalVisible={isModalVisible}
setIsModalVisible={setIsModalVisible}
/>
109
app.listen(3100, () => {
console.log("Server is running at port 3100");
});
110
app.use(cors());
app.use(
"/graphql", // the URL that we will access
graphqlHTTP({
schema, // the place where we will define our queries and
mutations
graphiql: true, // automatically provide us with a UI
})
);
app.listen(3100, () => {
console.log("Server is running at port 3100");
});
You need to have two command lines open, one for each process. So,
for the backend, you can simply launch the application.
In order to connect to the backend using GraphQL, you need to
instantiate the Apollo library, so you follow the documentation steps from
https://www.apollographql.com/docs/react/get-started/
111
In order to run Apollo on the frontend, you need to run the following
command in the frontend folder:
Now add the library to .frontend/index.js and then pass it to all the
child elements:
ReactDOM.render(
<React.StrictMode>
<ApolloProvider client={client}>
<App />
</ApolloProvider>
</React.StrictMode>,
document.getElementById("root")
);
reportWebVitals();
112
import "./App.css";
import "bootstrap/dist/css/bootstrap.min.css"; // Imports CSS
for bootstrap
import { Container, Col, Row, Button } from "react-bootstrap";
// Imports bootstrap elements
import { useState } from "react"; // import state from React
import CreateCustomer from "./CreateCustomer";
import { useQuery, gql } from "@apollo/client";
function App() {
const [isModalVisible, setIsModalVisible] = useState(false);
const { loading, error, data } = useQuery(GET_
CUSTOMERS_QUERY);
return (
<Container>
<h2>Clients</h2>
<Row>
<Col xs={10}>
{data &&
113
data.getCustomers.map((client) => {
return (
<div className="client_border">
<p>
Name: <b>{client.name}</b>
</p>
<p>
Address: <b>{client.address}</b>
</p>
<p>
Date Created: <b>{client.dateCreated}</b>
</p>
</div>
);
})}
</Col>
<Col>
<Button variant="primary" onClick={() =>
setIsModalVisible(true)}>
Create New
</Button>
</Col>
</Row>
<CreateCustomer
isModalVisible={isModalVisible}
setIsModalVisible={setIsModalVisible}
/>
</Container>
);
}
114
As you can now see, importing from the Apollo library will give you
three variables: a loading variable, which is set to true when the data is
loading, an error variable, which is normally null, but will contain an
error in the eventuality that you receive one, and a data variable, where the
result of your query is stored. You then run a map function over the data,
and that will create a div element for each customer in your database (see
Figure 6-9).
If you open the console in your browser, you can see the network call
to the backend, and the data that came back. Just right-click the page and
choose Inspect. Then go to the Network page (see Figure 6-10).
115
Also, in order to debug your React code, you can install an extension
for React in your browser. Just search for “React Developer Tools” in your
browser’s extension page and install them. This will give you access to a
new tab, where you can see the states of each component that you built
(see Figure 6-11).
Name of our component Data pulled from GraphQL into our state
116
But first, you need to add a new property to the query in App.js, so
that you have a function that fetches the query on your command. You will
then call this function after you push a mutation, so you always display the
latest data from the database.
const {
loading,
error,
data,
refetch: refetchQuery,
} = useQuery(GET_CUSTOMERS_QUERY);
You will then provide this new function as a parameter when you
render your component:
<CreateCustomer
isModalVisible={isModalVisible}
setIsModalVisible={setIsModalVisible}
// It is up to us what we name this parameter
refetchQuery={refetchQuery} />
117
return (
<Modal
show={isModalVisible}
onHide={() => {
// we simply call the setter with the new value as a
parameter
setIsModalVisible(false);
}}
>
118
<Modal.Header closeButton>
<Modal.Title>Create New Customer</Modal.Title>
</Modal.Header>
<Modal.Body>
Name
<Form.Control
value={customerName}
onChange={(e) => setCustomerName(e.target.value)}
// e is here an event, so we get the value of the
change event
/>
Address
<Form.Control
value={customerAddress}
onChange={(e) => setCustomerAddress(e.target.value)}
/>
</Modal.Body>
<Modal.Footer>
<Button
variant="secondary"
onClick={() => {
setIsModalVisible(false);
}}
>
Close
</Button>
<Button variant="primary" onClick={saveCustomer}>
Save changes
119
</Button>
</Modal.Footer>
</Modal>
);
}
All of these changes will lead to a modal like the one in Figure 6-12,
once you click the button to create a new customer. Saving the customer
will call the mutation, which in turn, will save the data to your database.
Homework
Set up the connection between your backend and your frontend:
120
Summary
In this chapter, you learned how to build a modern frontend solution using
React and Bootstrap, and how to connect it to a backend system using
Apollo. The most important part of building a modern frontend system is
choosing a framework, and at the moment, React is your best bet.
I encourage you to take some time and go through the homework
in this chapter. Even try to expand the application a little bit. The main
purpose of this chapter was to offer you the fundamentals of frontend
development, and it is entirely up to you to discover more about the
particularities of JavaScript and React.
After all, a modern backend system can only transmit some JSON
encoded data, and it is up to a skilled frontend developer (hopefully you!)
to transform that long JSON data into a well-rounded and user-friendly
application.
121
Going Fullstack
In the last chapter, you left your system with the following features: the
ability to list all the customers inside the database, and, with the help of a
popup, the ability to create a new user. The application currently looks like
Figure 7-1.
Now imagine that your Project Manager assigned to you two tickets
that you need to finish by the end of the week. These tickets are:
1. Make a better design. The users have complained
that even though the system works as it should, it
does not look pretty. You need to make the system
look more “modern.”
With these two tickets assigned to your name, you are now officially a
fullstack developer. Hooray! The next sections explain how to achieve what
your team needs from you, as well as how to deliver what your customers
request from you.
124
As a result, you will just copy/paste the code from the documentation and
change the name of the links. This will meet your current navigation needs.
This will make the ./frontend/src/App.js file look like the following code.
Pay attention to the fact that you are using two new Bootstrap
components, namely <Navbar> and <Nav>, and as a result, you need to
import them into the file.
125
h2 {
margin: 20px 0 15px 0 !important;
}
With that being done, your application now looks like Figure 7-3,
which is already significantly better.
But you are still left with the entire list of customers, which doesn’t
necessarily look pretty at all.
One idea is to list them in a table to have it at least more organized and
easier to understand. Such an approach would look like Figure 7-4, and I
may add that it is not too bad. To achieve such a result, Bootstrap provides
a table component that is lightly stylized, making it a decent option.
126
Figure 7-5. The table that Bootstrap has to offer to the React
application
127
That being said, you simply need to import it to use the <Table>
component provided by Bootstrap:
...
<Row>
<Col xs={10}>
<Table striped bordered hover>
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>Created</th>
</tr>
</thead>
<tbody>
{data &&
data.getCustomers.map((client) => {
return (
<tr>
<td>{client.name}</td>
<td>{client.address}</td>
<td>{client.dateCreated}</td>
</tr>
);
})}
</tbody>
</Table>
</Col>
<Col>
<Button variant="primary" onClick={() =>
setIsModalVisible(true)}>
Create New
128
</Button>
</Col>
</Row>
...
The table approach does make the application look better, and you
can certainly leave things like they are now. But I believe that you can do
an even better job, when it comes to the design of your application. My
personal approach would be to use some sort of card system to list all the
customers. This would be similar to the analog business cards used in the
physical world.
Again, going to Bootstrap, you find exactly what you need, from the
<Card> component (see Figure 7-6).
With this component, you can now use the .map() function on your
customer array to render one card for each customer. You will style the
component a bit, and add the button to delete a customer.
129
{data &&
data.getCustomers.map((client) => {
return (
<Card className="customer_card">
<Card.Header>{client.name}</Card.Header>
<Card.Body>
<Card.Text>
{client.address}
<div className="date_created_card">
{client.dateCreated}
</div>
</Card.Text>
<Button variant="outline-danger" size="sm">
Delete
</Button>
</Card.Body>
</Card>
);
})}
You also need to add the styling in the App.css file, to make sure that
the date is smaller than the address and the button is on the right of the
card. You also need to make sure that all cards are in a line, because by
default they will render at full-width and be underneath each other.
Add the following CSS code to your application:
.customer_card {
width: 300px;
float: left;
margin: 10px 10px 0 0;
}
130
.date_created_card {
color: grey;
font-size: 10px;
}
.customer_card button {
float: right;
}
With all of that coding done, you can now see your new frontend,
freshly designed for your CRM application (see Figure 7-7).
Start with the first part, as it makes more logical sense to start with the
backend. You first need to create the function that will go in the database
and delete the customer with a certain ID. You will then go to the
./backend/service/customerService.ts file and add a function to it:
...
const RootMutation = new GraphQLObjectType({
name: "RootMutationType",
fields: {
createCustomer: {
type: CustomerType, // return the newly created customer
args: { name: { type: GraphQLString }, address: { type:
GraphQLString } }, // we take the name and address
as inputs
132
resolve(parent, args) {
return createCustomer(args.name, args.address);
},
},
deleteCustomer: {
type: GraphQLBoolean,
args: {
id: { type: GraphQLID},
},
resolve(parent, args) {
deleteCustomer(args.id);
return true;
},
},
},
});
...
Now go to the frontend to create a function that will call the mutation,
and that will refresh the user list once you call the mutation.
First add the mutation as a string to the App.js file, then register it
to the useMutation() function, which comes from the GraphQL library.
After that, create a new function that will be called every time you click the
button, and afterwards, you simply link the button to it:
...
const DELETE_CUSTOMER_MUTATION = gql`
mutation deleteCustomer($id: ID) {
deleteCustomer(id: $id)
}
`;
...
133
You will now see that when you click the Delete button on each card,
the card will disappear. Your browser will refresh a new list of customers
automatically (see Figure 7-8).
134
Figure 7-8. The new list of customers, after the last entry has
been deleted
Homework
Implement the requirements that were presented at the beginning of the
chapter:
1. Follow the instructions to improve the design and
create the needed mutation.
Summary
In this chapter, you received a list of elements and features that needed to
be added to your application. For your first task as a fullstack developer,
you added various Bootstrap elements to your design, and then created the
mutation needed to enable users to delete a customer.
135
Automated Testing
If you have finished building your application (covered in the previous
chapter), you might think you are ready to hand it over to your customers.
But how can you ensure that all the new features work as intended? You
could always go in and start testing the application manually.
Although this is not necessarily a bad idea, and from time to time you
might need to go into the app and see if it all works correctly, will you
manually test the entire app every time you deploy a new feature? What
about library updates or maintenance? You can see how, after a year of
work, you would have hundreds of features that you would need to test on
an almost daily basis.
This is the point where automated testing comes in. You can automate
a large part of the testing, so that when you deploy a new feature, you’ll
have full confidence that you did not break anything else. Even if are trying
to deploy something complex, and you do end up breaking something, you
will have the confidence that you can determine in minutes what went well
and what went wrong.
Testing Concepts
Testing is one of those topics in development that definitely deserves an
entire chapter, and this section takes a quick look into what testing is and
what you can do with it.
138
Two of the most commonly used such testing systems is Selenium for
Java and Playwright for JavaScript. This book uses Playwright. You can take
a look at https://playwright.dev/ for a better understanding of how this
works and what it is capable to do.
How the testing should be done, and which parts should be tested, is a
matter of debate. Some companies believe in minimal testing, and others
test every piece of code. Some teams even rely on triggers in their pipeline
that block merge requests if the code does not have at least 80 percent
automated testing.
My personal opinion is that you should write as much end-to-end
testing as possible, as it has the following advantages:
1. It will test all of your code and system in one go,
whether it is backend, frontend, infrastructure, or
anything else.
2. It tests things in exactly the same way that the users
interact with your systems.
139
In short, testing is there to give you confidence that your code will not
break anything important. It is necessary that you find a balance between
the different types of testing and your actual development work.
That being said, the next section looks at the different types of tests,
explains how they work, and covers how can you write tests for your
application.
Unit Testing
As described, unit tests are built to verify that a certain unit of your code
works the way it was designed, regardless of its context. Unit testing is
mostly used to check the functionality of methods, functions, and small
components.
Imagine that you have just built the following function that you badly
need inside of your codebase. It is a very simple function, one that simply
adds two numbers, but it is enough to illustrate the testing process:
module.exports = { addNumbers };
140
Now add this function inside a file in the frontend folder, for example a
file named numberHelper.js. Why should you save this file in the frontend
folder? First of all, you will build unit tests around code that already exists.
So they have to be inside of the frontend or the backend folder. As a result,
the frontend folder will do just fine, for this example.
In order to start testing, you need to install the testing framework,
called jest (https://jestjs.io/). Just run the npm install jest
command. Then, open package.js and add the following code to it:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"jstest": "jest"
},
Now you can run your scripts by typing npm run jstest.
In order to start writing tests, create a folder called tests, and there,
create a file called helperTests.test.js. Note the extension test.js.
That way, the test framework knows where all the tests are located and can
run them all at once.
Now write your first test as follows:
141
If you run this command, you will see that the test runs green:
Let’s take a look at what exactly the code is doing. The describe
part is there to add order to the tests. It basically means that this is just
a collection of tests, and they check inside of the code whatever you
summarized in the description. Then, the it part is the start of a single test.
Seeing how you just tested what is supposed to go right with your code,
now you’ll see how you can test what is supposed to go wrong. This is also
an important part of testing.
For example, you know that you cannot call your functions with fewer
or more parameters. So you can test that:
This test case will also make your code check green.
As you can see, there are numerous things that you can test about
a single function. You need to find a balance though, which is where
your role as a developer comes in. You need to find a good spot between
testing what you want to test, or have to test, but also not overburden the
application with too many tests. Every time you change the function, you
also have to change the tests.
142
143
If you run the tests, you now get an error. That means you are at the
red step:
You need to make the tests run green. In order to do that, go into the
function and determine whether the parameters provided were correct. If
they were not correct, throw an error:
return a + b;
};
144
You can skip the refactor stage, since your code is well written from the
start. But this would be where you bring the code up to standard, if that is
not the case.
Now run this test again. Say that the other team had an issue, where
the function was called with two parameters, but as strings, and that led
to an error. You now have a new requirement—when the function receives
two parameters but they are not numbers, it should throw an error and ask
for numbers.
Here is the new test that takes care of that situation:
This function takes care of such an event, where both parameters are
strings, so that the tests run green.
145
And that is it! That is how you do test driven development (TDD).
There is, of course, a lot of controversy about whether this should actually
be done in the first place, or whether tests should be written at the end
of the coding session, once you actually know what you need to test.
The advantage of TDD is that you can always guarantee, with tests, that
your code works as it should. It also forces you to figure out early in the
development if all of the requirements have been completely understood.
The downside is that development takes longer, you end up with a large
number of tests that you have to maintain every time you change your
code, and it is difficult to implement when the feature requires a large
amount of interaction between the frontend and the backend. I personally
only use TDD when I need to build complex, singular functions.
I ntegration Tests
Suppose that your function is now so well tested that you are fully
confident that it will work as intended. However, your app has multiple
such functions, which continuously interact with each other. Because of
that, in order to have full confidence in your systems, it makes sense to
look into more complex test cases.
This is exactly where integration testing comes in. It offers you the
ability to verify how two or more functions interact with each other.
To understand this, you’ll build a new function that uses the previous
one. It should be something simple, so that you can write some tests for it.
You can make it more complicated later. To start, build something this:
146
This may not look very impressive at the moment, but you just
wrote your first integration test! That is because you are simultaneously
testing the totalNumber() function and the way that it interacts with the
addNumbers() function.
Now you can build something more complicated. Assume that the
totalNumber() function is supposed to deliver the total number of
customers. It does this by calling two APIs and formatting the result.
Something along the lines of this:
This function will first call the API of Amazon (or pretend to, at least, for
the sake of the demonstration) to retrieve a number of clients. It will then
call the eBay API and collect the customers that you have there. It will then
call the initial function, addNumbers(), using the new data that it collected.
147
Since you cannot accept that the actual API calls will happen every
time your tests run—because either they will be slow or you will have to
pay additionally for the API calls—it is better to somehow mock the data
coming back, when testing the function.
For this purpose, you can create APIs that will pretend to return the
data from the third-party websites. Create a new file called apiCalls.js
and add the following code to it:
module.exports = {
amazonTotalClients,
ebayTotalClients,
};
But now there is a dilemma. How exactly can you test such a function,
if you do not know how the APIs are going to behave? And besides that, it
is not really your job to be testing third-party APIs in the first place. You
therefore need to mock the APIs. Basically, you tell the jest framework
that you will pretend that you know what type of data will be returned by
the two APIs, and that way, you can continue with your tests.
jest.mock("../src/apiCalls");
148
You can see that the API calls were mocked by the test. When running
the integration tests, the testing framework will pretend that each API call
will return the numbers 12 and 13, and never actually call the API on the
third-party side. As a result, your total number is 25 instead of the actual 64
that would be returned if you were to actually call it.
I use this mocking property pretty often, because it allows me to
test parts of my code, without access to the database or to a third-party
API. This is especially helpful when you are trying to create new users
or are testing payment systems. In such cases, you would not want your
tests to be performed against production data. As a result, you can mock
such calls, so that you can test your integration services in isolation to the
systems that you normally plug into.
One of the best ways to use integration testing is to do GraphQL
testing. That is, you emulate your database and/or API calls, and then
access your backend application via the GraphQL interface. That way,
you can test your entire backend segment in isolation. Doing this type of
testing is, in my view, one of the best ways to perform integration testing.
End-to-End Testing
So far, you have investigated the process of testing your entire system. Your
tests plug directly into your functions and check various points inside
of them. However, your end users will not be accessing your functions
directly, but will interact with them using your trusted user interface.
Hence the name of end-to-end testing—from the user to the database.
149
As a result, you must test your application just as if you were an actual
user. That is, you need to open a browser and access your application. It
would also be nice to test various browsers to make sure that all users will
be able to access your system as you intended.
There are two big libraries that can achieve this using JavaScript:
Cypress (www.cypress.io) and Playwright (https://playwright.
dev/). This chapter uses Playwright, but they are very similar and use
similar syntax.
The first step is to install the library. Do this inside a new folder called
tests. Then run the following command:
After this, make sure that your frontend and backend are both running.
Then open a browser and verify that you can access the system (see
Figure 8-1). If you cannot access it, Playwright can’t either.
150
Note the await keyword in this code. All of the functions that have to
do with the browser are asynchronous, that is, they will not render a result
immediately, but will come back once the result has been produced.
151
You basically just go to the URL and wait for the button to appear. Once
that the button is there, you check that the page has a title, and that the
button is being rendered.
Now, for the second part, creating a client. It would be nice for your
popup form to have some classes or IDs, so that you can test them. Go to
the ./frontend/createCustomer.js file and add some classes to it:
<Modal.Body>
Name
<Form.Control
value={customerName}
className="customerName"
onChange={(e) => setCustomerName(e.target.value)}
// e is here an event, so we get the value of the
change event
/>
Address
<Form.Control
value={customerAddress}
className="customerAddress"
onChange={(e) => setCustomerAddress(e.target.value)}
/>
</Modal.Body>
You can see your changes by inspecting one of the inputs inside of the
popup. Just right-click and then choose Inspect (see Figure 8-2).
152
Figure 8-2. Inspecting the popup elements to see your new classes
With those classes, you can build the rest of your code. You can then
run it, and it will test your app in all three of the major browsers: Mozilla,
Chrome (this includes Edge), and Safari.
153
Note that because you use the customer name and address at least two
times, it is now a constant. That ensures that your code does not repeat
too much.
If you run your tests (by running the npx playwright test
command), you will instantly get a green light:
If you add headless: false inside of the use block in the config file,
the browser will open and automatically follow along with your test case.
That is also where you set up how many types of browsers you want to run
in your tests. I usually only have one, and that is Chrome.
154
Homework
Try writing your own tests:
Summary
Testing is an integral part of development. It is a lot more important when
you have a complex application. Testing gives developers the confidence
that the things that they deploy do not break important functionalities in
the existing system.
Finding a balance between development and testing is always difficult,
so as a beginner, it is a good idea to start with the 80/20 rule. That is,
spend 80 percent of your time on development, and 20 percent on testing.
Depending on your industry, this could be vastly different. For example, a
bank would have many more tests built into their code than a startup that
has a presentation website or created a small demo for their client. But this
is the job of the developer—to find the correct balance.
155
Other Frameworks
and Technologies
You do not need to build every functionality in your application. It is
actually quite the contrary! Most of the time, the best answer is to look for
ready-made solutions on the market. Some of them cost a bit of money,
but can be worth it, but in most cases, the ready-made solutions are free.
This chapter goes through a few examples of things that you should
know about, if you are to become a programmer. Some are simply
concepts that you should be familiar with, while others are exactly these
premade solutions that might come in handy in your projects.
L ogin Systems
Almost all applications need a login system. However, seeing how this
is the fundamental building block of the applications’ security, it is not
necessarily a good idea to build it from scratch.
Besides the fact that you would then need to deal with the hassle of
fixing potential bugs or deal with every possible type of attack, it would
also be an extremely difficult challenge, because you have to integrate the
login process with all of the possible vendors, such as Google, Facebook,
LinkedIn, and so on.
For actual application that you would build for production, I highly
recommend using a library that has everything prebuilt, where you would
only need to call a certain function.
One of the most commonly used libraries is PassportJS, found at
www.passportjs.org/. It is very flexible and most certainly offers you all
that you need for your login system.
That being said, let’s consider how you would start building a login
system, if you had to.
Any website that needs a login system is basically split into two parts:
The frontend part can be easily split into these two parts by just
checking the user data before the render. The way you can tell if somebody
is logged in is by using cookies.
158
Cookies
A cookie is a variable that is stored inside of a person’s browser that
contains personal information about the person, such as their login
credentials. It can have an expiration date, which is usually set to 30 days.
This is the way you can follow a person around the Internet.
There is however a restriction, which is that a website cannot read
the cookies from another website. This is a built-in security feature for
all modern browsers. You would not want a website that you visit to have
access to your login data from a different website.
let x = document.cookie;
// will return all cookies in one string: cookie1=value;
cookie2=value; cookie3=value;
This way, when a user comes back to your website a few days later, they
can skip the login part, because the site remembers who they are.
For the private part of the website, the one that needs authentication,
the program first checks if the user has the proper cookies. If they do not, it
redirects them to the landing page. This can easily be done in the frontend,
using the index.js file:
<ApolloProvider client={client}>
{isUserLoggedIn() ? <App /> : <LandingPage />}
</ApolloProvider>
If the user is not logged in, the program does not render the app, but
instead shows the landing page, which will contain the login screen.
An additional safety measure is that the backend also needs to check
this authentication before it returns any data.
159
M
D5
Here are the login steps for users to access your website:
The main problem that you can see here is that people usually have the
same password on many other websites, so that means that breaking into
one could possibly mean breaking into them all.
That is why it is useful to have a function that takes text as input,
such as a password, does some processing, and returns as a one-way
output some random text that cannot be deciphered. This is called a hash
function, and one of the most common ones is MD5.
160
MD5 will take your passwords and encrypt them, so that you only need
to store the encrypted versions in the database and encrypt the password
provided by the user before checking it into the database.
• StrongPass123& → 5e7afa1d53835a8e88a98aefb
89b64f4
• BestStrongPass@5 → 64d6f8cad75daf9a891dc575af
061bd7
A hash will always return the same output for the same input. Another
feature of the hash is that if you change the input just a little bit, the
output fundamentally changes, making it basically impossible to trace the
original string.
Coming back to your app, if you only have the hash in the database,
you can rehash the user-provided password and check the hash against the
one that you have inside the database.
Since there is no way to get the original string back, and the encryption
will always return the same key for the same input string, a database leak
will not cause too many issues. Using hashes, your database now looks like
this, so there is not a big security risk associated with it:
161
Open Source
A big part of the technologies that you will use as a developer is considered
open source. That means, first of all, that the source code of the software
is open to the public, so that everyone who wants to look at the code can
do so. This also means that the chances of there being security issues in
the code are minimal, since there is a large number of developers looking
over things.
Another big advantage of open source projects is that, generally
speaking, it does not cost anything to use them. Although some have
premium products on offer, such as better support or certain extensions, it
does not cost anything for you as a developer to create your own software
using open source technologies, and then use the solution. This is in
contrast to some other commercial solutions, which request that you pay a
part of your proceedings to them for using their software in your builds.
The most important part of using open source is that everybody
can add to it. That means that if you ever find a bug, you are absolutely
encouraged to try to fix it. It also means that there is a way for you to try out
your skills, if you so desire.
Famous open source projects include the following:
• GIMP, an image editing program
162
GIT
Git is one of the most commonly used technologies inside of the
programming space. It is a versioning control tool that enables you to
practically make a copy of the current code structure. With this copy, you
can change things around as much as you want without affecting the
main code.
Once you are done with the code, you can simply merge your changes
back into the main branch (see Figure 9-1).
Main branch
Separate branch
163
Both offer a free version, so if you want to learn more, you can simply
open an account and start looking around.
164
Docker
Docker enables you to create containers for your applications. But what
exactly is a container?
Imagine that you have just finished developing your application, and
you now want to deploy it to production, so that your users have access to
it. The normal way would be to create a server somewhere like Amazon
or Azure, and set up your app there. This would include the backend, the
frontend, the database, all the libraries, all the setups, ports, libraries,
and so on.
The issue with this is that if the server updates the operating system, or
you need to change the vendor, you have to start from scratch and perform
the setup all over again.
It is exactly for this case that Docker was built. You can set up an image
and detail exactly which operating system it should use, which ports go
where, and which servers start up with which files inside of them. It will all
just turn on and work in any machine that you try to run it from.
Say you create an app in a Docker image and send the entire package
to your friend, who uses a different operating system. All they would
have to do is to start up the Docker image, and everything would simply
just work.
NoSQL
Just as is generally the case, data that you have to save in the database is
normally thought of in a structured manner, and as a result, you can always
save it inside a predefined table and access it based on the columns of
those tables.
However, you may stumble into a case where you need to save and
later retrieve data that is not structured. Think about logs or collections of
data points from various machines.
165
You could always just save this data as text and later pull and parse it,
so you get your arrays and objects back, but you would lose the ability to
query the data.
For this reason, you could instead choose a NoSQL database, such
as MongoDB. NoSQL databases enable you to have flexible schema, so
that you can easily save and query data with any structure. The same idea
applies to DynamoDB, the NoSQL database from Amazon.
However, NoSQL databases are generally a niche product, and they are
rarely encountered in day-to-day life.
If you want to find out more, visit their websites at www.mongodb.com/
and https://aws.amazon.com/dynamodb.
JIRA
Jira is one of the most commonly used applications for managing
development projects and the work that teams need to perform. It helps
teams plan, track, report, and assign their work. It also helps teams with
various Agile methodologies.
Jira helps with the backlog of tickets, with sprint planning, and even
has some automation behind it. But before everything else, Jira is a ticket
management system (see Figure 9-2).
166
You can discover more, and even see a demo of Jira, by visiting their
official website at www.jira.com.
You will learn a lot more about this tool in a future chapter, but at the
moment, it is sufficient to say that working on a software development
team is a lot more efficient when you’re using a tool like Jira.
WordPress
WordPress is a content management system (CMS) and one of the easiest
and most powerful ways to create almost any website. It initially began
as a blogging platform, but it quickly evolved into much more than that.
WordPress currently offers solutions ranging from blogging and static
presentation websites, to online shopping platforms. It gives you the
advantage of installing and maintaining a website without any coding
knowledge.
167
168
169
Summary
One of the characteristics of any good engineer is knowing where to
channel the effort, in order to maximize the desired outcome. This
primarily translates into knowing which technologies exist on the market
and knowing how to use them.
Unfortunately, this chapter only covered a small amount of everything
that the Internet has to offer, in terms of efficient ways of working. As a
result, it is up to you to keep up to speed with the current state of affairs
and the current trends in your domain.
170
Landing Your
First Role
Creating a Portfolio
One of the best things you can do is develop your skills further. In addition
to that, you need to prove your skills to a potential employer. As a result, it
is a very good idea to start a personal project or to continue the CRM that
you started to build in this book.
The first step is to head over to https://github.com/. Create a free
account there, and then install the Git software on your computer. After
this, push your code into a Git repository, so that you can easily share it
with potential recruiters.
Then, think about something that you enjoy and create a small
presentation website. It does not have to be hosted anywhere. Just get
more familiar with all the things that web development has to offer.
Ask your friends if any of them need a website for anything. This way
you are also helping a friend out and adding projects to your portfolio.
Just as a personal anecdote, I used to love reading the travel blog that
two of my friends created. It was not working properly on mobile, and this
was my main way of catching up with them. As a result, I offered to fix their
website for free. Luckily, it was a WordPress website, so it was all finished
in a few days. By doing this, I got to spend time with my friends, help them
out, and contribute to a nice project that I was using.
174
175
Freelancing
An excellent way to gather experience is to start doing some freelancing
jobs. This comes with the added benefit of providing some small amount
of additional income. All you need to do to start along this path is head
either to www.upwork.com/ or to www.freelancer.com/ and open an
account.
At the beginning of my career, when I was not earning as much, I was
almost doubling my income with weekend projects that I got through
freelancing. Some of my friends have quit their jobs entirely and now only
work as freelancers.
Since you are starting a new career, I advise that you look for jobs
that match your knowledge, and be open and transparent to a potential
customer about the fact that you are still learning and looking for
experience. An easy way to get started is to take some side jobs for free,
so that you start having a reputation within the community. Most people
will not refuse a free job, so just make sure to take something that is
relatively small.
Once you have a few clients, they keep coming back. For me, for
example, after about six months on the platform, I was no longer looking
for new projects, as I had three customers who gave me enough work to fill
my free time. Sometimes even more.
All things considered, it is a good idea to look into this line of work,
especially at the beginning. You will have lots of flexibility, and will
absolutely learn a lot, including soft skills.
176
Don’t forget to cover soft skills, as this is a very important part of any
hiring. A manager is not only looking to hire an engineer, but also an actual
human being. They would much rather hire someone who is average
technically but can work great on a team, rather than a rock-star developer
who can only work alone, and is half the time in a bad mood. Therefore,
focus on how you work with others and what makes you a good hire from
that perspective.
One way to set yourself apart is to have a letter of intent. Just write a
few paragraphs about who you are and what motivates you. Explain what
you are looking for in the job that the company is posting, and what your
plans are if they hire you.
As always, it is important to know how to sell yourself. Try to make it
easy for the person reading your information to understand what makes
you a good fit, what your strong skills are, and what would make you a
good addition to their team.
177
178
179
180
position is more defined. Your job is also a lot safer, in terms of being laid
off, and you are better protected. However, this also means that most of the
time, you are a small cog in a huge machine. An important cog, yes, but it
can still feel impersonal and transactional.
Medium-sized companies, meaning anywhere between 50 and 1,000
employees, tend to be a mix between the two. Where exactly this mix falls
can only be determined on a case-by-case basis. Note that sometimes
departments from large companies behave relatively independently,
meaning you might find a perfect mix between the flexibility of a small
company and the safety of a big corporation. You just have to explore the
job market a bit.
In order to find one job, you need to apply to a lot of jobs. And I do
mean a lot. Depending on where you are located and your experience,
you should expect that around 100 applications will lead to around ten
interviews, and that will lead to one job offer. So it is all a numbers game.
Try not to take things personally, and do not be discouraged by rejection.
Just think of it as bringing you one step closer to your actual job.
Recruiters will also contact you. Also known as head-hunters, they
will try to reach you through LinkedIn, email, and phone calls. I am not
saying that you should ignore them. But remember that companies prefer
to hire you directly, if they can. First of all, never pay a recruiter. They are
being paid by the companies, and their role is to sell you into a position.
Since they are paid only if they get you hired, they have little interest as to
whether you are a good fit for the company, or if the company is a good fit
for you. So they do not have your best interests at heart.
The best piece of advice that I have for you here is to trust your
instincts. They evolved over millions of years to keep you safe. So if
somethings smells fishy or seems too good to be true, find out more. Head
over to glassdoor.com, for example, and see what other employees have to
say about that company. This will minimize the risks.
181
Interviews
Once you have started applying for jobs, it is a matter of time before you get
your tech interview. Just because the interview is for a technical position
does not mean that it will be radically different than any other interview.
At the end of the day, an interview is about finding a good match. That
includes technical skills of course, but it also includes compatibility with
the company’s culture, potential integration and smooth day-to-day
interactions with the team, and so on.
The following sections explore what you can expect from such
interviews, and tips for doing well. This includes what your general
attitude should be, and what types of things you should also ask and be on
the lookout for.
Most interviews include a coding challenge, which usually happens
before the discussion happens. In this coding challenge, you are provided
with a short list of requirements for a web app that you have to build.
Your code should be easy to read and should use the proper libraries for
your features (such as React). In addition, your solution must meet the
requirements that were laid out.
I only accept challenges that I am relatively confident that I can finish
in two-three hours. One challenge that I particularly enjoyed was to create
a frontend application that loaded data from a given GraphQL endpoint,
and was present it, with the possibility to filter the data, using a text input.
That took me around an hour to do. I have also received challenges that
would have taken me a couple of days, such as creating an entire mobile
application, with highly-complex backend architectures, including
deployment. I tend to reject those types of challenges.
I believe in the concept of equality. The hiring party wants you as an
employee, just as much as you want to work there, as far as you know.
They listed an opened position, and you applied for it. If you are ready to
give four hours of your time to see if it’s a good match, they should take the
same time. I consider this a question of respect. I have no problem with
182
an interview that lasts four hours, but to ask someone up-front for a 6- or
12-hour commitment, just to potentially be rejected using a generic email
with no feedback, I find to be a big red flag.
One the other hand, sometimes there are 100 candidates for a single
job, so you somehow need to filter through them. On my current team, we
also have a similar challenge, but it can usually be achieved in fewer than
an hour of work. My advice to you is to be careful about the time that you
spend on such challenges and weigh whether they are worth it.
Once you jump through these hoops, it is time to meet the developers.
Companies typically assign two-three developers from the team to assess
your skills and compatibility. Every interview will start with a small
introduction. When it is your time to talk, keep in mind that most likely
they have seen your CV. Use three-four minutes to describe your CV, your
achievements, and what motivates you. I, for example, mention the last
few positions and companies that I worked for, and then generally describe
how I love working in the tech industry because it enables other people to
do their jobs better. I try to create products that people use, not just apps
and code. I also have a more holistic approach to development in general.
This is what I believe, and if we do not match on this level, it is better to
find out earlier in the interviewing process.
Then next step is to present your answer to the challenge. Try to
be mindful of everybody’s time and start with a small demo. Include a
two-three minute description of your code and explain how you pieced
it together. After this point, the questions will start, first related to the
challenge, then to wider technical topics, and then to general interviewing
questions.
When you are asked a complex or technical question, first reiterate
the problem, so that you can make sure that you understood everything
completely. Then, while you think about possible solutions, talk about any
ideas you have. Try to be as verbose as possible; the main reason for an
interview is for the company to understand the way that you think. Go into
detail and ask for clarification, if you see the need.
183
184
Summary
Getting a job is never easy. You have to filter through a lot of job positions,
go though many interviews, negotiate, and generally keep trying. Not the
most pleasant of activities, but it is mostly worth it.
This chapter looked into how to apply for a job and what to expect
from an interview. I highly encourage you to do your own research as well
and look up tips and tricks related to interviews.
185
Working on a Team
The day will arrive when you start your first job as a web developer.
This chapter discusses what exactly a web development team does
differently than what you have been doing as an independent developer.
This includes a discussion of how teams are set up and what the normal
workflow is. The chapter also includes a short introduction to the
technologies needed for modern web development in the context of team
work and collaboration. I do, however, treat project management as a
separate topic altogether. It’s covered in the next chapter.
Team Structure
The most common way of working at the moment, when it comes to
software development, is by using the Agile methodology. You will read
a larger explanation about it a bit later, but the gist of it is that a team
should be able to work relatively independently. That is, they should be
able to take a feature from the stage of concept, into development, testing,
deployment, and monitoring, without depending on other teams.
Usually, a development team will include a variety of roles in order to
function properly, but many of them can be fulfilled by a single person. I
have personally worked on teams that were as large as 13 people, as well as
on teams of only three people. Regardless of the size of the team, one way
or another, all of the roles were covered by someone.
188
189
190
the backend changes to the users. After that is also done, it is time for you
to write unit tests, and then manually perform the user acceptance tests
on your end. Be sure to go through the user story and make sure that the
points have been properly implemented. The last development step is to
write any end-to-end tests that you need.
191
When developing your code, most likely you will have a locally running
environment with a frontend, backend, and a local database. This should
simulate your development environment relatively well. In this local
environment, you will develop your new features, test them, and then
prepare to launch them into development.
So, how does your code go from your local computer to the production
environment? As you are developing, your colleagues will be developing
things in parallel. So you can’t just push your new code on the server and
declare it to be the new version of your application. Anybody who had
developed something based on the previous version would lose their work.
For this purpose, you use a versioning tool, which provides all of the
functionalities needed by the entire team. The most common versioning
tool is Git. It allows multiple people to work on the same file at the same
time and includes tools for merging the changes and resolving conflicts.
It basically creates a copy of the codebase on your computer, and then
registers the difference between the base branch and the one that you are
working on.
Before you start working, you usually create a Git branch out of
the current state of the code in dev. The name of the branch should be
something representative and should start with your initials:
You create and test your code on the local environment, just as you did
before, and then commit your changes. You push the changes to the origin,
meaning back to the original Git server:
192
The last command returns an URL that enables you to create a merge
request (see Figure 11-1).
Once the merge request is done, you should always perform a self-
review first, to make sure that you did not push anything by accident that
you did not intend to push.
Go to the Files Changed tab (see Figure 11-2) and view the changes
that the current merge request is trying to push into the codebase. Read
the changes and perform a sanity check on your end.
193
Once you have ensured that everything is in order, you ask one of your
colleagues to review the code as well. It is generally required, and a good
idea, that at least two people (sometimes even more) review a piece of
code before it reaches the main branch.
What exactly are you looking for, when you are reviewing a merge
request? There are multiple levels on which you assess a merge request.
These are, in no particular order:
• Design: Is the code well designed and appropriate for
the system that it is being delivered to?
• Functionality: Does the code behave as the developer
intended? Are there any unforeseen consequences
of the way that the code is written, such as bugs or
vulnerabilities?
• Complexity: Would another developer understand
what the code is doing without further explanation?
194
Once these points have been reviewed, the appropriate person will
approve the merge request. From this point, you can simply merge your
branch into the main branch. Just click the green Merge button and Git will
take care of the rest.
If the repository is set up in such a way, merging will also trigger
certain additional steps. These are usually automated steps required to
bring the new code live to the development environment.
The collection of steps that Git runs after a successful merge is called a
pipeline (see Figure 11-3).
195
Here are some additional pieces of advice that I have for someone
starting their development career and working on a technical team:
• Communicate when something looks like a bad idea.
The entire team relies on you and your experience to
raise awareness about any roadblock that might appear
in the future.
• Try to get involved with the cycles of an application.
Try learning more about UX, about infrastructure, and
whatever else you are in contact with. Be curious!
• Avoid technical terms as much as possible. The main
purpose of communicating is to relay information.
Therefore, make sure that there are as few blocks as
possible, and simplify your speech as much as you
can, especially with people who are not well versed in
your field.
• Do not be too attached to your ideas. Ask the team
for a vote if there is no way to achieve a consensus, and
once the vote is done, go with the decision. Even if you
do not agree with it. That is what makes someone a
great team-player.
196
minimizes potential bugs. The disadvantage, of course, is that the team can
now only deliver half of their theoretical speed, so it is absolutely a matter
of quality vs quantity. If a team has pair programming as a standard, or it is
only happening with major algorithmic difficulties.
Summary
Working on a team is generally a challenge for a lot of people. But it is
one of the most important parts of almost any job. Your superpower as a
human relies on how well you can collaborate with others.
Hopefully, this chapter provided you with some insights into how web
developers work on a team to achieve their goals, and what you can do to
help once you are hired.
197
Project Management
Methods
They say that a team is only as good as the one who leads it. I would say
that a team is only as good as the way it’s organized. Knowing what you will
work on today and the way that relates to the rest of the team can make the
difference between a mediocre team and a great one. This chapter explores
how modern project management works in organizing IT development.
approach is usually called Agile. This is in contrast to the large and linear
approach of project management used 20 years ago, called waterfall.
This can be summarized as a linear approach to development, where
everything is preplanned, and each new step required the previous step to
be finished.
Agile software development is an umbrella term that encompasses any
set of processes and procedures that follow the 12 rules of Agile, as they are
derived from the Agile Manifesto [3]. Those rules are as follows:
1. “Our highest priority is to satisfy the customer
through early and continuous delivery of valuable
software.
2. Welcome changing requirements, even late in
development. Agile processes harness change for
the customer’s competitive advantage.
3. Deliver working software frequently, from a couple
of weeks to a couple of months, with a preference to
the shorter timescale.
4. Business people and developers must work together
daily throughout the project.
200
201
As you can see in Figure 12-1, from the very start, the customer has a
flying device. Although it may not be able to do everything, it is useful and
you can gather feedback as you improve the product. It also allows you
to incorporate any feedback into the newer versions of the product and
frequently revise it.
202
There is no fixed process for Agile, and each team will have its own
Agile Development method and its own ways of doing things. At least that
much needs to be said. But with that in mind, this section explores the
most common approaches and the concepts behind them.
At the core of the Agile methodology is the idea of continuous
integration and continuous delivery (CI/CD). That means that every two
to four weeks—a period that is called a Sprint—the team will have target
features to add the main app, including the testing that such features
require, integration, documentation, and so on.
These new consumable features should, first of all, not break any
functionality that is already there. The team should also try to avoid
launching incomplete features that error out when they are used.
Fundamentally, the target of the Sprint is the completion and
deployment of separate components into the main application. This
enables you to split an app into multiple incremental steps, so that you can
easily adapt to any incoming changes or difficulties. This is what makes
it agile.
Such an approach also allows you to integrate feedback very quickly.
At the end of every Sprint, the team goes through a ceremony (a
meeting) called Sprint planning, where the project manager, together with
the team, plans what the next Sprint should tackle, which tickets should
be worked on, and what the goal of the next two weeks should be. It is also
worth mentioning that the length of a Sprint usually is two weeks. A two-
week Sprint brings a good balance between taking time for planning and
having enough time for execution.
Each ticket should have a rough estimate of how many hours it will
take to finish, including development, testing, bug fixing, and deployment.
This estimate is approved by the team in a previous a meeting, called
grooming or backlog grooming (or a variation of these). This is usually
done one day before the planning. Each ticket is presented to the team,
203
and everyone gets to vote on how much effort each of the tickets will
require. If the ticket is open-ended, such as an improvement of a certain
piece of code, the team will usually time-box the ticket.
Each day, early at the beginning of the workday, the team meets for
what is called the daily standup. Every member takes turns explaining the
state of their tickets, what they did the day before, and what their plan for
the current day is. This provides transparency and good team cohesion.
Each team member is also responsible for asking for help if they need it.
See Figure 12-2.
Daily Scrum
Scrum Master 24
Hours
Sprint
1-4 weeks Sprint Retrospective
Product Owner Team
204
The discussion is split into three distinct chapters. The first chapter is
about what went well, where team members take note of the good things
that happened, or the positive processes that should be continued. The
next chapter is about what went bad, and this is usually where most of the
discussion happens. The discussion is focused in such a way to determine
what can be improved. Working in an Agile way also means that, for every
issue the team is facing, there usually is a possible solution. Even if it is not
perfect, the team can try one solution for two weeks, and at the next retro
discuss whether it helped.
Here is an example of a retro board:
205
Summary
The Agile methodology in general, and Scrum in particular, are currently
the industry standard in terms of web development. This involves Sprints
that usually last two weeks, daily meetings to organize the team and
bring everyone up to date, and features delivered regularly into the main
working project. Compared to the old approach called waterfall, the Agile
methodology allows you to incorporate feedback much earlier and be
more flexible in terms of where the product is going.
206
In Summary
Conclusions
Now that our time together has come to an end, it’s time to review
the topics covered in our journey together. I started with a series of
introductions into the career of a web developer, and you learned what you
can expect when working in such an environment. You learned about the
benefits and drawbacks of working as a programmer in general, together
with some common misconceptions.
Next, you learned about the importance that a database holds for any
given application, and how the SQL language generally works. You saw
how a SELECT statement is created, what you can do in a WHERE clause,
and probably one of the most important points of all—how to write a JOIN
statement.
You then learned about GraphQL, which is a query language for APIs.
You also learned about JavaScript, in order to understand how exactly this
language operates, what makes it different, and what you can expect when
using this language.
You then created your first backend application, using Node.js and
GraphQL, and managed to get it connected to a database. You succeeded
in setting up an entire environment, creating your first query, and then
your first mutation.
Once you were done with the backend, you moved to creating your
first frontend app. You used React to create a basic, bare-bones website,
and then started adding different components to it, in order to give your
fictious users an intuitive way to interact with the backend.
After everything was done, you learned a bit about the world of testing,
and learned what you can do to test your code. You learned about unit
tests as well end-to-end tests.
That was the big chunk of theory in this book. With that out of the way,
you investigated other technologies that you might need, if you will be
engaging with the world of web development, and had a short introduction
to where and how these technologies can be used.
Afterward, you learned how to prepare for your first job, what a normal
interview looks like, how to write a CV that is attuned to web development
positions, and how to find and apply to a job.
I also discussed your first day on the job. You learned how a
development team works, how it is organized, and how a day-to-day work
pace flows.
At the end, to wrap everything up, you learned about project
management inside the field of software development, about Agile and
Scrum, and about the way that a development team organizes itself in
order for the team’s goals to be met, and most importantly, the clients to
be happy.
I wrote this book with the hope that I could expose you to the
wonderful world of web development and that I could spark the same
curiosity and interests that I myself felt, once I started to understand more
about development in general.
This book should not be seen as a manual on how to use any particular
programming language or framework, as this is not what I intended
it to be. Instead, I wrote it as a guide for how and where to find more
information once you start on the development path, and what your steps
into the programming world should be. Since I had a difficult time figuring
out what was important and what was not worth putting my time into, I
hope that I have lightened the load for you, and that I at least gave you a
rough map of the web development field.
But there is only one way to become good at anything in general, and
programming is no exception to that rule. The only way to succeed is
210
References
[1] – https://www.statista.com/statistics/1124699/worldwide-
developer-survey-most-used-frameworks-web/
[2] – https://blog.back4app.com/backend-programming-
languages-list/
[3] – https://www.agilealliance.org/agile101/12-principles-
behind-the-agile-manifesto/
[4] – Image created by Ruxandra Corduneanu
211
214
E G
eBay API, 147 General web application
/ (end tag), 49 architecture, 15
End-to-end (system) testing, Git, 192, 195
138, 139, 149–154 Git repository, 75, 174
Equality, 182 Git technology
advantage, 163
git branches structure, 163
F version control tool, 163
Facebook, 17, 20, 21, 158 Google, 14, 16, 49, 77, 158
Figma UX design, 94–96 GraphQL, 111, 179, 190, 209
The Figma UX/UI dataflow, 89
Apollo, 111–117 data interfacing, 63
create new web project, 94 data response, 62
create React components, description, 61
108, 109 JSON format, 62
Homework (10 Min), 110 JSON object, 63
Homework (30-40 Min), 108 mutations, 64, 65
mutations to customer queries, 63
creation, 116–120 RESTful protocol, 61
popup creation, 102–107 SQL SELECT statement, 62
React, 94 GraphQL endpoint, 65, 78, 84, 182
setup, 96, 97 GraphQL library, 133
static page, 97–102 GraphQL testing, 149
forEach function, 71 Grooming/backlog grooming, 203
Foreign key, 34
Freelancing, 176
Frontend, 16, 23, 190 H
development, 93 Hackathons, 175
Figma UX/UI (see The Handshake, 16
Figma UX/UI) Hash function, 160, 161
web development, 93 Head-hunters, 181
./frontend/App.css file, 126 helperTests.test.js file, 141
215
216
217
218
219