# How Tech works – web app development for Non-Techies :::success **Get involved!** <a href="mailto:kontakt%40martinbetz.eu?subject=How%20Tech%20Works%20-%20Update%20me&body=Hi%2C%0A%0Aplease%20ping%20me%20once%20%22How%20Tech%20Works%22%20is%20ready!%0AThis%20is%20my%20advice%20to%20you%20for%20the%20book%3A%0A%0A">Get pinged when live</a> | <a href="mailto:kontakt%40martinbetz.eu?subject=How%20Tech%20Works%20-%20Alpha%20reader&body=Hi%2C%0A%0AI%20would%20love%20to%20be%20alpha%20reader%20for%20the%20book.%0A%0AAnd%20this%20is%20my%20advice%20to%20you%20for%20the%20book%3A%0A%0A">Become alpha reader</a> ::: Improve your work in software teams and organizations by understanding how web apps work and how diverse and complex coding is, especially in teams. :::info Dear early readers: - Please focus on how well you think the topics in the chapters can help you, not on typos or small details. - Please give me feedback with comments with categories - Good categories are "**Useful**", "**Confusing**", "**Not needed**", and "**Missing**" - Please put feedback that is about the full book here ::: ## About this book **What is the book about?** To help non-technical people who work with or in technical teams improve their collaboration with technical people by understanding how web app development works. **Author's motivation** I, Martin, created my first website in 1998 and have been working at the intersection of business, education, and technology ever since. I have been translating between technical and non-technical people in every organization that I ever worked for. This is the book I wish I had years ago, so I could have better supported the non-technical people in my teams to have better expectations, communication and hence collaboration with their technical peers. I hope it helps you and your teams to understand web technology better and work together more smoothly. And I want to make tech fun for you, at least a bit! I want this book to help you. To understand what works and what not, I value your feedback. Please give me advice at hello@martinbetz.eu **Who is this book for?** - The book is for you if you have a non-technical background and work in a software team or company, specifically on web applications. - The book is for you if you have little to no experience in web technology. - The book is for you if you want to better understand what developers of web apps work on and how they work. - The book is for you if you want to become proud because you read some real code and understand the ideas behind it! **Who is this book not for?** - The book is not for you if you work in technology beyond the web, such as hardware or industrial engineering. - The book is not enough if you want to become a programmer, it will give you a holistic overview and some code snippets, but you will not create code yourself. - The book is not for you if you hate 🍕, I use pizza and an pizza app to explain everything. **What will you get out of the book?** - You will learn what parts software are created from and how to relate to each other. - You will understand on a high-level what developers are thinking and talking about. - Be able to understand engineers better and have better collaboration with them. **What is being covered and what not in the book?** - The book does cover the high level of technologies used in software applications. - The book does not cover how to use any of the concepts and technology in detail, it will not make you a programmer. - The book covers basic code without explaining every detail, it intends to give you an idea not an exact playbook. - The book describes how web apps work. - The book does not cover history and pros and cons of single tools. **How should I read the book?** - You can read it end-to-end, it has a logical order and one consistent story. - You can also pick chapters whenever you need them. **How did I use AI for this book?** - I used AI tools (ChatGPT, ClaudeAI, GPT4) for the first draft of the book, and rewrote every single sentence. Everything that you read, was revised countless times by me - I used other tools (LanguageTool, DeepL Write) to find better ways to say what I want to say and spot errors. - I spend dozens of hours to get exactly the style and consistency of images I wanted to illustrate the book out of DALL-E3. ## Why you need basic technical knowledge? A typical day in a software team You work as a non-technical person in a technical software team. You know how hard it is to get definite answers that help you estimate your next software feature. You ask the engineers "How long will it take to bring this feature live?" and they answer "It depends", "Hard to say" or even "I don't know" and will reject to commit to any deadline. And even after estimating a lot more than any of the times they promised, you face lots of delayed projects. When you talk about a feature, you still feel that you and the engineers talk a different language. You say "The user wants to do this and that" and the engineer replies something along the lines of "That's not so easy, you have to consider that the API is not ready for such a task and I can't change it, because other teams depend on it's current structure". The engineers on the other hand feel bad when they feel that you have no idea what they talk about and do away their worries with "Yes, okay, that's a technical detail, but how much does it delay our project". Engineers think holistically and long-term about any implementation and you have to help them to trim it down to a first prototype. If they don't understand why you want to solve a problem and how exactly, they will imagine that it will be a huge thing and answer "It's hard or even impossible". You have to face it: Engineers and you speak different languages. And that's a problem! And when both sides of a collaboration feel bad, you can be sure that you will face a lot of misunderstandings, delays, and failures. When you don't find a mutual language, things get overcomplicated. And you cannot help them to reduce complexity if you have no idea on which level of technicality they are operating. If you manage to get a good communication with your developers, however, they can help you make good product decisions. They need the right context for it. **The Pizza App** Imagine you're a working at a startup building a pizza delivery app. You work closely with software engineers to bring features to life, but often hit roadblocks. One time, you were thrilled about launching a pizza rewards program. You told the engineers, "Users will earn points for each pizza they order to get free french fries!" But the team pushed back, saying the current database structure wouldn't support that easily. You didn't understand their technical limitations and kept pressing for the launch date. In the end, the engineers had to rush a messy, complex solution. The rewards program launched full of bugs and security flaws. Users were frustrated, you were embarrassed, and the engineers were burned out. It was a failure driven by communication breakdowns. The non-technical team was focused on the end-user experience. The engineers approached decisions from a technical feasibility angle. You spoke different languages, so you couldn't find a solution that worked for both perspectives. This communication gap is common, but there are ways to bridge it. This book will equip you with tactics to collaborate effectively with technical teams, even if you don't understand the nitty-gritty details. You'll learn how to: - Ask questions that uncover technical constraints early. - Grasp the scope and complexity of developers tasks. - Avoid oversimplifying or trivializing technical concerns. - Set realistic timelines based on engineer feedback. - Flag potential technical roadblocks and make alternate plans. - Write good user stories with the right level of technical requirements. You will learn this while getting a good understanding of web development works. With these competencies, you can lead technical teams through a shared vision. Engineers will feel empowered to raise issues early and propose creative solutions. You'll be able to make informed product decisions. Together, you can build software that delights users and pushes technical boundaries. But it all starts with communication. Read on to begin bridging the gap. ## **Web apps and developers.** Simplifying terms and roles **Terms** A: "Hey there! So, you might have heard a bunch of words like 'software', 'web technology,' 'web development,' and 'coding' at our company. But let's keep it simple. Imagine you're making something cool for the internet. Let's say, something to order pizza. We'll just call that thing a 'web app'. It means the same thing as all those other words, like also 'website' or 'software.'" B: "Got it! 'Web app' it is." **Roles and Descriptions** A: "Now, let's talk about the people who make these 'web apps' happen. They are called programmers, coders, engineers, and developers. And there are many roles they play: 'frontend developers' who work on what you see on the screen, and 'backend developers' who make sure everything behind the scenes runs smoothly. Some are 'tech leads' who guide the team, and others are 'QAs' or 'testers' who make sure everything works perfectly. But you know what? Let's keep things super simple for this book. They will all be called 'developers' in this book because they're all part of the team making 'web apps' and they all read and write code." B: "That sounds way easier! 'Developers' it is, then. Thanks for clearing that up!" ## Think like a developer to work best with them To bridge the gap between you as non-technical person and engineers, you have to first learn about their mindset and adopt yours accordingly. The first principle is: Software is never simple! Don't get misled by things that say otherwise, like no-code tools, 1-click website installations, and AI tools. Developing is a craft and an art. ### The Beginner Developer Mindset Here is the right set of mindset that good developers have and that you should adopt as well: - There will always be a lot more technical things that you don't know and don't understand than you understand. - You always only know a fraction of everything, even in the area that you are specialized in. - You have to know and respect your technical limitations, be humble with the little that you actually understand. - Never say "I can code", even after many years of coding. When you learned to write some simple scripts say "I just started and could solve a small challenge only". - You have to learn continuously, there are new concepts and tools every day. - Focus on what works long-term and deep dive into it, not on the latest shiny thing. - You know just a tiny bit of one or two programming languages and there are many others and even in your programming languages there is so much that you don't know. - You can know very little by heart, even experienced developers will search for solutions every single day. ### How to get technical There is a global set of rules that you can follow to become more technical, regardless of which technology you work on: - **Learn what you need**, when you need it, and find the right method that suits you. - Research technical terms and concepts when they get used in your company, research them and find out how they relate to your work. - Ask a lot of questions to developers to understand how they are working and how stuff works. - **Try technical things out** yourself, expect it to fail and break. - Be aware that technical skills become less important due to improved development tools and processes and yet it still helps to understand the underlying concepts because you get more flexible and less dependent on specific solutions. - Stay updated on developments and trends through reading, listening, and watching others discussing and teaching it. - Take time to really do intro courses online, on boot camps or hackathons - Dig deep into the technology that your current or former company is using and write down how others are describing its strengths and challenges. - Observe engineering meetings and discussions, both on what they talk about and how they do it. - Assume that actual code that is written in a large team of engineers is a lot more complicated than code that you write alone. ## **The Pizza App** - An app's technical parts are like a pizza restaurant To help you keeping the big picture, I will use one concept throughout the book: Pizza. An app is like a pizza shop, every part has their specific task and they all need to work smoothly together to create a great result. In this chapter, I will go through the full analogy between a web app and a pizza restaurant. This already describes all technical concepts from this book. If you only read and understood this, you already learned the most important thing. :::spoiler A picture of the menu of a pizzeria ::: - **Code** is like the secret sauce in the pizza-making process. It's the set of instructions that tells the kitchen how to prepare the pizza, combining various ingredients to create the final product. - **Command line applications** are like a secret code that the pizza place uses to make special pizzas. They're programs that you can run on your computer by typing text commands into a terminal or command prompt. - **Frontend: The Menu** The frontend is like the menu that shows you all the different types of pizza you can order and their prices. It's what you see and interact with when you're deciding what to order. - **Backend: The Kitchen** The backend is like the kitchen where the pizza is made. It's where all the ingredients come together and the pizza is cooked and prepared for you. - **Application Programming Interfaces (APIs): The Phone:** The APIs are like the phone lines that the pizza place uses to take your order and tell the kitchen what to make or get from the stockroom. They connect what you see on the menu with the kitchen and storage. - **Database: The Ingredients Stockroom** The database is the stockroom where ingredients are stored and retrieved as needed. - **Version control: Managing recipes** is like keeping a record of all the different pizza recipes the pizza place has ever made. It's a way of managing changes to the application's code over time and making sure that everyone is working with the same version. - **Deployment: The Delivery** Deployment is like the delivery person who brings the pizza to your door. These are the most important elements to create and deliver the pizza. Here are a few more concepts to make sure you receive the pizza: - **Server: The Waiters Taking Orders:** Servers are like the waiters who bring your pizza to your table. They are the computers that host the web app and serve it to users when they request it. - An **IP address** is like the address of your restaurant. It's a unique set of numbers that identifies your device on the internet. Every device that connects to the internet has its own IP address. - **HTTP request: Order a pizza** When you place your order from your desktop or mobile device, it's like making a **request** to the pizza place. The request goes through the APIs to the backend and database, where your order is processed and the pizza is made. The web server then sends the website's content back to your device, and you see the confirmation that your pizza is on its way. - **Cloud computing: The big kitchen** is like the pizza place having a big kitchen that can serve lots of customers at once. It's a way of using remote servers to store, manage, and process data and applications over the internet instead of on your local device. - **CDN: Network of pizza bakers** (Content Delivery Network) is like a group of delivery people who work together to make sure your pizza gets to you as quickly as possible. It's a network of servers located in different parts of the world that help deliver the website's content to users quickly and efficiently. - **Authentication and Security: Keeping the Restaurant Safe:** Authentication is like showing your ID to the pizza place so they know who you are and that you're allowed to order pizza. It's a way to make sure that only authorized people can access certain parts of the website or database. - **Containers** are like little pizza boxes that keep different parts of the pizza separate from each other. They're a way of packaging up software applications and their dependencies so they can be easily deployed and run on different computers and servers. - **Microservices** are like different types of pizza that the pizza place offers. They're small, independent parts of a larger application that can be developed, deployed, and scaled independently of each other. - **Software architecture**: Imagine software architecture as the blueprint of the pizza shop. It outlines how different parts of the web app fit together, just like a well-designed restaurant layout ensures smooth operations. - **Log files** are like the records that the pizza place keeps of all the orders they receive and pizzas they make. They're a way of tracking what's happening in the application and troubleshooting issues. - **AB Testing** is like taste-testing different pizza recipes. It involves trying out variations to see which one customers prefer, helping improve the app based on user feedback. - **Email** is similar to the communication channel the pizza place uses to keep you updated. It's how the restaurant informs you about promotions, new menu items, or the status of your order. - **Open source software** is like a recipe that the pizza place shares with other people so they can make their own pizzas. It's software that's freely available and can be modified and distributed by anyone. - **Technical Debt** is similar to overdue maintenance in the pizza shop. It's the result of cutting corners in the past, which can slow down development. Addressing technical debt is like renovating the restaurant to ensure it stays efficient. - **Software Development Lifecycle:** The Software Development Lifecycle is like the step-by-step process of creating a new pizza recipe. It involves planning, development, testing, and deployment, just as making a new pizza requires careful steps from dough preparation to serving. - **Testing and Quality Assurance: Food Quality Control:** Relating testing and quality assurance processes to ensuring food quality before serving it to customers. These technical concepts are all related to building and managing websites and applications, and they all contribute to making the website or application more effective, efficient, and user-friendly. ## **Code** - The language to tell machines what to do > Person_A: "Have you started writing the code for the new feature yet?" > Person_B: "Not yet, I'm still trying to find the best language and code style for this problem." Code is how humans tell computers in a structured way what they should do. The structure is given in a way that humans can also understand it. How could the code equivalent for creating a pizza look like? Instead of getting the pizza on your plate, we'll print it out on the user's computer. I'm using the Python language and will show it in two other languages so you can see how different it looks. ```python # Python # Create a function def compose_pizza(topping): return "Your pizza: " + topping # Execute function and save result to variable my_pizza = compose_pizza("mushrooms") # Print out the result print(my_pizza) ``` To execute this script, go to a search engine, search for "Execute Python online" and paste and run the script there. When you run this script, it outputs `Your pizza: mushroom`. As the function works with every topping, you could also create a spinach pizza (using `compose_pizza("spinach")`). When I started to learn coding, I could not believe that you can write big apps with such simple structures, yet all apps work like this, just with a lot more functions. :::info **How to work with the code in this book?** There will be code snippets all over the book to illustrate the code. Here's how you should treat it: - Try to understand the big picture, not the details. - Copy it to an online editor and run it yourself. - Enjoy when it works. - Remix when you feel brave. - Move on if something breaks or confuses you. ::: Every programming language has its own structure and rules. This is called syntax. And every programming language was created or turned out to be very good with some special use case, e.g. the creation of websites or for data science. There are also different philosophies how a language works. And around every language, there are lots of tools, and ready-made libraries that help with tasks, e.g. connecting to a website. There are no good or bad programming languages per se, the best one is the one that helps you best to solve your problems. Experienced developers usually have 1-2 languages in which they are very strong and can get along in multiple others. Don't get dogmatic and judgemental about languages (e.g. "Language A is only for beginners!", "Language philosophy B is the best!" or "Language C is slow"), focus on learning as much as needed to be proficient in one language. There is a concept of high and low level languages, where low level means that you get closer to For reference, here's the little Pizza app in another language, Haskell, from the family of so-called functional languages: ```haskell -- Define the composePizza function composePizza :: String -> String composePizza topping = "Your pizza: " ++ topping -- Define the main function main :: IO () main = do let myPizza = composePizza "mushrooms" putStrLn myPizza ``` There's also the concept of high and low level languages. The depth refers not to easiness of a language, but how close you are to the computer. As this book is on software and low-level languages are most used in hardware, here's just the beginning of how our little pizza composer would look like in a low-level language such as `Assembly`. Don't look at the details, just notice how much more you need and control here: ```assembly section .data pizza_template db "Your pizza: ", 0 topping db 0, 0, 0, 0, 0, 0, 0, 0 ; Buffer to store topping section .bss topping_size resb 8 section .text global _start print_string: mov eax, 4 ; sys_write mov ebx, 1 ; file descriptor (stdout) mov ecx, edi ; message address mov edx, esi ; message length int 0x80 ; syscall ret … ``` The three languages I've shown have a very different syntax, an very own way of defining functions and grouping things together. You can, however, see some common ways to give structure with brackets `(…)`/`{…}`, and separating things with `:`. Let's explain more concepts of code by expanding our pizza app. **Libraries** Libraries add pre-built code packages that enhance efficiency and simplify development. If you package many multiple libraries together, for example for making the creation of websites easy, these are called frameworks. ```python import random def suggest_random_topping(): toppings = ["mushrooms", "pepperoni", "olives"] random_topping = random.choice(toppings) return random_topping ``` This function uses the library `random` that helps picking one random topping. It holds a `list` of possible toppings. This list is often called `array` as well. The script then runs the random library to get a random topping and saves the result to a `variable` called "random_topping". Finally, it returns this variable, similar to printing it out for users but for the machine, so that other functions can use the result. **Loops, and conditionals** Let's expand our pizza app, so that you can create multiple pizzas wich multiple toppings–except "jam", who would eat that on a pizza? For this, you need loops, and conditionals. ```python def create_multiple_pizzas(num_pizzas): pizzas = [] for _ in range(num_pizzas): topping = input("Enter a topping: ") if topping != 'jam': pizza = "Your pizza: " + topping pizzas.append(pizza) print("Pizza added:", pizza) # Print statement to check pizza addition else: print("Jam topping not allowed.") return pizzas print(create_multiple_pizzas(2)) ``` I will now describe a couple of things that engineers spend time with every single day and that is not writing new features. These are the things that from the outside feel like slowing down the process and are still needed elements of the craft. You need to know and value these. **Debugging** There is one powerful concept in code which is debugging. Debugging means identifying and fixing errors (bugs) in code or as I wrote before, often it means, finding the small errors, like a closing bracket. :::info **Joke:** You spend 10% of your time on writing new code. And 90% on finding the missing comma. ::: The easiest way to debug is to print intermediate results to see what happens one after another. Let's expand our last script: ```python def create_multiple_pizzas(num_pizzas): pizzas = [] for _ in range(num_pizzas): print(f"DEBUG: Number of pizzas: {num_pizzas}") topping = input("Enter a topping: ") if topping != 'jam': print("DEBUG: You entered something allowed, i.e. not jam") pizza = "Your pizza: " + topping pizzas.append(pizza) print(f"DEBUG: Pizza list so far {pizzas}") print("Pizza added:", pizza) else: print("Jam topping not allowed.") return pizzas print(create_multiple_pizzas(2)) ``` When you run this, the script will output intermediate results and you can check whether this is what you expect and fix if you find an error. The only new element here is `f("Add some {variable}")` which is called string interpolation, or put simply, combining natural text with variables. :::info All important elements of code: - **Variables:** Variables store data temporarily and allow code to work with changing values. - **Functions:** Functions are reusable blocks of code that perform specific tasks. - **Data Types:** This is ow different types is organized and stored in data (e.g., numbers, text, lists) - **Control Structures:** Loops repeat actions and conditionals enables code to make decisions. ::: There is one more aspect when it comes to code: Everyone writes differently, there is no single right way, and often different solutions are possible. You can imagine that this can get different when multiple people work together. Here's again the simplest version of our Pizza app: ```python # Python # Create a function def compose_pizza(topping): return "Your pizza: " + topping # Execute function and save result to variable my_pizza = compose_pizza("mushrooms") # Print out the result print(my_pizza) ``` Another developer could get the same result with this code: ```python c_p = lambda t: "Your pizza: " + t print(c_p("mushrooms")) ``` **Maintenance and legacy code** Developers don't always start from scratch, they often continue work on old code, like from a former employee or from your own code from one year ago. This code often has a different format and is very complicated to understand. Also, code needs care, you cannot write it once and it works forever. For example, bugs get found in your programming language, or security issues in a library that you use. Or the main browser changes. And then your app stops working. The outdated code that is called *legacy code*, the hygiene work to keep software up-to-date is called *maintenance*. **Code Style** How you write your code is significant to get consistency. It has an impact on code readability and maintainability. In the examples above, there are two ways to write code and solve the same problem. It uses very short names and different features. Both developer can argue that their style is better. And who is right? There is no right here, but as soon as you work together on an app, you need to align on some basic rules. This is called *Code Style* and it's the agreements on how to write the code as there's always many ways to do it. :::info **Advice:** Write code so everyone can understand it. Even yourself in six months. ::: **Code reviews** When developers finish their part of the work on a new feature, they send it to other engineers to review it. This is called *Code Review*. Engineers read code together and check it for style. **The risk of no/low code** There are more and more tools that promise to let you create software without writing code but with drag'n'drop. Textual instruction is replaced by visual instruction. This is easier to use if you don't know formal language, but you have less control and get new limits. It means you use one huge framework and are fully dependent on what it can and cannot do. This has the risk of massive legacy code. ### **Whitespace or Tabs?** - Details matter for developers Here's one example of how difficult even small things like code style can get. Developers can get very opinionated and have heated emotional discussions about this: > Should you write code with whitespaces or tabs? What is this about? Let's take the code to create a pizza: ```python def compose_pizza(topping): return "Your pizza: " + topping ``` The debate is about the space in the second line before `return`. It is a visual indentation that shows that the return is part of the function. Indentation improves code structure and visual organization. And there are multiple ways to handle this: use no indentation at all, either use one or multiple spaces or use one tab (the same way as in a word processor). Let's visualize spaces with `.` and tab with `>` to see how many ways such a simple rule gives us. ```python # No indentation def compose_pizza(topping): return "Your pizza: " + topping # Tab def compose_pizza(topping): >return "Your pizza: " + topping # 1 space def compose_pizza(topping): .return "Your pizza: " + topping # 2 spaces def compose_pizza(topping): ..return "Your pizza: " + topping # 3 spaces def compose_pizza(topping): ...return "Your pizza: " + topping ``` If even just two people work on such code and use different rules for indentation, the code has mixed code style and is harder to read ("Why is the indentation different?"). Some programming languages have no rules about indentation and teams of developers need to find an agreement on such code styling together. You used Python here and Python is whitspace sensitive: It forces you to use indentation of any kind. They even have an official proprosal (PEP8) which suggests 4 spaces. Example one will not work hence, it will give you an error message. Do developers memorize all these code styles and make no errors ever? Of course not. They use tools to check their code automatically for code rules and styles. *Code linters* enforce coding standards, including whitespace rules in your code editor. **What you can learn about developers' work from tabs vs spaces** The fact that developers disagree over the use of whitespace or tabs may seem like a small, trivial matter, but it actually highlights some important lessons that non-technical people can learn from: **There is no one "right" way to do things in software development.** Different developers have different preferences, and what works well for one person or team may not work well for another. This is why it's important to have open communication and collaboration among developers to find common ground and agree on coding conventions that work for everyone. **Attention to detail is important in software development.** The use of whitespace or tabs may seem like a minor detail, but it can have a big impact on the readability and maintainability of code. Consistent formatting and style can make code easier to understand, debug, and modify, which ultimately leads to better software quality. **Technical debates can be passionate and heated but ultimately it's important to focus on the bigger picture.** While it's natural for developers to have strong opinions and preferences, it's important to keep in mind the end goal of delivering high-quality software that meets the needs of users and stakeholders. Sometimes, it's necessary to compromise and prioritize what's best for the project as a whole, rather than getting bogged down in minor technical details. You as non-technical team member can help developers to not get lost in these kind of discussions but keep the eyes on the price and balance coding hygiene and business outcome. ### Challenges with code in daily engineer work Code itself is not the most complex thing. Contrary to popular belief, developers don't spend as much time thinking about how to write a line such as `def do_this_or_that` and once the code is there, everything is fine. The challenges are around consistency, and collaboration. There are countless programming languages and philosophy and code can be seen as a large family of formal languages with many dialects. So the challenges that you can face with developers on a daily basis can be: - Challenging which language to use, especially in a team ("Why not X? Y has problems with Z!"). - Challenges to read what someone wrote some time ago and understood what was meant (including code that you wrote yourself). ## **Command-line tools** - How developers work with specialized apps that you manage with text input When you look over the shoulders of a developer, you will likely see a lot of text on their monitor. Don't be scared. When you work with code, it is easier to interact with text and not only with visual drag'n'drop. As code is the language to speak with computers and code is text, this is the easiest and most direct way to interact with computers. Yes, there are also visual tools that offer you "no code" and this means that you have less control over what and how you speak with computers. So you should not be afraid of the text, just embrace and learn the most important things that bring you to 80%. The first thing that developers use are so called command-line apps. The commandline is the direct interface to talk to computers. And there are a lot of small tools that help you with it. All of them are specialized and do exactly one task. They have short names because developers are lazy and do not want to memorize a long name and retype it often every day. So instead of `list` to list all files in a given directory, there is the CLI app `ls`. There's `touch` to create a new file, there's `host` to show you technical details about a domain, and there's `ssh` to connect to a remote computer via text. And there are thousands of other small helpers. Many of the ones that developers use most are related to working with files, such as copying or editing text files – because everything about code is in text files. Often, you are forced to use text-based interaction, especially when you connect to a computer that runs code, a server. All command-line apps, also called CLI (command-line interface), work with the same method: - You enter a `command` - You add `arguments` - The computer outputs the result of your command The most simple example with arguments is the CLI app `cp` for copying files: 1. `cp -v file1.txt file1_copy.txt` 2. `cp` is the command 3. `file1.txt` is the file that you want to copy 4. `file1_copy.txt` is the name of the copy 5. Both `file1.txt` and `file1_copy.txt` are arguments 6. `-v` is to make `cp` verbose, i.e. tell us what it did Once you run this command, the computer will output the result of your action. In this case, it will tell you `file1.txt -> file1_copy.txt` to show that it was succesful. The most used CLI tools are for the following use cases: - Navigating the file system (e.g., `cd`, `ls`, `pwd`) - Copying, moving, renaming, and deleting files and directories (`cp` for copy, `mv` for move, ) - Transferring files to and from a server using command line tools (e.g., `scp`, `rsync`) - Advanced command line tools for specific tasks (e.g., `awk`, `sed`, `grep`) Because you need to use the command-line when connecting to a server, let's have a full walkthrough of what you do then: You know that a former developer once saved the recipe for margerita to our server. 1. First, you open our terminal. The terminal is an app write commands to the computer and run command-line apps. There are many different terminal apps that you can use. Imagine it's like our magic window to your computer. 2. `ssh` allows you to connect to other computers securely. Type `ssh username@hostname` and press Enter. For your pizza app this is `ssh owner@yummypizzaapp.com` 3. Use `ls` to list what's in your current folder. Type `ls` and press Enter. You'll see a list of files and folders, including `recipe_margherita.txt` - you were lucky to directly get to the folder that had the file… 4. To check where you are in your computer, use `pwd`. Type `pwd` and press Enter. It'll show you the path to your current location. 5. Now, let's make a copy of 1.txt to have a backup and maybe change it later. Type `cp recipe_margherita.txt recipe_margherita_copy.txt` and press Enter. You've just copied the recipe to a new file. 6. Let's read the content of `recipe_margherita_copy.txt` using `less`. Type `less recipe_margherita_copy.txt` and press Enter. You can scroll through the file by pressing the arrow keys. When done, press 'q' to exit. 7. The `host` command helps you find information about websites. Type `host yummypizzaapp.com` and press Enter. It'll show you details about the restaurant's server. 9. If you want to clear your terminal, use `clear`. Just type `clear` and press Enter. It's like starting with a fresh slate. These basic commands will help you navigate and do things in the shell. ### Challenges with command line tools in daily work life - You have a new challenge and need a new tool that solves it and this tool works totally different than anything that you used before. - You think it's a very small problem that you can quickly tackle and then the CLI app does not work as expected and returns unexpected output. ## Code Editors - Your Web Development Command Center Code editors are like the chef's workstation in a bustling pizzeria. They're where developers knead and toss their web app dough, which is essentially lines of code. Imagine a pizzeria's kitchen, but instead of flour and sauce, it's filled with lines of code and creativity! ```img Screenshot of code editor with pizza app ``` **Benefits of Using Code Editors** Code editors keep the code organized, help spot errors, and even complete your coding sentences, just like a skilled chef who knows how to create the perfect pizza every time. These alternatives, like using pre-made pizza bases and store-bought toppings, might seem convenient, but they lack the precision and customization that code editors provide. It's like comparing a frozen pizza to one made from scratch by a master chef. **Why Not Drag-and-Drop and Visual Tools** Now, you might be wondering, "Why not just use drag-and-drop or visual tools in web development?" Well, these tools are like assembling a pizza from pre-made ingredients. It's quick and easy, but it doesn't offer the same level of control and craftsmanship. Code editors offer precision and flexibility, just like a chef handcrafting a pizza crust to fit a specific customer's taste. They allow developers to tailor their code to the exact needs of the web app, ensuring it works flawlessly. So, in the world of web development, code editors are the secret ingredient that makes everything come together perfectly. And now, you're getting a taste of why they're so important. In the next chapter, we'll dive deeper into the world of code editors and see how they work their pizza-making magic. **How can code editors help?** Here are 15 things that code editors help with in the context of web development: (TODO: Too many functions of editor, trim down) 1. **Writing Code:** Code editors are where developers write the instructions that make web apps work, just like a chef follows a recipe. 2. **Organization:** They keep all the code neat and tidy, like arranging pizza ingredients neatly on the counter. 3. **Error Checking:** Code editors help find mistakes in the code, similar to a chef checking if the pizza is cooked just right. 4. **Auto-Completion:** They suggest words and phrases to make coding faster, like having someone finish your sentences while writing a pizza menu. 5. **Formatting:** Code editors make sure the code looks nice and is easy to read, similar to arranging pizza toppings in an appealing way. 6. **Color Coding:** They use colors to highlight different parts of the code, making it easier to understand, like using different colors for pizza ingredients to distinguish them. 7. **Finding and Replacing:** You can quickly find specific bits of code and replace them, just like swapping out ingredients on a pizza. 8. **Version Control:** Code editors help keep track of changes made to the code, like recording every variation of a pizza recipe. 9. **Integration:** They can work with other tools and services, just like a pizza oven fits into a kitchen setup. 10. **Customization:** Developers can personalize their code editor to work the way they like, similar to a chef customizing their kitchen tools. 11. **Collaboration:** Code editors make it easy for multiple developers to work on the same code, like chefs working together to prepare a large order of pizzas. 12. **Code Suggestions:** They offer ideas and solutions to coding problems, akin to suggesting new pizza recipes when you run out of ingredients. 13. **Debugging:** Code editors help find and fix issues in the code, similar to troubleshooting why a pizza didn't turn out as expected. 14. **Extensions:** Developers can add extra features to their code editor, just like adding new kitchen gadgets to make pizza-making easier. 15. **Efficiency:** They save time and effort, helping developers create web apps faster, like a skilled pizza chef who can whip up pies in no time. These are some of the ways code editors assist developers in their work, making web development more efficient and manageable. **Why editors and setup matter for collaboration?** (TODO) ### Challenges with editors in daily work life - Editors are meant to speed up development, but this requires them to be set up in an optimal way which is often not the case. - Often, you have an update, a plugin breaks, or you have a new problem that you never worked on with the editor before. Getting your editor back to work can take hours. - As editors are important tools for all engineers, having a broken editor can mean that no other work can be done at all. ## Technical file formats - How information is saved for developers (TODO: Why am I introducing file formats here?) In this chapter, we'll explore technical file formats, which are like different containers for organizing data in web apps. We'll focus on four key formats: JSON, CSV, YAML, and XML. These formats help web applications communicate and store information. Think of them as different ways to package your pizza orders. You will find them in various applications. **YAML - The Neatly Folded Pizza Menu** YAML (YAML Ain't Markup Language) is like a neatly folded pizza menu. It uses indentation to show the structure. Here's an example: ```yaml --- - pizzaName: Pepperoni toppings: - cheese - tomato sauce - pepperoni price: 12.99 ``` In this YAML menu, you have a pizza with its attributes and toppings listed clearly. **XML - The Tagged Pizza Ingredients** XML (Extensible Markup Language) is like labeling each ingredient on the pizza. It uses tags to mark the beginning and end of each piece of information. Here's an example: ```xml <pizza> <pizzaName>Pepperoni</pizzaName> <toppings> <topping>cheese</topping> <topping>tomato sauce</topping> <topping>pepperoni</topping> </toppings> <price>12.99</price> </pizza> ``` In this XML, each pizza and its attributes are enclosed in tags, making it easy to understand. **CSV - The Comma-Separated Slices** ``` Pizza Name,Toppings,Price Pepperoni,"cheese, tomato sauce, pepperoni",12.99 Hawaiian,"cheese, tomato sauce, pineapple",11.99 ``` In this CSV format, each row represents a pizza with its name, toppings (enclosed in quotes when there are multiple toppings), and price. This format is suitable for straightforward tabular data representation. The columns are separated by a single character, most often, a comma `,` is being used for it. ## **Frontend** - What the user see and interact with > Person_A: "The frontend for the new web app looks great." > Person_B: "Yes, I'm working on the database schema right now." I will now deep dive into the 3 main parts of an app: Frontend, backend, and database. Frontend and backend are two parts of a web app. The frontend is what you see and interact with, while the backend is the part that does the work behind the scenes. The database is what manages the data for the app, that means it saves and retrieves it for the backend and frontend. Frontend is what happens in the browser. There are two parts to the frontend: What you see and what you can interact with. What you see is HTML and CSS. HTML is structuring the content so a machine can understand it, CSS is adding style. HTML is like the unstyled menu, you can see clearly see the name of the pizza and prices that belong to it, but it looks boring. CSS adds the fonts, different sizes, the colors, so it looks really good. We're having a pizza order app, though, so here is the basic structure. ```html <html> <body> <button>Order <span id="amount"></span> pizzas</button> </body> </html> ``` To try it out, search for "HTML bin online" and copy the code in. You will see a button that says "Order pizza". **HTML (Hypertext Markup Language)** Think of HTML as the menu in your pizza restaurant. It's the foundation, telling you what's available to order. In web development, HTML structures your web page content. It's like listing pizzas with their toppings and prices. But now the page looks completely dull. You want some styling. This is where CSS comes into play. **CSS (Cascading Style Sheets)** Now, think of CSS as the chef's artistic touch. It's how you style and decorate your pizzas. Just like the chef adds sauce, cheese, and toppings to make the pizza look delicious, CSS makes your web content visually appealing. The CSS goes in the header of the HTML page, because HTML and the DOM get loaded from top to bottom and any styling needs to come before the content. ```html <html> <head> <style> button { background-color: black; color: white; } </style> </head> <body> <button>Order <span id="amount"></span> pizzas</button> </body> </html> ``` This is no masterpiece, but at least the button stands out now. You can beautify your app completely with CSS. There are also frameworks for CSS that make it easier to build beautiful web apps. **Mobile-Friendly Development:** Browsers are everywhere and browsing on mobile devices keeps growing. On mobile devices, touching is the first interaction, on desktop it's moving with the mouse. Web apps are now developed mobile-first. You start designing it for the smallest device and keep the user interface as simple as possible. You add designs for bigger devices only after you made sure that your website is optimized for the small device. Because mobile connections can be shaky and slow, a fast loading speed and high performance for web apps is important. All of the code is written once and it has rules that tell a web app how to show depending on the screen sizes. This is called responsive design. Let's adjust our button and favor mobile devices by making it shiny and red for them only. It will show black for all bigger devices. The detection of a device happens by asking it for its pixel size, so how much is shown on the display. You can see the nature of the DOM here again: It reads from top to bottom and when something new comes, it simply overwrites what came before, so here first the small devices is described and if it's bigger, the CSS rule will be overwritten by the second one. Notice the advantage of mobile first development: You only have one code for all devices. ```html <html> <head> <style> /* For smartphones and smaller screens */ @media not all and (min-width: 640px) { button { background-color: red; } } /* For tablets and larger screens (max-md) */ @media not all and (min-width: 768px) { button { background-color: black; } } </style> </head> <body> <button>Order <span id="amount"></span> pizzas</button> </body> </html> ``` **Make button interactive with Javascript** The button looks nicer, but the button does not do anything when you click on it. You need Javascript to make it interactive: ```html <html> <body> <button id="orderButton">Order pizzas: <span id="amount">0</span></button> <script> // Get references to the button and span elements const orderButton = document.getElementById("orderButton"); const amountSpan = document.getElementById("amount"); let pizzaAmount = 0; // Initialize the pizza count // Add a click event listener to the button orderButton.addEventListener("click", () => { pizzaAmount++; // Increase the pizza count amountSpan.textContent = pizzaAmount; // Update the span with the new count }); </script> </body> </html> ``` **JavaScript** Meet JavaScript, your waiter. It's the one making things happen when you interact with the menu. JavaScript adds interactivity to your web app, like taking orders from customers. How JavaScript does it is by changing the structure of the HTML. This is called DOM. **DOM (Document Object Model)** The DOM, which stands for Document Object Model, is like a tree that represents a web page. Each element on a web page, like buttons or text, is a part of this tree. The DOM is like the order ticket. It's how the kitchen knows what pizzas to make. In web development, it's the programmatic way to interact with your HTML and make changes. JavaScript, or JS for short, can change this tree. Here's how the above JavaScript changes the DOM: When someone clicks the button with the label "Order pizzas," JS listens for that click. When it hears it, JS adds 1 to the pizza count and updates the number you see next to the button. So, if you click the button once, the number goes from 0 to 1, and if you click it again, it goes from 1 to 2, and so on. JavaScript is like the magic behind the scenes that makes the web page do things when you interact with it! **User Interface (UI) and User Experience (UX):** The user inface is the visual layout and design of the web app that users interact with. They compose of the structure and content (HTML), the design (CSS), and the interaction (Javascript). How the full interface feels and works for the user holistically is called User Experience (UX). **Browser Compatibility and Cross-Browser Testing** Picture different people ordering pizzas, each with their own preferences. Similarly, different web browsers might display your web app slightly differently. This used to be challenging, but it's important to make sure everyone gets the right pizza and these days, it's way easier to achieve browser compatibility. To ensure everyone enjoys your pizzas, you need to taste them yourself. Similarly, cross-browser testing involves checking how your web app looks and works on different browsers. It's like trying your pizza on different plates to make sure it's just as delicious. **Client-Side vs. Server-Side Rendering** Think of this as deciding where to prepare the pizzas – in the kitchen or at the table. Client-side rendering means making pizzas at the table (the user's device), while server-side rendering is like having them made in the kitchen (the server). Both have their pros and cons. **Single-Page Applications (SPAs)** Imagine if you could order all your pizzas on one menu page without flipping through pages. That's what SPAs do - they make your web app smoother by reducing page changes. **Internationalization (i18n) and Localization (l10n)** Just like offering your pizzas with different toppings for various tastes, i18n and l10n mean making your web app speak different languages and adapt to local customs. It's like offering pizzas with different regional flavors. **Progressive Web Apps (PWAs)** PWAs are like the modern delivery service with an app. They are a web app but can be installed on mobile devices and feel and behave very much like a native app. So they use the same codebase as the web app, but look like an app. This is a huge opportunity, because you don't need to maintain two codebases. PWAs often also offer offline support: Imagine your pizza place can serve even when the phone lines are down. Similarly, offline support means your web app can still work without an internet connection. It's like enjoying your pizza even if the internet is temporarily out. **Conclusion** So, think of your web app as a pizza delivery service. The frontend is like the order-taking part, while the backend is the kitchen. The frontend talks to the backend to get the pizzas (data) and serves them to the customers (users). So, that's the frontend in a pizza nutshell. It's all about the menu, the presentation, and the interactions. Next up, we'll explore the backend, the heart of your web app where all the cooking happens. Stick around! ### Challenges with frontend in daily work life - HTML and Javascript look easy for easy examples, but can become very big files very quickly. - There are many different ways to create the frontend, many philosophies and things change rapidly, especially in Javascript, so it's hard to align on "best ways" for a team. - It's challenging to find a good balance between performance, usability, and ease of development. - As the frontend gets shipped to many different devices in size and type, it's quite hard to make sure that it looks and works right everywhere. - Frontend needs a close collaboration with usability, hence working together well with product designers is crucial. ## **Backend** - The logic that works with and transforms the user data The frontend shows stuff to the user, but it cannot store or transform data. For our pizza web app this means: The frontend can show a button, but you cannot actually order a pizza. You need a service in the background to process the order. This usually happens not in the browser of an user, but on a server. This service is then called backend. The backend handles business rules and logic to process user inputs. So in the pizza analogy: The backend is the act of baking, taking ingredients from the storage (= database) and processing it and giving it then to the customer. The backend is where all the rules for making the pizza get applied. It has many of these small functions that help to make it happen. For the task of making a pizza, the function in the backend could look like this: ```python def bake_pizza(name, ingredients, seconds): add_toppings(ingredients) put_to_oven(name) wait(seconds) put_from_oven(name) ``` So for a Margherita, it would be then. ```python bake_pizza(name='Margherita', toppings=['Tomato Sauce', 'Cheese'], baking_time=720) ``` To guarantee that the logic runs in the right way, the backend also applies rules. ### **Data Validation and sanitization: Right and clean orders** The backend checks the input of users and makes sure only wanted data is processed. This is called data validation and sanitization. For our example, the user can input name, ingredients, time: - The name should be only standard letters (or did you ever order pizza with the name "💩"?) - The ingredients must only be words consisting of letters - The time must only be integers, numbers with no comma. And it must be positive numbers (find me a pizzeria where the cook shouts: "Oh, your pizza will be ready in -2 minutes!") Here's how to check in the backend for these two rules for "seconds": ```python if not isinstance(seconds, int) or seconds < 0: raise ValueError("Seconds must be a non-negative integer.") ``` In plain English: "If the 'seconds' argument is not an integer or if the integer is below zero, show an error message and don't process the function further". ### **Authentification and authorization: The bouncer** The backend is also the gate keeper, usually. It checks for every incoming request: Who can do what? This is to protect sensitive data and make sure the right people can do what was intended to do so. So, for our pizza web app, e.g. only logged-in users can make an order: ```python if user.is_registered == True: print('Welcome back! May I take your order?') else: print('Please register first to make your order.') ``` To test whether someone is logged in, a small information is created by the backend and sent to the frontend with the information: A cookie. The cookie is created by the backend and then sent to the frontend. The backend is responsible for generating and managing cookies, which are small pieces of data that the server (backend) sends to the client (frontend) to store information. These cookies can include things like user session IDs, login status, and other data that helps the server keep track of the user's interactions with the web application. The frontend stores and sends back these cookies as needed, but the initial creation and management of cookies happen on the backend. Here's how this could be in code: The backend sets a cookie first. ```python # User logged in via frontend and sends this info to backend # Backend sets cookie that user is logged in set_cookie("logged_in", "yes") ``` And here's how the frontend checks for the log-in status from the cookie and acts upon it: ```javascript function checkLoginStatus() { var loggedIn = getCookie("logged_in"); if (loggedIn === "yes") { return "Yes, logged in already. Can order."; } else { return "Not logged in yet. Cannot order"; } } ``` And once the frontend has succesfully checked for log-in state from the cookie, it can assume that the user is logged in. ### **Caching: Quick Access to the Oven Manual** In web development, caching is akin to keeping the manual for your oven right at your fingertips. Imagine you're using a complex oven to bake your pizzas. Instead of fumbling through a drawer every time you need to refer to the oven's manual, you keep a copy of it nearby for instant access. Loading the huge manual everytime you need it would mean downloading lots of content and would be slow. That's why you cache the manual and can quickly search through it. This is how a cache aka manual works in code: ```python # Check if the oven manual is already cached if manual in cache: # Use the cached manual return cache[manual] else: # Retrieve the oven manual from a trusted source oven_manual = fetch_oven_manual(manual) # Store the manual in the cache for future reference cache[manual] = oven_manual return cache[manual] ``` You're checking if the oven manual is already in the cache. If it is, you can directly use the cached manual, ensuring quick access. If it's not in the cache, the code retrieves it from a trusted source, store it in the cache, and then use it. This approach eliminates the need to repeatedly fetch the manual, much like having your oven's instructions ready whenever you need them for perfect pizza baking. Caches are used for frequent queries to a database where the content does not change frequently. Just like a manual of generations-old recipes. ### **Queueing: Streamlining Task Processing** In web app development, not every backend task can occur instantaneously. Some tasks are simply to big to just do them on the spot. Tasks like sending emails or processing large datasets necessitate management in terms of when and in what order they should be executed. This is where queues come into play. They operate as standalone applications, similar to managing orders one after another in a pizza shop, where each order's preparation follows a structured sequence. Here's a queue of pizza orders in code. Pizzas will be processed one after another: ```python import time pizza_orders = ["Margherita", "Custom Toppings", "Pepperoni", "Vegetarian"] for order in orders: print(f"Initiating order processing: {order}") time.sleep(2) # Simulating processing time print(f"Order {order} processed and ready") ``` Let's break down the code snippet step by step: - `import time`: This line imports a module to handle time-related functions. - `pizza_orders = ["Margherita", "Custom Toppings", "Pepperoni", "Vegetarian"]`: Here, we create a list of pizza orders. - `for order in pizza_orders:`: This loop processes each pizza order one by one. - `print(f"Processing order: {order}")`: This line displays which order is being processed. - `time.sleep(2)`: Simulating a processing time of 2 seconds for each order. - `print(f"Order {order} processed and ready")`: Indicates when each order is done. Queues act like holding spots. For instance, think about a pizza that didn't bake properly or an email that didn't get delivered. Queues handle these mess-ups by giving them another shot. If these hiccups were just part of the usual process, they could mess things up, causing delays and even crashes. But with queues, these issues get managed separately, so your app keeps running smoothly. However, handling queues can be a bit of a puzzle because it means dealing with an extra system just for managing these tasks effectively. ### Challenges with the backend in daily work life - Queues are another system and you need to set up and maintain extra systems to keep them running. - You need extra monitoring to make sure you find errors and get notified quickly when they happen. - Every extra system adds complexity and the risk for error. ## **APIs** - How technical parts of the app talk with each other or The Messengers That Connect Applications > Person_A: "How do I send our orders from the frontend to our backend?" > Person_B: "You need to send them via our API!" In our pizza shop, the waiter acts as the messenger between the customer and the kitchen staff. The waiter takes the order from the customer, delivers it to the chef, then brings back the prepared pizza to the hungry patron. Just like the waiter, APIs act as messengers that deliver communication between different software systems. Here's the flow of a waiter and the corresponding API language and flow: ```mermaid flowchart TD; subgraph API a[Receives API request] --> b[Processes request] --> c[Sends back response]; end subgraph Waiter q[Takes order] --> w[Delivers to chef] --> e[Returns food]; end ``` ### Why are APIs Important? API stands for *Application Programming Interface*. An API provides a structured way for different applications to interact with each other programmatically. In the pizza shop, the menu lists all the order options available (pepperoni pizza, veggie pizza, salad, etc). This is like an *API endpoint* - it defines the available services you can request. When the customer places an order, they are sending a request just like an API call. The waiter then delivers that request to the kitchen, which prepares and returns the response, like the API sending back a data response. APIs allow different applications to connect by sending requests and data to each other. For our web app, frontend, backend, and the database are connected via APIs, it's the only way they can work together. ### **How the frontend gets order details via API** Let's start with how the Javascript frontend gets the details of a specific order: ```javascript <script> fetch('https://api.yummypizzaapp.com/orders/456', { method: 'GET', headers: { 'Authorization': 'Bearer abc123' } }) .then(response => response.json()) .then(orderData => console.log(orderData)); </script> ``` - `https://api.yummypizzaapp.com` - the API is often an URL that can be called just like you would visit a website - The `/orders` is the endpoint for getting all orders - The `456` is the ID of a specific order - `method: 'GET'` describes that an information is read (as opposed to being sent) - The header is extra info that the API needs, in our case it's the authorization secret (where `Bearer` is a frequent keyword), you don't want that anyone can just enter the URL and get all orders' details… If the order exists and our authorization secret was right, you will now get the details for the order in `JSON` format: ```json { "pizzaName": "Pepperoni", "toppings": { "cheese": true, "tomatoSauce": true, "pepperoni": true }, "price": 12.99 } ``` (TODO: Format as info box) #### **JSON - The Pizza Box with Braces {}** JSON (JavaScript Object Notation) is like a pizza box with curly braces `{}`. Inside these braces, you put pairs of names and values, even nested. Think of the names as pizza attributes and the values as their descriptions. JSON gets used a lot in Javascript, the frontend language. ### The elements of an API Let's look in more detail on the key elements of an API: ### Endpoints A restaurant menu lists the available food endpoints - pizza, salad, etc. Similarly, an API exposes endpoints just as for Pizza app: ```http /orders /users /pizzas ``` These endpoints represent the different resources available in the API. They are usually avaible as an URL, so the backend might be exposing its APIs like this: `yummypizzaapp.com/api/`, so if you access `yummypizzaapp.com/api/users`, you trigger the API for users and get a list of all users in return. Every endpoint can have own rules what and how to display. You already saw `/orders/456` to get a specific order. There could also be a filter query, such as `/orders?status=Delivered` to only show all orders that were actually delivered. Here're two more examples for our endpoints: - `/users?search=Ronald` (to find out whether 🤡 got tired of Hamburgers) - `/pizzas?ingredient=Mushroom` (to list all pizzas that have mushrooms) ### HTTP Methods So far, you only read information from the API via the `GET` method. But you can also add, change, and delete information via API. Here's an overview of the HTTP methods and the equivalent of what a waiter does: | Method | API | Waiter | | ------ | --------------------- | ------------------ | | GET | Retrieve a resource | Check order status | | POST | Create a new resource | Take order | | PUT | Update resource | Modify order | | DELETE | Delete a resource | Cancel order | Just like waiters have different actions based on the order, APIs support basic methods for interacting with resources. To give you a better feeling of how API's work, here's an example of creating a new order via API and the POST method: ```javascript // Example using POST method to create a new order fetch('https://yummypizzaapp.com/api/orders', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer abc123' }, body: JSON.stringify({ "pizzaName": "Vegetarian", "toppings": { "cheese": true, "tomatoSauce": true, "vegetables": true }, "price": 11.99 }) }) .then(response => response.json()); ``` ### Response Status Codes (TODO: Image with monitor in restaurant with 404, pizza not found) In the examples so far, there was always a succesful answer–the order existed, the new order could be created. Whenever you call an API, you get a response with a number and a message. The success response is `200 OK`. Here are the most important responses and their waiter equivalents: | API | Waiter | |-------------------------------|--------------------------| | 200 OK - Success! | Order received | | 404 - Not found | Menu item not available | | 503 - Service unavailable | Kitchen closed | The waiter can indicate status back to the customer, just like APIs return status codes to tell you the result of your request. ### Headers Headers are like notes the waiter brings with an order, such as: - Allergy info - Instructions to rush the order - Table number For an API, the headers can hold extra information, most importantly authorization. You saw two headers before already, for authorization, and for the format of the request: ```javascript fetch('https://yummypizzaapp.com/api/orders', { method: 'POST', headers: { 'Content-Type': 'application/json', // 'Authorization': 'Bearer abc123' }, ``` 1. `'Content-Type': 'application/json'`: This header specifies the type of content that is being sent in the request body. In this case, it's set to `application/json`, indicating that the data sent in the body of the request will be in JSON format. It helps the server understand how to interpret the data being sent. 2. `'Authorization': 'Bearer abc123'`: This header is typically used for authorization purposes. It includes an access token ('Bearer abc123' in this case) that grants permission to the client making the request. The term "Bearer" specifies the type of access token being sent. ### Challenges with APIs in daily engineer work Working with APIs can present several challenges that might slow down development or create hurdles in an engineer's daily work: 1. **Poor Documentation**: Incomplete or unclear API guides hinder integration, forcing trial-and-error methods, hampering productivity. 2. **Unstable Behavior**: External APIs may exhibit erratic responses, downtime, or unannounced changes, disrupting workflow. 3. **Authentication Complexity**: Managing security measures like API keys, tokens, or OAuth adds development complexity. 4. **Rate Limiting**: Engineers must intelligently handle API usage limits to avoid disruptions. 5. **Error Handling**: Dealing with unexpected API behaviors requires robust error management for application stability. 6. **Versioning Challenges**: Transitioning between API versions while maintaining system integrity poses difficulties. 7. **Testing Complexity**: Testing, debugging, and simulating API scenarios demand meticulous effort and time. Addressing these challenges often requires time to explore the API, try out how it works, and continuous monitoring to ensure smooth integration and operation of APIs. ## **Databases and SQL** - Where and how the data of users are saved, retrieved, and understood > Person_A: "Can you tell me how many margherita pizzas we sold yesterday? > Person_B: "I can write a SQL query that answers this question." To save the data on our available pizzas and their orders, you need an extra software. This is called a database. A database is like a big logbook that stores information. A database helps you save and retrieve information in a structured way and put it in relation. The database organizes the data into tables with columns and rows on each page, like a spreadsheet application. An ID is an unique identifier for every entry, often a running number. The content of our pizzas table looks like this, one entry is called a `row`: ```csv // Table name: pizzas // Columns: id, name, price id,name,price 1,Margherita,10.99 2,Veggie Supreme,12.99 3,Spinach and Feta,11.99 4,Mushroom Delight,11.49 5,Pepper and Onion,10.49 ``` For the `orders` , you do not enter the names of pizzas from fresh, but reference the ID of the pizza in the `pizzas` tables. This way, you can also get the price of every pizza for every order. Here are the orders for January 1st: Two people ordered pizza, Person_A ordered a Margherita (ID:1), Person_B ordered one Margherita (ID:1) and one Veggie Supreme (ID:2). This creates three entries in the table: ```csv // Table name: orders // Columns: id, order_date, email, pizza_id id,date,email,pizza_id 1,2100-01-01,Person_A,1 2,2100-01-01,Person_B,1 2,2100-01-01,Person_B,2 ``` SQLite is a great database to test all from this chapter, it's a database that is just a file. One speciality about databases is that it is very opinionated on how you save things. Every column defines exactly what can be saved in it, for example a number with two digits (e.g. 1.25, it's called float), or a date. These rules are called data types. Why is this important? Because only when the data is saved right and this is guaranteed, you can later analyze, summarize this data. So, for example for the date you can say "Show me all lines that happened 4 weeks or more ago" and for this, you need to be sure that actually there is only dates in the column. If you try to enter something else, like text in a number column, the database will refuse the entry. ```sql -- Database schema "pizzas" create table pizzas ( id integer primary key, name text, price float ); -- Database schema "orders" create table orders ( id integer primary key, order_date date, email text, pizza_id integer ); ``` **Query a database with SQL** To talk to the database, you need a special programming language called SQL (Structured Query Language). SQL is a way to talk to a database. It's like a special language that lets you ask questions and get information back. And here is the query to answer our initial question: ```sql -- Today is Jan 2 2100 -- How many margherita pizzas did you sell yesterday? SELECT count(*) FROM orders WHERE pizzas.name = 'Margherita' AND order_date = '2100-01-01' JOIN pizzas WHERE pizzas.id = orders.pizza_id -- Result 2 ``` Let's add a second example to show two more important features: grouping and ordering. Let's also use a have a more realistic question to show the rest of the important SQL query elements: > How many orders did you have on January 1st, 2100 for every pizza? ```sql SELECT pizzas.name, count(*) FROM orders WHERE order_date = '2021-01-01' JOIN pizzas WHERE pizzas.id = orders.pizza_id GROUP BY 1 ORDER BY 2 DESC ``` The result is: ```csv Margherita,2 Veggie Supreme,1 ``` `Group` aggregates on a column - and needs a function like `sum` or `count`, `order by` sorts by a column. You use nummerical references for the columns that are defined in select. ## Modifying Data with SQL In addition to querying data, SQL provides statements for modifying data in the database: **INSERT** - add new rows ```sql INSERT INTO pizzas (name, price) VALUES ('Guacamole', '15.99'); ``` **UPDATE** - edit rows, update from "Mushroom Delight" to "Marshmellow Party". ```sql UPDATE pizzas SET name = 'Mushroom Delight' WHERE name = 'Marshmellow Party'; ``` **DELETE** - remove rows ```sql DELETE FROM pizza WHERE id = 5; -- deletes "Pepper and Onion" ``` ### What could possibly go wrong? When working with databases, what can slow down development and delivery can be a couple of things: - The **data is duplicate and insonsistent**, e.g. there are different tables for orders with wrongly filled or hard to understand content that the teams need to clean up. - Running into **performance issues**: Poor database design and SQL queries can lead to extra efforts as data volumes grow. - When business or developer requirements change, time expensive **database schema changes** might be needed. - Teams can have **challenges understanding the database and data**: Current developers might not have created the database and data. They might not understand . If you don't understand the structure, you will not understand the data easily. Database is managed by other team and changes not possible or slow - **Challenging ownership and dependencies** on others: The teams that need a database does not own or maintain it: Lack of clarity on ownership and governance of the database between teams. Team lacking necessary database administration and SQL skills. ## **Version Control** - A full history of what, when and who added or changed any line of code > Person_A: "I need to collaborate with you on this code. Do you know a system to avoid chaos like files with the name `final_really_final_file` and prevent mistakes?" > Person_B: "Sure, you need a version control system like Git!" **Why Do You Need Version Control?** (TODO: Image of two slips of paper with handwritten Pizza margherita recipes with different ingredients, next to each other) ![[git-two-recipes.jpeg|300]] Imagine two cooks working on a new recipe for the perfect margherita, both trying to add their secret ingredients at the same time to the recipe book of the restaurant. Should they take one recipe and discard the other? Or should they merge both recipes? The same conflict happens for code. And the tools to solve it are called version control systems. Version control lets you and your fellow cooks collaborate smoothly. You can work on different parts of the recipe without stepping on each other's toes. And when you want to decide on the final recipe, the tool shows you conflicts and how to resolve them. Version control is also like a time machine for code. It helps keep track of changes and lets people work on the same code without getting in each other's way. It's like having a chef's notebook with every recipe tweak ever made. Developers can work together on software projects, track changes, and even roll back changes if they make a mistake. ### How Git works - Two margherita recipes Here's a simple example to demonstrate the benefits of version control using Git with a pizza recipe edited by two cooks together. **The Initial Pizza Recipe** The main cook Person_Cook_A created the first recipe content for the Pizza margherita in a simple text editor and saved it as file with the name `margherita.txt`: ```plaintext margherita Pizza Recipe: - Dough - Tomato sauce - Mozzarella cheese - Fresh basil leaves ``` To save all changes on this file, Person_Cook_A creates a Git repo: ```bash git init ``` A git repo is like a folder in which all infos on the tracked files are being saved. After creating the repo, Person_Cook_A adds the file to the Git index, so it knows that it needs to track it. You only need to add a file once. After that, Then they add the content of this initial recipe version. Submitting content to the index is called "commit": ```bash git add margherita.txt git commit -m "Initial pizza recipe" ``` You can also add a message about what you changed in the file with the `-m` argument, which stands for `message`. Commits are like jotting down every tiny change you make to your recipe. Each one gets a unique ID, making it easy to find and understand it later. Let's see how Git can help you to keep track of your changes. Person_Cook_A adds the amount of tomato sauce needed and saves the file: ``` margherita Pizza Recipe: - Dough - 90ml Tomato sauce - Mozzarella cheese - Fresh basil leaves ``` Now, Git can tell us how this file changed when you use the command `git diff`: ```diff diff --git a/margherita.txt b/margherita.txt index 5b2f2cb..45bcb1a 100644 --- a/margherita.txt +++ b/margherita.txt @@ -1,6 +1,6 @@ margherita Pizza Recipe: - Dough -- Tomato sauce +- 90ml Tomato sauce - Mozzarella cheese - Fresh basil leaves ``` Lines starting with `-` are removed compared to the previous version, and lines starting with `+` added. You can easily see that an amount was added here. Person_Cook_A saves these changes to Git: ```bash git add margherita.txt git commit "Add: Amount of sauce" ``` One recommendation is to commit every small change, so not to rewrite the full recipe and commit then, but do as in our example and give it descriptive change messages. If you want to see all changes that you made, you can use `git log`. For the example, you will see 2 versions and an output like this: ```bash * 8defa46 (HEAD -> master) Add: Amount of sauce * b5312a1 Initial pizza recipe ``` To see the changes that were made in the initial recipe, you type `git show b5312a1`. This number is like the `_final_v100` that you might have had in the past when you saved different versions. In your book, when explaining branching and merging in Git with the pizza recipe analogy, you can use this simple approach: **Branching and Merging with Pizza Recipes** Imagine your pizza recipe is like a master recipe, and you want to experiment with different variations without throwing the original recipe away too fast. This is where Git branching comes in. 1. **Creating a New Branch** - Just like creating a new pizza recipe, you create a new branch for your changes. - Use `git branch experiment-001` to create a branch. - Now, you can work on this new recipe without affecting the original one. 2. **Making Changes** In your `experiment-001` branch, modify the master recipe as you like. For instance, you decide to add olives to your margherita pizza. You commit changes as you learned before. 3. **Merging Changes** - Now, if you want to combine the changes from your `experiment-001` branch back into the master recipe. - Use `git merge new-recipe` to do this. - Git will automatically merge the changes, and you'll have a pizza recipe with olives. Remember, branching allows you to work on different versions of your recipe simultaneously, just like experimenting with different pizza toppings. Merging brings those changes back into the main recipe, so you have a delicious, updated master recipe. If the experiment fails, you can savely throw it away and just return to your master recipe. **Collaborative Editing** Now, in a big restaurant, not only one cook works on recipes. Our two cooks, Person_Cook_A and Person_Cook_B are actually pretty opinionated about Pizza margherita, and they edit the recipe at the same time. Both terminals: ```bash git clone <repository_url> local_pizza_recipe cd local_pizza_recipe ``` **Step 4: B's Edits** 6. B makes their edits to `margherita.txt` by changing the cheese: ```plaintext margherita Pizza Recipe: - Dough - Tomato sauce - Fresh mozzarella cheese (sliced) - Fresh basil leaves - Olive oil ``` 7. C commits her changes: ```bash git add margherita.txt git commit -m "Reformat: updated cheese to sliced mozzarella" ``` **Step 5: C's Edits** 8. C also makes his edits to `margherita.txt` by changing the cheese: ```plaintext margherita Pizza Recipe: - Dough - Tomato sauce - Mozzarella cheese (shredded) - Fresh basil leaves - Cherry tomatoes (optional) ``` 9. C commits his changes: ```bash git add margherita.txt git commit -m "Reformat: updated cheese to shredded mozzarella" ``` **Step 6: Conflicting Changes** 10. When C tries to push his changes, he encounters a conflict: ```bash git push ``` Git will inform C that there's a conflict between his changes and B's changes because they both edited the same lines related to cheese. 11. C resolves the conflict in `margherita.txt` by choosing which cheese change to keep and removing conflict markers. Then, they add and commit the resolved file: ```diff margherita Pizza Recipe: - Dough - Tomato sauce <<<<<<< HEAD - Fresh mozzarella cheese (sliced) ======= - Mozzarella cheese (shredded) >>>>>>> Alice's changes: updated cheese to sliced mozzarella - Fresh basil leaves - Cherry tomatoes (optional) ``` B needs to make some edit now because the recipe either can use C's or C's change. There can only be one type of cheese! In a Git conflict file, lines between `<<<<<<< HEAD` and `=======` represent the current state of the file from the branch you're merging into. Lines between `=======` and `>>>>>>>` represent the incoming changes from another branch. In your example, there's a conflict in the line for cheese because both C and C made different changes to it. You need to manually choose which change to keep or combine them as needed. Once resolved, you remove the conflict markers and save the file. In this specific case, you'd decide whether to use C's "Fresh mozzarella cheese (sliced)" or C's "Mozzarella cheese (shredded)" and update the line accordingly. The conflict markers help Git identify the conflicting sections, allowing you to make a conscious choice during the merge process. C's terminal: ```bash git add margherita.txt git commit -m "Resolved conflict by keeping C's cheese change" git push ``` **Step 7: Synchronization** 12. C can now pull C's changes to her local repository: C's terminal: ```bash git pull ``` Now, both C and C have the same version of the recipe with the conflict resolved in favor of C's cheese change. **Pull Requests** Pull requests are your way of inviting other cooks to taste your dish before it's added to the official menu. They ensure quality control in your kitchen. This scenario demonstrates how conflicts can occur when multiple users edit the same lines of a file in a Git repository and how to resolve those conflicts through manual intervention. In a real big pizza app, there are a lot more lines of code and a lot of collaborators. Working on this code is complicated, even with git, so expect that developers will need time to manage their version control systems. ## **Deployment** - How the code gets live so users can use it > Person_A: "Why is the new feature for the pizza web app not live yet?" > Person_B: "The CI pipeline is failing on one of the tests." You've written some great new code for your pizza ordering web app. But how does it actually get live on the internet so customers can use it? That's where deployment comes in. Deployment is the process of taking the code you've written and getting it onto servers where users can access it. It involves carefully copying new code onto live servers without breaking things. At our pizza place, when a new pizza recipe is created, it needs to be passed along to the cooks who will actually be making the pizzas in the kitchen. The new recipe can't just be scribbled on a napkin - it needs to be formally added to the kitchen's master recipe book. And the cooks need to be trained on how to make the new pizza properly. Deployment works similarly - new code is formally added to the live servers and systems are updated to run it. ### Testing First with CI/CD Before deploying new code, it's important to test it thoroughly. You don't want to break your live web app by deploying buggy code! This is where **C**ontinuous **I**ntegration and **C**ontinuous **D**eployment (CI/CD) comes in. CI/CD is an automated process that lets developers continuously build, test, and deploy code changes. At our pizza place, when a new recipe is added to the master recipe book, the cooks first try making a test pizza to ensure the instructions make sense. CI/CD does the same thing, but automatically, by building the code and running tests to catch any errors. The CI/CD pipeline looks like this: 1. Developer commits code changes to version control 2. CI/CD server detects changes and pulls new code 3. New code is built and unit/integration tests run 4. If tests pass, code is deployed to staging environment 5. More acceptance and load tests run against staging 6. If staging tests pass, code is deployed to production! By testing first, CI/CD catches issues before they impact real users. ### Deploying to Different Environments Typically, code is deployed to multiple environments: - **Local environment:** Developers run the code on their own computers first - **Staging environment:** Code is deployed to servers for internal testing - **Production environment:** Live servers where real users access the app At our pizza place, new recipes might be tested at home first. Then they are tested in a single pizza kitchen before rolling out to all locations. Similarly, developers deploy and test internally first before going live to users. Staging environments mimic production and catch issues before public deployment. ### Managing Rollouts Carefully The actual rollout of new code onto production servers needs to be done carefully: - **Rolling out slowly:** Deploy to a few servers first, watch for issues, then deploy to more. - **Feature flags:** Release code but keep new features hidden behind flags. - **Rollbacks:** Rollback code if something goes wrong. At our pizza place, new pizzas are added to just a few kitchens before expanding to all. Features like spicy sauce can be held back with "flags" until ready. If customers hate a new recipe, it can be "rolled back" off the menus. Careful rollouts reduce risk and allow catching issues early. Release management is key for smooth deployments! ### Key Takeaways - Use CI/CD to build, test and deploy code changes automatically - Deploy to local, staging, and production environments - Manage rollouts carefully with feature flags, incremental rollouts, and rollbacks By mastering deployment, you can ship new code faster and with confidence! ### Web servers - A computer that shares info with other computers over the internet A web server is like a waiter at a pizzeria, but for computers. Its job is to share information with other computers over the internet. Just like a waiter takes orders and serves pizzas, a web server takes requests from the internet and sends back the right information. **What Web Servers Do:** 1. **Storing and Sharing**: Think of a web server as a big storage place for web stuff. It stores and shares web apps, files, databases, and even handles emails. But here's the catch – web servers don't have fancy screens or buttons; they understand only text commands. 2. **Waiting for Visitors**: A server is always ready for visitors, just like a waiter standing by the pizzeria's door. For a pizzeria, you have the address with a street and a ZIP code. For a server, it's an IP address and a domain name, like yummypizzaapp.com. **Server Configuration - The Pizzeria Recipe:** Imagine a recipe for setting up a pizzeria. For a server, it's a bit of code like this: ```nginx server { # The domain name for the server server_name yummypizzaapp.com; # On which "phone line," called port, to listen to for incoming HTTP requests listen 80; # In which folder on the server are the files located root /var/www/yummypizzaapp; # Which file to display when visiting the root of yummypizzaapp.com index index.html; } ``` This code tells the server how to behave. It's like a recipe telling the pizzeria how to make a pizza. **Breaking it Down:** - `index index.html`: This says, "When someone comes to the website, show them the `index.html` file." It's like saying, "Give them the menu when they enter the pizzeria." **Extra Jobs of Web Servers:** Web servers also do a few more things: - **Load Balancing**: Imagine if there are many waiters at the pizzeria to serve lots of customers. Web servers can do something similar by distributing visitors to different servers to make the website faster. - **Scalability and Load Balancing**: They make sure the pizzeria (or website) can handle lots of customers without slowing down. - **Concurrency**: Web servers are great at doing many things at once, just like handling multiple orders in a busy pizzeria. So, the next time you visit a website, remember, there's a web server working behind the scenes, like a helpful waiter making sure you get your web pages quickly and correctly. ## **IP-Address and Domain** - The postcode and address of the computer that runs your applications > Person_A: "We're having trouble connecting to the server. What could be the reason?" > Person_B: "Can you please first check whether you still have the right IP address for it?" Imagine the internet as a bustling city, and every computer in it has a unique address, just like every pizzeria has its own location. These addresses come in two types, like two flavors of pizza: IPv4 and IPv6. They're like phone numbers for computers. **Flavors of IP Addresses:** - **Public vs. Private**: Some addresses are like well-known pizzerias on main streets; anyone can find them. Others are private, like hidden gems known to a select few. - **Static vs. Dynamic**: A static IP is like a pizzeria always at the same spot. Dynamic IPs change, like a food truck moving to a new location each day. **Ports and Protocols - The Pizza Shop's Languages:** When computers order online, they use different languages called protocols, just like how pizza shops have different menus. Think of ports as special windows for taking orders, like a pizza place having a window for each type of pizza. **Meet the Domain - Your Internet Friend's Name:** Now, imagine if instead of using pizzeria addresses, you had to remember their phone numbers. That's where domains come in. A domain is like a friendly name that links to a pizzeria's address. For example, "yummypizzaapp.com" links to an IP address. **How Domains Work:** When you type "yummypizzaapp.com" in your browser, it's like asking the magical address book (DNS) to find the pizzeria's address (IP address). It's like looking up a phone number in a book. Once you have the IP address, your computer can connect with the right pizzeria on the internet. **Bringing It All Together:** So, in our server recipe, you have the domain name, like "yummypizzaapp.com." The IP address is like the secret recipe; it's given automatically. To make them work together, you just need to add an entry in the internet's address book, the DNS settings. You can usually do this where you bought the domain, like saving a friend's number in your phone. Now, you know that the internet is like a city filled with pizzerias, and domains are like the names of these pizzerias. They make the internet a tastier and friendlier place to explore. And how to find out the address given a IP? There's a CLI tool for this: `host`. And this is how it works: ```bash host yummypizzaapp.com yummypizzaapp.com has address 216.58.209.14 yummypizzaapp.com has IPv6 address 2a00:1450:401b:808::200e yummypizzaapp.com mail is handled by 10 smtp.google.com. ``` ## **HTTP** - HTTP(s) is a way for computers to talk to each other on the internet (TODO: Merge with API or make distinct) In this chapter, we'll unravel the mysteries of HTTP, the secret code that makes the internet work. Think of it as the language computers use to chat on the web. HTTP, which stands for HyperText Transfer Protocol, is like the pizza order in your favorite pizza shop. When you order your pizza, you use specific words and phrases to tell the pizza chef exactly what you want. HTTP does the same for computers on the internet. Imagine you're ordering a pizza online at `yummypizzaapp.com`. That's like the address of the pizza shop. When you hit "Order," your computer sends an HTTP request to the pizza shop's computer. It says, "Hey, I want a large pepperoni pizza with extra cheese, please!" **Making Requests and Getting Responses** In the pizza world, it's like you're asking for something, and the pizza shop responds. The request is like, "Give me pizza," and the response is, "Here's your pizza." HTTP has different ways to ask and different ways to respond. These are called HTTP methods. There's `GET` (asking for something), `POST` (ordering something new), PUT (changing something), and DELETE (removing something). **Headers - The Pizza Details** Imagine if you ordered a pizza without saying whether you want it hot or cold. That would be a mess! In HTTP, headers are like those extra details. They tell the computers more about what's going on. Like, "I want my pizza hot, and I can eat cheese." **Status Codes - The Pizza Review** After you order, the pizza shop tells you if your request was a success or not. HTTP does that too with status codes. For example, 200 means "Success, enjoy your pizza!" But 404 means "Sorry, I couldn't find that pizza." **Security - Keeping the Pizza Safe** In the pizza world, you don't want someone messing with your order. In HTTP, you worry about that too. You want to keep your internet communication secure, so no one messes with your pizza orders (or your data!). **Authentication - Proving You're You** Sometimes, the pizza shop needs to make sure it's really you ordering. In HTTP, this is called authentication. It's like showing your ID to pick up your pizza. That's the slice of HTTP we're serving up in this chapter. It's the key to understanding how computers on the web talk to each other. So next time someone says "HTTP," you'll know it's just the language of pizza-loving computers! 🍕 ### Example Sure, here's a simple cURL demo to illustrate the concept of making an HTTP request: Suppose you want to order a pizza from a fictional pizza shop called "Pizza." Pizza has a web app for pizza orders, and you want to use cURL to place an order for a large pepperoni pizza with extra cheese. You can use a CLI tool called `curl` for this: ```bash # Using cURL to make an HTTP POST request to order a pizza curl -X POST https://yummypizzaapp.com/orders \ -H "Content-Type: application/json" \ -d '{"pizza_type": "pepperoni", "size": "large", "extra_cheese": true}' ``` Here's the detailed explanation: - `curl` is the command to make HTTP requests. - `-X POST` specifies that you want to make a POST request, which is like placing a new order. - `https://yummypizzaapp.com/orders` is the URL of Pizza's web app, where you place the order. - `-H "Content-Type: application/json"` sets the request header to indicate that you're sending `JSON` data. - `-d '{"pizza_type": "pepperoni", "size": "large", "extra_cheese": true}'` sends the order details in `JSON` format, specifying that you want a large pepperoni pizza with extra cheese. When you run this cURL command, it's like sending an HTTP request to Pizza's web app, asking them to prepare your pizza order. And here's the response given by the server: ```json HTTP/1.1 200 OK Content-Type: application/json { "order_id": "123456", "status": "confirmed", "estimated_delivery_time": "30 minutes", "total_price": "$15.99", "message": "Your order for a large pepperoni pizza with extra cheese has been confirmed. Enjoy your meal!" } ``` In this response: - `HTTP/1.1 200 OK` is the HTTP response status line, indicating that the request was successful (status code 200 OK). - `Content-Type: application/json` is a response header indicating that the content is in JSON format. The response body contains the JSON data, which includes details about your pizza order. This structure represents a typical HTTP response, with the status code, headers, and response data. Now you learnt how to talk to a pizza server with HTTP language! ## **Cloud** - The cloud is like a big computer that you can rent and use over the internet. > Person_A: "I want to move the app to the cloud so that it can scale it more easily." > Person_B: "Oh, let's discuss the pros and cons first! Our server is quite fine." In this chapter, we're going to talk about something called the "cloud." Imagine the cloud as a massive computer that you can borrow and use through the internet. It's like renting a super-powerful computer that you don't have to keep in your own house. Let's explore this idea. ### What's the Cloud? Think of it this way: You know how when you order a pizza, you can choose to dine in or take it home? Well, the cloud is a bit like that. Instead of having your own computer to run your programs and websites, you can use the cloud's computer. It's especially handy because you don't have to worry about buying and maintaining expensive computer equipment. When saying "the cloud," it is not just about one computer but lots of them, all working together. It's like having multiple counters in a pizzeria to serve your hungry customers. If your pizza place becomes super popular, one counter might not be enough. People would be lined up out the door and even onto the streets! That's when the cloud comes to the rescue. Here are the good things about it: **Advantages of the Cloud:** 1. **Scalability:** The cloud lets you quickly adjust to how many customers you have. If your pizza place gets crazy busy, the cloud can handle it. 2. **Cost Savings:** Instead of buying your own expensive cooking equipment, you pay only for what you use with the cloud. It's like paying for pizza ingredients only when you make a pizza. 3. **Accessibility:** You can reach your data and programs from anywhere, anytime, using any device with an internet connection. It's like being able to check your pizza orders from your phone, no matter where you are. But like everything, the cloud also has its downsides: **Disadvantages of the Cloud:** 1. **Lots of Options:** There are many different cloud providers and solutions, and they all work a bit differently. So, you'll need to learn how to use each one. 2. **Complexity:** All the services you use in the cloud need to talk to each other using something called APIs. Sometimes, this can get pretty complicated, and things might break. If your web app is small, it might be simpler to run it on just one server, like having one counter at your pizza place. **How did the cloud evolved? From Your Computer to the Cloud** Let's walk through the journey to get to cloud computing. 1. **Your Computer at Home:** Think of this as your very own kitchen. You have your ingredients, your recipes, and your trusty oven. It's where you have full control and can cook your favorite dishes whenever you want. 2. **A Big Computer in a Special Room:** Now, picture a colossal kitchen, far larger and more powerful than yours. This kitchen is like a professional restaurant kitchen, bustling with chefs and multiple ovens. It's located in a special room, and it's where all the complex culinary creations happen. In the tech world, this represents the central servers and infrastructure that power websites and apps. 3. **A Cooking Station You Rent in That Big Kitchen**: Sometimes, you don't need to use the entire massive kitchen because it's expensive, and you don't require it 24/7. So, you decide to rent a specific cooking station within that professional kitchen for the times when you want to make your special dishes. This is similar to renting a designated workspace in the restaurant kitchen. You only pay when you use it, just like paying rent for a workspace. 4. **A Private Corner at Your Rented Cooking Station (Virtual Private Server)**: Now, imagine that the cooking station you've rented in the restaurant's kitchen is entirely yours. It's like having your private corner within that bustling kitchen. You can keep your unique recipes, ingredients, and tools there, and no one else can touch them. In the tech world, this is akin to having your own virtual private server (VPS). It's a dedicated portion of a larger computer, exclusively for your use. 5. **The Cloud! It's Like a Supercomputer for Everyone to Share:** At the highest level of abstraction, there is the cloud. Think of the cloud as an enormous, state-of-the-art kitchen facility that many people and businesses can access. It's as if the entire restaurant's kitchen has become a massive, shared cooking space. Each user, like you with your VPS, gets their private corner within this expansive kitchen. This shared kitchen is equipped with all the ingredients, ovens, and tools you need to cook up virtually anything you desire. So, to sum it up, the journey of cloud computing always starts with your personal computer at home. It then progresses to a larger, centralized computer setup, which you can rent space within. This rented space becomes your private enclave, similar to a virtual private server. Finally, you reach the cloud, the highest level of abstraction, where an immense, shared computing facility is available for everyone to use, just like a vast, communal kitchen for digital creations. So, there you have it! The cloud is like renting a super-duper computer to help you run your web apps. It's a bit like having extra ovens in your pizzeria when you need to bake more pizzas. In the next chapter, we'll dive into more tech stuff to help you understand how all this works even better. ## **CDN** - To make sure the application can be used always and fast by everyone by serving it from many places > Person_A: "We're getting a huge amount of traffic to the web app after we got covered in the magazine. How can we make sure our server is not crashing?" > Person_B: "Oh, let's put a CDN in front of the server so at least everyone sees our menu!" Imagine your pizza place is booming, customers are flocking in, and you want to serve up those mouthwatering pizzas as fast as lightning. That's where a Content Delivery Network (CDN) comes to the rescue. **Why CDN?** 1. **Better Speed:** A CDN makes your web app as fast as a pizza delivered right out of the oven. 2. **Rock-Solid Reliability:** Just like a trusty pizza oven that never fails, a CDN keeps your web app running smoothly, even during a rush. 3. **Top-Notch Security:** Think of it as having a vigilant bouncer at your restaurant's door, ensuring only genuine customers get in. 4. **Super Scalability:** When your pizza joint becomes the talk of the town, a CDN ensures you can handle the crowd without running out of dough (pun intended). **What Goes on a CDN?** Picture a CDN as your go-to delivery vehicle for web content. It's perfect for: - **Media Delivery:** Sending out boxes of tempting images, videos, and audio files to your eager customers. - **Dynamic Web Content:** Stuff like JavaScript, CSS, and HTML that adds flavor to your web app. - **Static Web Content:** Basic stuff like HTML, CSS, and images that make up your menu. But remember, you can't stuff your entire kitchen (the backend) into the CDN. That's best kept in the cloud, where it's managed more efficiently. **How Does It Work?** A CDN is like having pizza ovens scattered across the city. Here's how it operates: 1. **Global Sharing:** Your content spreads out to servers worldwide, just like opening new branches of your restaurant. 2. **Serve from the Closest Spot:** When a hungry customer visits your web app, the CDN serves them from the nearest server. It's like delivering a pizza from the closest restaurant. 3. **Content Pros:** CDNs are experts at fast content delivery, like pizza delivery pros who know the quickest routes. **Related Terms** - **Kissed to Death:** Imagine your pizza place getting overwhelmed with orders until you run out of dough. That's what happens when something is "kissed to death." - **Denial of Service:** This is when your restaurant is flooded with fake orders, making it impossible to serve real customers. CDNs protect against this, just like a vigilant bouncer keeping out troublemakers. In a nutshell, CDNs are the secret sauce for your web app's speed and reliability, ensuring everyone gets a taste of your digital menu without any hiccups. ## **Security and authentication** - Decide who is allowed to do what with your application ![[security.jpeg|250]] > Person_A: "We need to add authentication to the app. Do you know how it works?" > Person_B: "Sort of, but could you explain it to me in more detail?" Logging in is like showing your ID to get into an exclusive pizza club. It's how you prove you are who you say you are in the digital world. Web apps use **authentication** to confirm your identity before letting you access private areas. Just like a pizza club bouncer checks your ID matches their member list, web apps check the **username** and **password** you enter matches their records. If everything checks out, you're granted access. This keeps strangers out of members-only pizza parties, just like authentication stops random people logging into your online accounts. **Two Ways to Beef Up Security** 1. **Multi-Factor Authentication** Extra login steps, like getting a special code texted to your phone after entering your password. It's like the pizza club calling your cell to double check before letting you inside. Adds protection in case someone learns your password. 2. **Biometric Authentication** Using your fingerprint, face recognition, or other unique biological traits to login. It's like the pizza club using your photo to confirm you're you before entering. More secure than passwords which can be forgotten or stolen. **Managing Access with Roles and Rules** Good pizza clubs organize things so different members get different experiences. Web apps do the same by controlling what you can access based on your: - **Role** - Admins, editors, and viewers get different privileges, like allowing only admins in the kitchen. - **Attributes** - Age, location and other details determine your permissions, like letting teens order just cheese slices. This keeps things orderly, just like only allowing qualified chefs in the kitchen to toss pizza dough. **Staying Logged In Securely** **Sessions** track your activity so you stay logged in as you navigate web apps, like how pizza clubs know you're still there if you leave your table. But inactive sessions can **expire** after some time, logging you out automatically. Like polite staff asking you to leave after closing time. Managing sessions well improves security and the user experience. You shouldn't have to show your ID every time you visit the restroom! **Outsmarting Sneaky Threats** Like checking your pizza for unpleasant surprises, beware these **authentication threats**: - **Brute force attacks** - Repeatedly guessing passwords - **Phishing** - Tricking you to reveal your login details - **Hijacking sessions** - Taking over your active login - **Cracking passwords** - Uncovering weak passwords Stay secure by using strong passwords, being cautious of scams, and monitoring activity for anything suspicious. **Proving You're Not a Robot** Before entering pizza sites, you may have to prove you're human, not a pizza-grabbing bot. **CAPTCHAs** make you solve puzzles robots can't. Other anti-bot techniques also help block sneaky automated attacks trying to break into accounts. **Logging in Everywhere with Single Sign-On** **SSO** lets you access multiple apps with one login, like using a VIP pass for all pizza festivals in town. More convenient than managing separate passwords and great for security. **Getting a Digital Vouch with Identity Providers** **Identity providers** like Google and Facebook confirm you are who you say you are when logging into new apps. Just like having a famous pizza chef vouch for you at a new pizza place. Simplifies login without new accounts. **Securely Sharing Data with OAuth 2.0** **OAuth 2.0** enables apps to access your data on other platforms without you sharing passwords. Like giving the pizza delivery guy temporary access to leave your pizza at your door. Convenient and secure data sharing. **Staying Secure with Best Practices** Like ensuring quality ingredients and kitchen hygiene for great vegan pizza, follow security best practices: - Update software regularly - Educate users on safe authentication - Encrypt sensitive data - Monitor and analyze activity for threats **Other security topics** 1. **Encryption**: This is like a secret language between your computer and the website you’re visiting. Only your computer and the website know how to decode it. It’s like ordering a pizza in a secret language that only you and the pizzeria understand. 2. **Firewalls**: These are like the doors of a pizzeria. They allow legitimate customers (data packets) to enter and exit, but keep out anyone who doesn’t belong (malicious attacks). 3. **Secure Sockets Layer (SSL) / Transport Layer Security (TLS)**: These are protocols for establishing authenticated and encrypted links between networked computers. It’s like a verified safe route for your pizza delivery, ensuring your pizza (data) isn’t tampered with on its way to you. 4. **SQL Injection**: This is a code injection technique that attackers use to insert malicious SQL code into a query. It’s like someone changing your pizza order without you knowing, resulting in an unexpected outcome. 5. **Cross-Site Scripting (XSS)**: This is a type of attack where malicious scripts are injected into trusted websites. It’s like if someone tampered with the pizzeria’s menu to trick you into ordering something you didn’t want. 6. **Denial-of-Service (DoS) Attacks**: This is when an attacker overwhelms a system with traffic, causing it to be inaccessible to users. It’s like if someone placed a million orders at your favorite pizzeria all at once, causing it to be too busy to take your order. **Security and delivery speed** Developers need to follow these secruity measures with all the libraries and frameworks. This can eat a considerable amount of time, and delay projects, especially if security leaks are being discovered and you have to react on the spot. Why is security an issue in software development? Because it belongs to the *quality* aspect of it and will slow down your delivery. 1. **Security is a multi-layer challenge**: Security can be compared to the process of making a pizza. Just as making a good pizza involves multiple steps like kneading the dough, adding the right amount of sauce and toppings, and baking it at the right temperature, web security also involves multiple layers such as authentication, encryption, and firewalls. These layers need to be well planned and readjusted continuously. 2. **Developers have to think a lot about security**: This is similar to a pizzeria owner ensuring the safety of their establishment. Just as the owner has to consider various safety measures like fire extinguishers, food safety standards, and secure cash handling procedures, developers also have to consider various security aspects while designing and running an application. 3. **Security will slow down any delivery and management will not like this**: This can be likened to the time it takes to properly cook a pizza. While rushing the cooking process can lead to faster delivery times, it can compromise the quality (or security) of the pizza. Similarly, while implementing robust security measures might slow down the delivery process of a web application, it is crucial for ensuring the safety of the application. ## **Microservices and containers** - Tiny programs that work together to make a bigger program > Person_A: "We should consider breaking the app up into microservices to make it easier to maintain." > Person_B: "That's a good idea. Which parts of the app do you think we should break up first?" ![[container.jpg|500]] Containers help package code and dependencies into isolated, portable boxes so programs can run consistently in different environments. They're like reusable pizza boxes carrying perfectly portioned slices. ### What are Microservices? Many modern apps use a microservices architecture. This means breaking the app into smaller, independent services instead of one giant program. Each microservice focuses on a specific feature and runs in its own container. For example, a shopping app could have separate microservices for the cart, payment, recommendations, etc. Microservices enable: - **Agility**: Developers can update services independently without affecting others. - **Scalability**: Individual services can be scaled as needed, rather than the entire app. - **Resilience**: If one service fails, others keep working. However, microservices also increase complexity. There are more moving parts to coordinate and network calls between services. ### Potential Collaboration Challenges With microservices, technical misunderstandings can cause delays: - **Unclear responsibilities** - Confusion over which teams own which services. Clear ownership and APIs are crucial. - **Testing dependencies** - Services rely on each other, so changes may break integration tests. Careful coordination of releases is needed. - **Networking issues** - Misconfigured networks or firewalls can break communication between services. Collaboration between infrastructure and app teams is vital. - **Monitoring complexity** - More services make monitoring health/performance harder. Metrics and alerts should be agreed upon early. - **Lack of documentation** - Undocumented service APIs and purposes hamper understanding. Consistent documentation processes are key. Microservices enable scalability and velocity but require thoughtful coordination between teams to realize their benefits. With good communication and planning, they can accelerate delivery without disruption. I focused the revision on emphasizing microservices, their tradeoffs, and potential collaboration pitfalls between technical and non-technical teams. Let me know if you would like me to expand or refine any part of the chapter further. Here is a simplified hypothetical example to explain microservices and containers to non-technical audiences: ### Pizza app as microservices Let's rebuild the pizza ass with microservices! The app needs to show the menu and allow online orders. You could build this as one big app: ``` Big Pizza App - Menu code - Ordering code - Payment code ``` But there's an alternative way! You can split it into two smaller microservices: ``` Menu Microservice - Menu code ``` ``` Order Microservice - Ordering code - Payment code ``` Now the menu and orders are separated. Each microservice handles a single capability. We'll package these services into containers—think of them like reusable pizza boxes: ``` Menu Container - Menu code ``` ``` Order Container - Ordering code - Payment code ``` This makes the app: - **Flexible** - The menu and orders can be developed and updated separately. - **Scalable** - More order containers can be added if order volume increases. - **Reliable** - If one container goes down, the other keeps working. While simplified, this demonstrates the core ideas of microservices and containers - breaking apps into independent components that can be packaged and scaled modularly. ## Software Architecture - Choosing the Right Recipe for Your Web App Understanding software architecture can be seen as finding the right recipe for a pizza you want to introduce in your pizzeria. **Scaling - Choosing Your Pizza Size** Imagine you're hosting a pizza party. You'd naturally choose different pizza sizes based on the number of guests. Similarly, in software architecture, you decide on the scale that fits your project. Example: If you have a small group of friends over, you'd order a small pizza. Likewise, if you're building a simple website for a local business, you might choose a small-sized architecture. Wrong sizes lead to waste, both for pizza and web development. **Architectural Styles - Pizza Styles** Think of architectural styles like pizza styles. Whether it's a classic Margherita, a fancy new one such as pizza guacamole, just as you pick a pizza style, developers select an architectural style for web apps. Example: If you love the crispy texture of thin-crust pizza, you'd select an architectural style that prioritizes speed and efficiency. On the other hand, if you prefer a hearty, stuffed-crust pizza for its robustness, you might opt for a Microservices architectural style to handle complex functionalities. **Components - Toppings for Your Web App** Software components are like pizza toppings. Each enhances your web app's functionality. Just as you choose toppings for your pizza, you select components for your app's frontend, backend, and databases. Example: Consider your app's frontend. You can add extra cheese as a topping to enhance its appeal, just like adding authentication to enhance security for your web app. **Frameworks - Your Software Recipe** Frameworks are to software development what recipes are to pizza making. They guide the process and provide structure. Example: Think of using a web development framework like using a pizza recipe. Just as a recipe tells you the steps to make a delicious pizza, a framework provides pre-defined structures and tools to build your web app efficiently. **The Role of an Architect - The Pizza Chef** A skilled pizza chef and a software architect both make crucial decisions. They play a pivotal role in crafting something exceptional. Example: Picture a pizza chef creating a customized pizza based on your preferences. Similarly, a software architect chooses the right technologies and design patterns to ensure your web app's success. **Optimizing Communication - Pizza Delivery Routes** Optimizing communication protocols and APIs between the components is like optimizing pizza delivery routes. Both ensure seamless delivery. Example: Consider a pizza delivery app. Just as the app optimizes delivery routes to get your pizza to you hot and fresh, software architects optimize communication protocols and APIs to ensure that data flows smoothly between different parts of your web app. **Suboptimal Architecture - Ordering Mistakes** Implementing suboptimal architecture is like ordering a pizza with the wrong toppings. It requires effort to change, just like refactoring architecture. Example: Imagine you initially build your web app with an inefficient architecture. This is akin to ordering a pizza with toppings you don't like. To fix it, you'd need to make changes, just as in software development, you'd undergo a refactoring process to improve your app's architecture. **Custom vs. Pre-Built - Building Your Pizza** Choose between building a custom pizza (web app) or ordering from the menu (using pre-built solutions). This aligns with architectural decisions in software development. Example: Think of it this way: you can build a custom pizza with your preferred ingredients, just as you can create a web app tailored to your specific needs. Alternatively, you can order a pre-made pizza from a menu, similar to using third-party libraries or platforms to speed up your app development. Crafting the perfect software architecture sounds quite easy, but actually getting it right is an art, like making the perfect pizza, involves careful choices. Your choice today can influence the success of your software (or pizzeria) for quite some time because chanigng architecture and recipes takes a lot of energy and time. This is especially true in big teams with lots of different opinions. Next time you savor a slice, remember you're tasting the world of software architecture! 🍕🌐 ## **Log** - Find out what happened when from a text file In this chapter, we'll unravel the mysteries of logs, using a familiar setting—the command line interface (CLI) of our pizza ordering system on the server. Logs, in the context of web app development, are like the behind-the-scenes records of orders. By the end of this chapter, you'll confidently navigate logs, understand their significance in web app development, and even learn how to search for specific events. 🍕📜 ### **The Essence of Logs** **Pizza Slice Takeaway**: Logs are like order receipts in a CLI, providing a record of every action. Imagine the CLI as the control panel for our pizza ordering system. Logs, in this scenario, are akin to the order receipts. Just as every pizza order is documented, every action in the system is logged. Logs can be generated by all parts of the web app, such as frontend, backend, or database systems. These logs comprise three crucial elements: - **Timestamps:** Like time stamps on pizza orders, they record when an event occurred. - **Log Levels:** Think of log levels as different order types, each signifying the importance of an event. - **Messages:** Messages in logs are akin to pizza orders—they describe what happened during an event. ### **Navigating Logs in the CLI** **Pizza Slice Takeaway**: Learning to read logs on the CLI is as essential as navigating the order log. Reading logs helps We'll dive into practical steps: 1. **Accessing Logs:** Just as you open the pizza menu, you can access logs using CLI commands. 2. **Viewing Logs:** Think of viewing logs as reading the menu descriptions; you'll use commands to see log entries. 3. **Filtering Logs:** Like picking your pizza toppings, you can filter logs to find specific events. Let's look at an example of viewing logs with the `tail` CLI command: ```shell $ tail -n 10 app.log ``` This command fetches the last 10 log entries from the "app.log" file, just like checking the latest pizza orders. ### **Understanding Log Levels** **Pizza Slice Takeaway**: Log levels, similar to pizza varieties, tell us the significance of each log entry. In our CLI pizza world, log levels function much like pizza varieties on a menu. Here's how they break down: - **INFO (Margherita):** INFO-level logs provide basic information, much like ordering a basic Margherita pizza. - **DEBUG (Custom Pizza):** DEBUG-level logs are detailed, akin to creating a custom pizza with specific toppings. - **ERROR (Problem):** ERROR-level logs indicate issues, similar to encountering a problem with your pizza order. ### **Searching Logs for Answers** **Pizza Slice Takeaway**: Searching logs is like finding a pizza order in a logbook. It helps you locate specific events or issues. Searching for events in logs is akin to searching for your preferred pizza on a menu. We'll show you how to use the `grep` command to find specific events in your logs. For example: ```shell $ grep "Edamame" app.log ``` This command would retrieve all log entries containing pizza orders with "Edamame" beans. ### **Managing Large Logs Efficiently** **Pizza Slice Takeaway**: Just as you manage a mountain of pizza boxes, efficiently handling large logs is crucial. Dealing with large logs is akin to managing stacks of pizza boxes during a pizza party. Even if it's just text, logs can easily become very large and fill the full server. That's why often logs are being deleted after a certain timeframe or overwritten (it's called rolling logs then). Logs are good places to search for causes if things break or give unexpected results. Developers will appreciate it a lot if you already made the effort to browse them and looked for potential errors before approaching them. ## Tracking events Beyond tracking problems, ## **AB Testing** - Testing different versions of a feature to see which one performs better Imagine you run an online pizza ordering app, and you want to test if changing the color of the "Order Now" button increases orders. Here's some simplified code to illustrate the process: ```javascript // JavaScript code for tracking button clicks document.getElementById("orderButton").addEventListener("click", function() { // This event logs that a user clicked the "Order Now" button. trackEvent("button_clicked"); }); ``` Now, let's imagine you run this test for a week, and here are our results: - **Control Group (Original Button Color):** - Sessions: 1000 - Button Clicks: 200 - **Treatment Group (New Button Color):** - Sessions: 1000 - Button Clicks: 250 Now, using Bayesian evaluation, you can confidently say that the new button color increased clicks. This means more orders for your pizza app! **What you need to know about A/B Testing** A/B testing is like experimenting with different pizza recipes to find the one your customers love the most. In web app development, it's about trying out changes to see what makes your app better. Here's what you need to know to run good recipe tests: **Setting Clear Goals** Imagine you're perfecting a pizza recipe. You need a clear goal, like creating the ultimate pizza. In A/B testing, having a clear target is essential. It's like having a vision for your pizza. **Tracking and Consistency** When a customer orders a pizza, you write it down. This ensures they always get the same pizza. In A/B testing, you save a user's group (control or treatment) in a "cookie" to ensure consistent behavior. Think of cookies as order slips in your pizza shop. **Tracking User Behavior** To track user behavior, you can use events. Think of events like keeping an eye on which customers are clicking the "Order" button in your shop. **Comparing Control and Treatment Groups** Imagine your pizza shop serves two types of pizzas: Control and Treatment. The number of customers who dine (sessions) and the number of pizzas served (triggered events) are your metrics. You're comparing which type of pizza is more popular. **Understanding Bayesian Evaluation** Bayesian evaluation is like trying a slice of pizza and confidently saying, "This tastes better." It's a way to be sure about your results without getting into complicated statistics. **Sample Size and Test Duration** Planning the sample size (how many pizzas to make) and test duration (for how long) is essential. Imagine running your pizza shop: How many pizzas should you prepare for a night? How long should the taste test last? **Importance of Randomization** Randomization is like making sure every pizza has an equal chance of winning. In A/B testing, you need randomness to get reliable results, just like in a fair pizza contest. **Dealing with Biases and External Factors** Imagine your pizza contest is influenced by people's pizza preferences. You need to account for these biases and external factors. In A/B testing, it's about making sure your results aren't skewed. **Data Analysis and Interpretation** Analyzing data is like deciding which pizza is the tastiest. You look at the ingredients, taste, and presentation to decide which pizza is the winner. **Statistical Significance** Statistical significance is about being confident in your results. It's like being sure that your pizza is the best without getting lost in complicated numbers. In this chapter, we've shown you how A/B testing works, from setting goals to analyzing results. Now you can use it to make data-driven decisions in your web app development journey. Enjoy optimizing your app, just like crafting the perfect pizza! 🍕📈 ## **Email** - Old technology with limits that still connects people Email has been widely available since the mid 1990s, and it's like a digital post office for the internet. It helps people send messages to each other quickly and easily. In this chapter, we'll explore how email works without diving too deep into the technical stuff. Emails are used in web apps for different use cases such as password reset, order notification and sending product updates. Because email technology has aged, incorporating emails can be tricky and limited in features and may delay your delivery **Email's Secret Messengers: Mail Transfer Agents (MTAs)** Behind the scenes, email uses special helpers called Mail Transfer Agents (MTAs). Picture this: MTAs are like the delivery drivers who ensure your pizza order gets from the pizza shop to your doorstep. They make sure your email gets from your computer to your friend's computer. They follow the address on the envelope (the email address) to find the right place. **Sending and Receiving Emails** To send and receive emails, you use different protocols. These are like sets of rules that computers follow to talk to each other. Some of the popular ones are SMTP (Sending Mail), POP3 (Receiving Mail), and IMAP (Receiving Mail). SMTP is for sending, while POP3 and IMAP are for receiving emails. Think of these protocols as the language pizza shops use to communicate with delivery drivers and customers. SMTP is how the shop tells the driver what pizza to deliver, while POP3 and IMAP are how you receive the pizza at your doorstep. **Email Headers: Labels for Digital Mail** Think of email headers as the labels on your digital mail. They contain important information like the sender, receiver, and the path the email took to get to you. These headers are crucial for making sure your email goes to the right place. Picture this: Email headers are like the stickers on your pizza box that show who it's for, where it came from, and its delivery route. **Full Email with Headers Example:** Here's an example of a full email with headers: ``` From: John Doe <johndoe@yummypizzaapp.com> To: Jane Smith <janesmith@foodlovers.net> Subject: Dinner plans for Friday Date: Wed, 28 Sep 2023 19:30:00 +0000 Message-ID: <johndoe@yummypizzaapp.com> Content-Type: text/plain; charset="UTF-8" Hey Jane, Are you up for dinner this Friday? Let's meet at our favorite Italian restaurant at 7:00 PM. Looking forward to catching up! Best regards, John ``` In this example: - **From**: The sender's name and email address. - **To**: The recipient's name and email address. - **Subject**: The subject of the email. - **Date**: The date and time the email was sent. - **Message-ID**: A unique identifier for the email. - **Content-Type**: Specifies the type of content and character encoding used in the email body. **Email Limitations Emails can display rich content, like websites, using HTML and CSS. However, email clients don't work exactly like web browsers, and security can be a challenge. In the future, we'll explore topics like SPIF, domain spoofing, how to verify email legitimacy, and avoiding spam folders. **Reasons Why Emails land in Spam:** Emails can land in spam folders for various reasons, and email providers use complex algorithms to determine what is spam. Here are common reasons: 1. **Unauthenticated Sender**: Emails without proper authentication, like SPF and DKIM records, may be seen as suspicious. 2. **Spammy Content**: Emails with excessive use of trigger words (e.g., "Viagra," "Free Money") or too many exclamation marks can trigger spam filters. 3. **Blacklisted IP or Domain**: If the sender's IP address or domain is on a spam blacklist, emails are likely to be marked as spam. 4. **Low Engagement**: If recipients consistently mark emails as spam or don't engage with them, future emails from the sender may be flagged. 5. **Misleading Subject Lines**: Emails with deceptive subject lines or misleading content can be treated as spam. 6. **Large Attachments or Links**: Emails with large attachments or multiple links can appear suspicious. 7. **HTML and CSS Issues**: Poorly formatted HTML or CSS in emails can trigger spam filters. 8. **Mismatched Sender Information**: If the sender's information doesn't match the email's headers, it can raise suspicions. **How to Prevent Emails from Landing in Spam:** To prevent emails from going to spam folders: 1. **Authentication**: Implement SPF, DKIM, and DMARC records to authenticate your email server and domain. 2. **Quality Content**: Avoid spammy content, use clear and relevant subject lines, and provide valuable information. 3. **Clean Lists**: Maintain clean email lists by regularly removing inactive or bouncing addresses. 4. **Engagement**: Encourage recipients to open and engage with your emails. Ask them to mark your emails as "Not Spam." 5. **Monitor Blacklists**: Regularly check if your domain or IP address is on spam blacklists and take action to remove it if necessary. 6. **Use a Reputable Email Service**: Use a reputable email service provider with a good sender reputation. **Keeping It Safe: SPF and DKIM** Emails can be private, so you use things like SPF (Sender Policy Framework) and DKIM (DomainKeys Identified Mail) to make sure they are real and not fake. These tools help prevent email scams and phishing attacks. Imagine SPF and DKIM as the security measures in place to ensure your pizza is made by the real pizza shop and not an impostor. **SPF (Sender Policy Framework) and DKIM (DomainKeys Identified Mail) Example:** SPF and DKIM are security measures that help ensure the legitimacy of emails. Here's an example of how they work together: Suppose you receive an email claiming to be from "johndoe@yummypizzaapp.com." To verify its authenticity, your email server performs SPF and DKIM checks: 1. **SPF Check**: The sender's domain (yummypizzaapp.com) publishes SPF records in their DNS settings. Your email server queries these records to check if the IP address of the sending server is authorized to send emails on behalf of yummypizzaapp.com. If it matches, the email passes the SPF check. 2. **DKIM Check**: The sender's email server signs the email with a private key, and the public key is published in DNS as a DKIM record. Your email server uses this public key to verify that the email's content hasn't been altered during transit. If the email's content matches the DKIM signature, it passes the DKIM check. If both SPF and DKIM checks pass, the email is considered legitimate. If either check fails, it might be a suspicious or fraudulent email. ## **Open Source** - Every company uses collaboratively created free software > Person_A: "We should consider making the project open source so that other developers can contribute." > Person_B: "Good idea, let's pick a fitting license" Open-source software is an essential component of many projects, providing readily available code and libraries. However, incorporating open-source components introduces a unique set of challenges. While open-source software can accelerate development and reduce reinvention of the wheel, it can also contribute to technical debt if not managed effectively. Keeping track of open-source dependencies, staying aware of vulnerabilities or updates, and contributing back to the community can help mitigate the risk of accumulating technical debt. **1. Understanding Open Source Licenses** Open source licenses are like the rules of the recipe. They dictate how you can use, share, and modify code. Let's explore some common licenses: - **MIT License**: It's like saying, "Here's my recipe; do whatever you want with it, just give me credit." MIT-licensed code allows for maximum freedom and is often used in both commercial and open source projects. - **GPL (GNU General Public License)**: This license is a bit more like, "You can use my recipe, but if you make changes and share it, your version must also be open source." It ensures that open source code remains open. - **Apache License**: This one is akin to, "You can use my recipe, modify it, and even sell the dish, but you must include a notice that you used my recipe." It encourages collaboration while preserving authorship. **2. Open vs. Closed Source** Open source is like hosting a potluck dinner where everyone brings a dish to share. It fosters collaboration and transparency. Closed source, on the other hand, is like a secret family recipe – you can enjoy the dish, but you don't know what's in it. - **Benefits of Open Source**: It encourages innovation, allows for community-driven development, and often leads to higher-quality software. For example, the Linux operating system is a famous open source success story. - **Benefits of Closed Source**: Closed source can protect intellectual property and business secrets. Companies use this model for their proprietary software. **3. Myths and Misconceptions** Open source can be misunderstood. Let's debunk some myths: - **Myth 1: Open Source Means Low Quality**: Not true. Many open source projects are top-notch, like the web browser Firefox. - **Myth 2: Open Source Is Just About Code**: It's more than that. It's about community, collaboration, and shared values. **4. The Power of Documentation and Community** Imagine a recipe without instructions; it would be chaotic. Documentation in open source is like a well-written recipe card. The community is your group of cooking buddies who help when you're stuck. - **Documentation**: Good documentation explains how to use and contribute to a project. For instance, Python's documentation is praised for its clarity. - **Community**: Good open source projects thrive because of their vibrant communities. They offer support, answer questions, and improve the software collectively. **5. Identifying Quality Projects** Just like you'd inspect the ingredients before cooking, you should assess open source projects. Look for: - **Active Development**: Frequent updates and a responsive community are positive signs. - **Clear Licensing**: Projects with clear and permissive licenses are easier to work with. **6. Using Open Source in Business** Incorporating open source into your company's tech stack is like adding versatile ingredients to your kitchen. But it comes with considerations: - **Support**: Will you rely on community support or pay for professional support? - **Compliance**: Ensure your use of open source complies with licenses. **8. Business Models for Open Source** Companies can thrive in the open source world. Consider these models: - **Support and Services**: Offer support and consulting for open source projects. - **Dual Licensing**: Provide open source and proprietary versions. Using open source can speed up your development, but also slow it down. Here's why: **Reasons for Delay:** 1. **Integration Complexity:** Open source components may not always seamlessly integrate with your existing codebase, leading to integration challenges and potential delays. 2. **Dependency Management:** Relying on open source libraries means you're dependent on external updates and fixes, which can slow down development if those updates introduce breaking changes or bugs. 3. **Security Concerns:** Ensuring the security of open source components can be time-consuming. You need to continually monitor for vulnerabilities and apply patches promptly. 4. **Lack of Support:** Open source projects may lack dedicated support teams. When issues arise, waiting for community support can lead to delays. 5. **License Compliance:** Understanding and complying with various open source licenses can be complex. Missteps in licensing can result in legal issues that halt progress. By addressing these challenges proactively, you can harness the benefits of open source while minimizing potential delays in your project's delivery. ## **Technical Debt** - Taking shortcuts or making compromises in software development that need to be addressed later In the fast-paced world of technology, technical debt has become a significant concern for teams and organizations. In this chapter, you will explore why technical debt matters to non-technical individuals working in technical teams. Understanding the impact of technical debt is crucial for making informed decisions and maintaining a healthy and efficient development process. **1. Slows Down Execution** Technical debt matters because it directly affects the speed and efficiency of your team's execution. When technical debt accumulates, it introduces complexities, workarounds, and suboptimal solutions within the codebase or system. These shortcuts may provide short-term benefits by saving time or effort, but over time, they become a burden. Technical debt increases the complexity of future development, leading to slower progress and decreased productivity. Teams may spend more time debugging, fixing issues, and integrating new features, instead of focusing on innovation and delivering value. **2. Inevitability of Technical Debt** Technical debt matters because it is an inevitable part of the software development process. It arises from various factors, including time constraints, business pressures, evolving requirements, and the need for quick releases. As software evolves, changes, and adapts to new circumstances, technical debt tends to accumulate. It's important to acknowledge that technical debt is not inherently bad or avoidable. Instead, it needs to be managed effectively to minimize its negative impact. **1. Dependencies** Dependencies play a significant role in technical debt. When your code relies on external libraries, frameworks, or modules, you introduce a level of dependency. If these dependencies are not properly managed or kept up to date, they can become a source of technical debt. Outdated or incompatible dependencies can lead to security vulnerabilities, performance issues, or difficulties in upgrading other parts of the system. It is crucial to maintain a clear understanding of your project's dependencies and actively manage them to minimize technical debt. **3. Update/Upgrade Processes** Regular updates and upgrades are vital for maintaining a healthy software ecosystem. Neglecting updates can lead to a significant increase in technical debt. Updates often include bug fixes, security patches, performance improvements, and new features. Failing to incorporate these updates in a timely manner can result in a growing gap between the current state of your system and the latest stable versions. This divergence leads to increased complexity and compatibility issues, potentially slowing down future development and introducing additional technical debt **4. Semver (Semantic Versioning)** Semantic versioning, or Semver, is a widely adopted versioning scheme used in software development. Semver provides a standardized way to communicate the compatibility and impact of changes between different versions of software components. Understanding Semver is crucial for managing technical debt. By following Semver guidelines, you can make informed decisions about incorporating updates, identifying breaking changes, and managing compatibility with other dependencies. This knowledge helps prevent the accumulation of technical debt due to incompatible or poorly planned version upgrades. **5. Maintenance** Maintenance encompasses all activities required to keep a software system operational, secure, and up to date. Neglecting maintenance tasks can significantly contribute to technical debt. Proper maintenance includes activities such as code refactoring, bug fixing, performance optimization, security audits, and documentation updates. By prioritizing and allocating resources for maintenance tasks, you can proactively address technical debt and prevent it from escalating. **Conclusion** Technical debt matters to non-technical individuals in technical teams because it directly impacts their ability to execute efficiently. By understanding the consequences of technical debt and its related concepts such as dependencies, open-source software, updates/upgrades, Semver, and maintenance, non-technical team members can actively contribute to managing technical debt and promoting a healthy development process. Recognizing the inevitability of technical debt and taking proactive steps to mitigate its impact is crucial for long-term success in software development. In addition to the points mentioned earlier, there are several other aspects that could be covered in the chapter on technical debt for non-technical people in technical teams. Here are some additional topics to consider: **1. Types of Technical Debt** Explore different types of technical debt, such as design debt, code debt, architectural debt, testing debt, and documentation debt. Explain how each type of debt can accumulate and impact the development process. **2. Causes of Technical Debt** Discuss the various factors that contribute to the accumulation of technical debt, such as tight deadlines, insufficient resources, changing requirements, inadequate planning, and lack of communication. Help non-technical team members understand the underlying causes and how they can influence the management of technical debt. **3. Consequences of Ignoring Technical Debt** Highlight the potential consequences of ignoring technical debt, such as increased maintenance costs, decreased stability, higher defect rates, slower delivery of new features, reduced code quality, and negative impact on team morale. Emphasize the long-term implications and risks associated with neglecting technical debt. **4. Techniques for Managing Technical Debt** Introduce strategies and techniques for managing technical debt effectively. This could include approaches like refactoring, prioritizing debt repayment, conducting regular code reviews, establishing automated testing practices, fostering a culture of continuous improvement, and allocating dedicated time for debt reduction. **5. Communicating Technical Debt to Stakeholders** Discuss the importance of effectively communicating technical debt to stakeholders, including project managers, product owners, and executives. Explain how to articulate the impact of technical debt on project timelines, resource allocation, and overall business goals. Provide guidance on presenting technical debt in a way that resonates with non-technical stakeholders and facilitates informed decision-making. **6. Tools and Metrics for Tracking Technical Debt** Introduce tools and metrics that can help track and quantify technical debt. Discuss the use of code analysis tools, code coverage metrics, and maintainability metrics to identify areas of high technical debt. Explain how these tools and metrics can provide valuable insights and aid in prioritizing debt repayment efforts. **7. Balancing Technical Debt and Business Priorities** Explore the delicate balance between addressing technical debt and meeting business priorities. Help non-technical team members understand the trade-offs involved in managing technical debt while delivering value to customers and stakeholders. Discuss strategies for prioritizing debt repayment alongside feature development and project deadlines. **8. Preventing Technical Debt** Offer guidance on proactive measures to prevent the accumulation of technical debt. Discuss the importance of code reviews, test-driven development, continuous integration, and other best practices in writing clean and maintainable code. Emphasize the value of investing time upfront to avoid technical debt down the line. Remember to tailor the chapter's content to the target audience of non-technical individuals in technical teams, ensuring that the concepts and explanations are accessible and applicable to their roles and responsibilities. ## **Software Development Lifecycle** - Which stages software development goes to until code is live Software does not go from idea to live in one go. There is a repeatable cycle for everything: `Scope > Research > Spike > Buy or build > Plan > MVP > Review > Test > Debug > Deploy > Live` And at each step, there are many things that can go wrong. **Backend Environments: No two ovens are a like** Changes to your backend code can not be done on the live web app, because it might not work as expected. Also, when multiple developers work on the backend, they all have to test it out on their own machine. So there are what's called different environments where the backend runs. There's the famous claim: "It works on my machine" which says that the code runs on a developer's machine but not on the real system. This is like having multiple ovens where one is for trying out new recipes that is smaller and having one real oven that is used for customer orders. ### Scope Scoping means to find out what is important and what not. What should be part of the feature and what not. This is thinking in what the code should and should not do. But in a very broad sense, not just in edge cases. A scope for our pizza app could be "Only for one language". Having multiple languages in the app would make it a lot more complicated. Scoping is not only about what the users will get, but also how complex the app itself gets. The smaller the scope, the easier the code, the easier it will get to change code later once you find out what works with the user and what not. ### Research To research means to search how a problem similar to yourse was solved in the past. This can be looking at your own code from the past or searching online for what other people did in the past. In this phase, developers will also search for libraries, frameworks or even complete services with APIs that help with the problem. This is called the "buy or build?" dilemma. ### Buy or build Buying often comes with a big upfront cost and seems to be less flexible, because what you buy will never be completely fulfilling all your needs and requirements. Buying also seems to be a problem outside of developer's mind and responsibility, because hey, they should code, not buy ready solutions. But this perspective misses the point. As said, developers want to solve a technical challenge, not write as much code as possible. Also, developers know best that "building" has some long-term costs that non-technical people easily oversee: you have to document and maintain your own code, if you just let it run for some time, it will certainly break. And if the developer who built a custom tool leaves the company, all the knowledge is gone. So, maybe surprisingly for you, good developers will actually propose to business quite often to not build certain things ourselves. ### Spike In the "Spike" phase, developers take a deep dive into specific technical challenges. It's like the moment a pizza chef decides to experiment with a new type of dough or sauce. They explore potential solutions, create prototypes, and investigate feasibility. This phase allows developers to gain insights into the best way to tackle complex problems before committing to a full-blown development effort. It's a bit like trying out new ingredients before making a whole pizza. ### Plan The "Plan" phase is the critical stage where the roadmap for your software project takes shape. It's like designing the menu for your pizza restaurant, deciding which pizzas to offer and how they'll be prepared. In this phase, several key activities take place: - Understanding requirements gathering and analysis: Just as a pizzeria owner must understand the preferences of their customers, developers gather and analyze requirements from stakeholders to determine what the software should achieve. This involves detailed discussions, interviews, and documentation to capture the needs and expectations of users. - Designing and spiking of the software solution: Think of this as the pizza chef creating a blueprint for each pizza recipe. Developers design the architecture, structure, and user interfaces of the software. They might also conduct "spikes," which are exploratory efforts to investigate specific technical challenges or experiment with different approaches to solving problems. - Coding and implementing the features: Similar to assembling the ingredients and preparing the dough for a pizza, developers start writing code based on the designs. They transform concepts and plans into actual software components. This is where the real cooking, or coding, begins. - Testing and quality assurance: Just as a chef tastes a pizza before it's served, developers perform various tests to ensure the software functions correctly. Quality assurance is crucial to catch any defects or inconsistencies early in the process. It's like making sure the pizza meets quality standards before it reaches the customer's table. - Deployment and release management: Once the software is ready, it needs to be deployed, which is like serving the prepared pizza to customers. Deployment involves careful planning and coordination to ensure a smooth and error-free release. Release management ensures that the right version of the software is delivered to the right users at the right time. - Maintenance and ongoing support: Like a pizzeria that maintains its kitchen equipment and provides ongoing customer service, software requires continuous attention. Developers monitor the software in production, address issues, and provide support to users. Maintenance ensures that the software remains reliable and up-to-date. The "Plan" phase lays the foundation for the entire software development journey. It ensures that everyone involved in the project understands what needs to be built, how it will be built, and how it will be maintained. Effective planning sets the stage for a successful development cycle, just as a well-thought-out menu and kitchen preparations are essential for a thriving pizza restaurant. ### Code Review Code review is akin to having a second set of eyes examine your pizza-making process. It's a collaborative effort where developers carefully inspect each other's code to ensure quality and consistency. Think of it as a team of pizza chefs checking each other's dough, sauce, and toppings to guarantee the final product meets the highest standards. ### MVP The MVP phase is where you create the simplest version of your software that delivers value to users. Picture it as serving a basic cheese pizza to your customers before adding extra toppings. This approach allows you to gather feedback early, ensuring that you're on the right track and not overcomplicating things from the start. ### Test and Debug Testing is like quality control in a pizza kitchen. You want to make sure your software functions correctly, just as a pizza should taste delicious. Testing involves running various scenarios to identify and fix any issues or "taste" problems. Debugging is the process of tracking down and eliminating these issues, ensuring your software operates smoothly, just like making sure your pizza doesn't have any burnt edges or undercooked spots. ### Deploy Deployment is similar to serving the finished pizza to your customers. It's the moment when your software goes live for users to access. But, just like delivering a pizza to a customer's doorstep, deploying software requires careful planning and coordination to ensure a smooth and error-free release. ### AB Test AB testing is like experimenting with different pizza recipes to see which one customers prefer. In this phase, you might offer two versions of your software to different user groups and compare their experiences. It helps you make data-driven decisions about which features or changes to keep and which ones to discard. ### Live The "Live" phase is where your software is in constant operation, serving users like a popular pizzeria. It's essential to monitor its performance, gather user feedback, and continuously improve it. This phase never truly ends, much like a successful pizza shop that evolves its menu based on customer preferences and market trends. ## **Testing and Quality Assurance** - How to make sure that software actually works In the world of web app development, testing plays a pivotal role in ensuring the quality and reliability of software. In this chapter, you will delve into the essential aspects of testing, from its significance in the software development process to the various types of testing techniques that help maintain the integrity of your web application. ### The Role of Testing in the Software Development Process Testing is the unsung hero of web app development. It's the process of systematically examining your code and application to identify and rectify any issues or bugs. Think of it as quality control for your digital creations. Testing ensures that your web app not only works as intended but also stands up to the challenges it may encounter in the real world. ### Different Types of Testing Testing isn't a one-size-fits-all endeavor. There are various types of testing, each with a unique purpose: - **Unit Testing**: This is like checking each ingredient in your pizza separately before putting them all together. It examines individual components of your code to make sure they function correctly. - **Integration Testing**: Imagine testing how well different ingredients blend together to create a harmonious flavor. Integration testing checks how different parts of your web app work together. - **Regression Testing**: Like ensuring that your tried-and-true pizza recipe remains the same after making changes. This type of testing ensures that new code changes don't break existing features. - **User Acceptance Testing (UAT)**: This is when your customers get to taste the final pizza and give their verdict. UAT ensures that the web app meets user expectations and requirements. ### Creating Test Plans and Test Cases Just as a pizza chef follows a recipe, developers create test plans and test cases to guide their testing efforts. These documents outline what needs to be tested, how it will be tested, and the expected outcomes. It's like having a cooking plan for your web app. ### Automation of Testing Processes Automated Tests are the secret sauce of efficient development. By setting up automated processes, you can have your tests run automatically, saving time and effort. It's like having a robot chef who can cook your pizza perfectly every time. ### Continuous Integration and Continuous Testing Think of this as constantly taste-testing your pizza throughout the cooking process to ensure it's turning out just right. Continuous integration and continuous testing are practices that involve regularly merging code changes and running tests to catch issues early. ### Bug Tracking and Issue Management Every chef encounters a burnt crust or a misplaced olive now and then. Similarly, in web app development, bugs are bound to happen. Bug tracking and issue management help you keep track of these imperfections and prioritize fixing them. ### Edge Cases In the world of pizza, these are the unusual requests, like pineapple on pizza or a pizza with no cheese. In web app testing, edge cases involve considering and testing scenarios that are at the extreme or uncommon ends of the expected input or usage spectrum. This ensures that your software can handle unexpected or unusual situations effectively. In this chapter, we've covered the critical role of testing, the various types of testing, the importance of test plans and cases, automation, continuous testing, bug tracking, and the significance of handling edge cases. Testing is the guardian of your web app's quality, and mastering it is key to delivering a top-notch product. So, get ready to become a testing pro, even if you're a non-techie. 🚀 ### Example ```python def compose_pizza(topping): return "Your pizza: " + topping # Execute function and save result to variable my_pizza = compose_pizza("mushrooms") # Print out the result print(my_pizza) ``` And the test: ```python import unittest # Create the function to be tested def compose_pizza(topping): return "Your pizza: " + topping # Create a test class that inherits from unittest.TestCase class TestComposePizzaFunction(unittest.TestCase): # Define a test case def test_compose_pizza(self): result = compose_pizza("mushrooms") self.assertEqual(result, "Your pizza: mushrooms") # Run the tests if __name__ == '__main__': unittest.main() ``` Why can I not just try it out myself? What's the advantage? Well, for this simple example, yes, you could just try it out manually. Automated testing gets interesting when you have many functions and often they also relate to each other. What can happen is that you add a new feature with a new function and an old one breaks. You would have to manually test the full app. Here's an example: The boss wants to charge the topping by the length of the topping's name. The developer adjusts the function and adds the length in brackets: ```python def compose_pizza(topping): # New feature: calculate length of topping and append it topping_length = len(topping) return f"Your pizza: {topping} ({topping_length} characters)" # Execute function and save result to variable my_pizza = compose_pizza("mushrooms") # Print out the result print(my_pizza) ``` But now they introduced a problem. If the user purchases a topping that is a number (like `2`), maybe from the list of all toppings, you know users do all of unexpected things, the app breaks, because a number has no length. Before, the cook would get the message "Your pizza: 2", would check the list of toppings and pick mushrooms. Now, they are confronted with this error message only: `TypeError: object of type 'int' has no len()` and call the developer. ## **Technical Documentation and RFCs** - Technical documentation provides decicisions, instructions, and explanations for software developers and users Technical documentation is like the recipe book for web app development. It provides decisions, instructions, and explanations for both software developers and users. Let's dive into this crucial aspect of tech. ### Types of Technical Documentation Technical documentation comes in different flavors, just like various dishes at a restaurant. You have API documentation, which is like a menu describing the available options. Then there are user manuals, your guide to using the software effectively. Each type serves a specific purpose, ensuring everyone can enjoy the tech feast. ### Writing Clear and Concise Documentation Think of writing technical documentation like preparing a meal. You want it to be clear and concise, just like a well-structured recipe. Use simple words and straightforward language, making it easy for everyone to follow along. Avoid jargon and complexity; think of it as creating a dish that everyone can savor. ### How to Read Technical Documentation? Reading technical documentation is like using a kitchen tool, such as a knife. You need to understand how it works to get the job done efficiently. Let's take the example of the `rm` command: - `rm` is like our tool. - It removes files, not directories, by default. - There are options you can use, like choosing a cutting technique. - If you want to be extra cautious, you can make it interactive, just like asking for permission before slicing. ### Versioning in Documentation Versioning is like labeling your dishes. It helps you track changes and improvements over time. Just like a restaurant updates its menu, software documentation gets better with newer versions. It ensures that everyone gets the most up-to-date information, like tasting the latest recipe. ### RFCs Imagine creating a tech plan with a group, just like deciding on a pizza topping. RFCs, or Request for Comments, are the recipes of tech, ensuring that everyone can understand and work together. They simplify processes and choices, and we'll explore how they make tech work like a well-loved cookbook. - **Start with idea:** A developer starts with an idea, writes it down, and shares it with other developers for feedback. - **Comment:** Like picking pizza toppings, everyone suggests changes until everyone agrees. - **Write it down:** Then, it's written down in detail, just like a pizza recipe. - **Review:** Other developers review it, like chefs reviewing recipes for a delicious outcome. - **Make it official:** Once everyone's happy, it becomes official. - **Bring to live:** Like making pizza, you put the plan into action. - **Revise:** If needed, like trying different pizza toppings, RFCs can be updated. - **Great for collaboration:** RFCs ensure everyone works together smoothly, like having a clear manual. - **Quality guaranteed:** They keep things consistent and reliable, like following a trusted recipe. ## **Bug Tickets** - Tracking issues in software with organized text, making it easier to identify and fix problems. **Introduction** In the world of web app development, bugs are like the dough that refuses to rise or the oven that refuses to heat. They're pesky, they disrupt the cooking process, and if left unchecked, they can ruin the whole pizza party. Bug tickets are your secret sauce to tackle these issues and ensure your web app comes out of the oven perfectly baked. **Why Bug Tickets Matter** Bugs in software are like the sneaky mushrooms hiding under the cheese; you might not notice them until you take a bite. These bugs can range from minor annoyances to critical errors that crash the entire app. Every bug can cost you time, money, and customers. Imagine a pizza place that consistently serves burnt or undercooked pizzas – customers won't return, and your reputation will suffer. ### Creating Effective Bug Tickets Now that you understand why bug tickets matter, let's dive into the art of creating effective ones. Think of a bug ticket as your order at the pizza place. The more specific and clear your order, the better your chances of getting the perfect pizza. **Clear and Concise Descriptions** When you report a bug, use simple and straightforward language. Avoid jargon and technical terms that might leave your developer scratching their head. For instance, instead of saying, "The API endpoint is returning a 404 error," you could say, "I can't access the shopping cart." **Including Relevant Details** Just like you'd specify your pizza toppings, provide all the relevant details in your bug ticket. Describe what happened, when it happened, and on which device or browser. Attach screenshots or error messages if possible. The more information you provide, the easier it is for your developer to understand and fix the issue. **Providing Context** Imagine ordering a pizza without specifying the size, crust, or toppings – chaos! Bug tickets are no different; they need context. Explain the steps that led to the bug's discovery. What were you doing before it happened? This context helps developers reproduce the issue, making it easier to identify and fix. ### **Common Mistakes to Avoid** As with any recipe, there are pitfalls to avoid when creating bug tickets. Here are a few common mistakes: **Overloading Bug Tickets with Unnecessary Information** While details are crucial, don't drown your bug ticket in unnecessary information. Stick to the problem at hand and avoid unrelated tangents. **Using Technical Jargon** Don't pepper your bug ticket with technical jargon. Keep it accessible to everyone on your team, regardless of their technical background. **Ambiguity in Bug Descriptions** Avoid vague descriptions like "It's not working" or "Something's wrong." Be specific, and if you're unsure, provide as much context as possible. **Bug Ticket Workflow** Bug tickets follow a journey, much like the various stages in making a pizza. They start from the moment you discover a bug and go through a series of steps until they're resolved. Understanding this workflow is essential for effective collaboration between non-technical and technical team members. **How Bug Tickets Move Through the Development Process** Typically, bug tickets follow a workflow that includes stages like "Open," "In Progress," "Testing," and "Resolved." Each stage signifies a different phase in resolving the issue. **Collaboration Between Non-Technical and Technical Team Members** Effective collaboration is like the teamwork in a pizza kitchen. Non-technical team members create bug tickets with clear instructions, while technical team members use their skills to fix the issues. Clear bug tickets and open communication ensure a smoother process. **Tools for Bug Tracking** Just as every pizza place needs its tools and utensils, bug tracking requires the right software. There are various bug tracking tools available, each with its strengths. Finding the right tool for your team can significantly improve your bug tracking process. **Introduction to Bug Tracking Software** Bug tracking software is designed to streamline the process of reporting, tracking, and resolving issues in software development. Examples include Jira, Trello, and Bugzilla. **Choosing the Right Tool for Your Team** Selecting the right tool depends on your team's size, needs, and budget. Consider factors like ease of use, integration with other tools, and customization options. **Conclusion** In this chapter, we've learned that bug tickets are the backbone of effective communication in web app development. They help you identify, track, and resolve issues, ensuring a smoother development process and a better end product. By creating clear and concise bug tickets, providing context, and using the right bug tracking tools, you can improve collaboration between non-technical and technical team members and serve up a perfect web app, just like a well-baked pizza. # And now? Your next steps You finished the book and scratched the surface for everything that makes web technology. What comes next? When you work in a tech team, this question will not come up, you will already know a new challenge that slows down delivery or challenges your collaboration with the developers. You know what you have to do: Ask them questions and dive deeper into the details until you are able to have a better conversation and solve the challenge together. Learn what you need and learn what you are interested in.