DEV Community

Cover image for The Complete Guide to Becoming a Web Developer: Part 4
Ahmed Radwan
Ahmed Radwan

Posted on • Originally published at nerdleveltech.com

The Complete Guide to Becoming a Web Developer: Part 4

Welcome, fellow web explorers! Today, we continue with our becoming a web developer series and embark on an exciting journey into the heart of modern web development. Our travel companions? Three powerful technologies have revolutionized how we interact with the web: AJAX, JSON, and APIs.

If you are new here, you can start with part 1, part 2, or part 3. Now let's start with a quick introduction.

Introduction

AJAX (Asynchronous JavaScript and XML) is like a secret agent for your web page. It works behind the scenes, communicating with the server, fetching data, and updating the web page, all without needing to reload the entire page. This makes for a smooth, seamless user experience. Imagine being able to update a news feed, post a comment, or load more items in a shopping category without a page refresh. That's AJAX in action!

Next up, we have JSON (JavaScript Object Notation). JSON is the language of data on the web. It's a simple, lightweight format for storing and transporting data. JSON is easy for humans to read and write, and easy for machines to parse and generate. It's like the universal translator for data on the web, allowing different systems and programming languages to communicate and exchange data with ease.

Last but not least, we have APIs (Application Programming Interfaces). An API is like a menu in a restaurant. It provides a list of operations that are available for you to use. When you interact with an API, you're telling it what operation you want to perform, and the API takes care of the rest. APIs are used everywhere in web development, from fetching data from a database to interacting with external services like social media platforms, weather services, payment gateways, and many other examples.

Together, AJAX, JSON, and APIs form the backbone of dynamic, interactive web applications. They allow us to create rich, responsive user experiences, and open up a world of possibilities for what we can achieve with our web applications.

So buckle up, and get ready for an adventure. By the end of this journey, you'll have a solid understanding of AJAX, JSON, and APIs, and you'll be equipped with the knowledge and skills to use them effectively in your own projects. Let's dive in!

Section 1: Deep Look into AJAX

In this section, we're going to dive deeper into AJAX, JSON, and APIs. These three technologies are the pillars of modern web development, enabling us to create dynamic, interactive web applications. Let's break them down one by one.

What is AJAX?

AJAX stands for Asynchronous JavaScript and XML. It's a technique that allows web pages to be updated asynchronously by exchanging data with a web server behind the scenes. This means that it is possible to update parts of a web page, without reloading the whole page.

Let's break it down:

  • Asynchronous: This means that AJAX allows you to send and receive data (in the form of HTTP requests) to a server in the background, without interfering with the display and behavior of the existing page.
  • JavaScript: AJAX is implemented using JavaScript. JavaScript has the ability to send a request to a server, and to react to the response.
  • XML: This stands for eXtensible Markup Language. Despite its name, AJAX doesn't require the use of XML. AJAX applications can send data as plain text or as JSON text.

Here's a simple example of an AJAX request using the Fetch API:

fetch('https://api.example.com/data', {
  method: 'GET', 
})
.then(response => response.json())
.then(data => console.log(data))
.catch((error) => {
  console.error('Error:', error);
});

In this example, we're sending a GET request to 'https://api.example.com/data'. When we receive the response, we convert it to JSON and log it to the console.

Making XMLHttpRequests (XHR)

XMLHttpRequest (XHR) objects are like the Swiss Army knives of AJAX. They're used to interacting with servers and can retrieve data from a URL without having to do a full page refresh. This makes them a powerful tool for creating dynamic, interactive web applications.

Here's how you might create and send an XMLHttpRequest:

var xhr = new XMLHttpRequest(); // create a new XMLHttpRequest object

xhr.open('GET', 'https://api.example.com/data', true); // specify the type of request, the URL, and whether the request should be asynchronous

xhr.onreadystatechange = function () { // set up a function to run when the state of the request changes
  if (xhr.readyState == 4 && xhr.status == 200) // check if the request has been completed successfully
    console.log(JSON.parse(xhr.responseText)); // log the response data to the console
};

xhr.send(); // send the request

In this example, we're sending a GET request to 'https://api.example.com/data'. When the request is complete and successful, we log the response data to the console.

When I say that XMLHttpRequests are used to "interact with servers and can retrieve data from a URL without having to do a full page refresh," I'm referring to the ability to send HTTP requests directly from JavaScript running in the browser. This allows you to fetch data from a server and update the content of your web page without having to reload the entire page.

This is a fundamental aspect of AJAX (Asynchronous JavaScript and XML), which is a set of web development techniques used to create asynchronous web applications. With AJAX, you can send and receive data from a server after the page has loaded, and update parts of a web page without reloading the whole page.

Here's a simple example: let's say you have a web page that displays a list of users. Without AJAX, if you wanted to add a new user to the list, you would have to submit a form, the server would have to process the request and generate a new HTML page, and then the entire page would have to be reloaded in the browser to display the updated list.

With AJAX, you can send a request to the server to add a new user, and then just update the part of the page that displays the list of users with the new user. The rest of the page doesn't need to be reloaded.

Here's what that might look like with an XMLHttpRequest:

var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/users', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
  if (xhr.readyState == 4 && xhr.status == 200) {
    var newUser = JSON.parse(xhr.responseText);
    var userList = document.getElementById('userList');
    var newUserElement = document.createElement('li');
    newUserElement.textContent = newUser.name;
    userList.appendChild(newUserElement);
  }
};
xhr.send(JSON.stringify({
  name: 'John Doe',
  email: 'john@example.com'
}));

In this example, we're sending a POST request to 'https://api.example.com/users' to add a new user. When we receive the response from the server, we create a new list item with the new user's name and append it to the user list. The rest of the page doesn't need to be reloaded.

This ability to update parts of a web page without reloading the whole page is a key aspect of many modern web development frameworks and libraries, such as React, Angular, and Vue.js. These frameworks and libraries provide more advanced and efficient ways to update the DOM based on changes in application state, but the fundamental concept of updating parts of a web page without reloading the whole page is the same.

While XMLHttpRequests are powerful, they can be a bit verbose and complex to set up, especially for more complex requests. This has led to the development of newer APIs like the Fetch API and libraries like Axios, which provide a more modern and powerful interface for making HTTP requests. Let's have a comparison between all three so we can appreciate the amount of work done on these new tools, first start with XMLHttpRequest:

XMLHttpRequest (XHR)

XMLHttpRequest is the original method for making AJAX requests. It's supported in all browsers and has a wide range of features. However, its API is a bit clunky and outdated compared to newer methods. For example:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data');
xhr.onreadystatechange = function () {
  if (xhr.readyState == 4 && xhr.status == 200)
    console.log(JSON.parse(xhr.responseText));
}
xhr.send();

As you can see, the XHR API involves a lot of boilerplate code and manual handling of the response.

Fetch

The Fetch API is a modern alternative to XHR that provides a more powerful and flexible feature set. It's built into most modern browsers and returns Promises, which are easier to work with than the callbacks used by XHR. Here's how you might make a GET request with the Fetch API:

fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

As you can see, the Fetch API is much cleaner and easier to use than XHR. However, it's not supported in Internet Explorer, and it doesn't automatically send or receive cookies.

Axios

Axios is a promise-based HTTP client that works in the browser and in Node.js. It has a simple API and provides several features that aren't available in the Fetch API, such as automatic transformation of JSON data and progress events. Here's how you might make a GET request with Axios:

axios.get('https://api.example.com/data')
  .then(response => console.log(response.data))
  .catch(error => console.error('Error:', error));

Section 2: Deep Look into JSON

What is JSON?

JSON, or JavaScript Object Notation, is a lightweight data-interchange format. It's a way of encoding data structures that ensures that they are easy for humans to read and write and easy for machines to parse and generate. It's primarily used to transmit data between a server and a web application, serving as an alternative to XML.

Here's an example of what JSON data might look like:

{
  "name": "John Doe",
  "email": "john@example.com",
  "age": 30,
  "isMember": true
}

In this example, we have a JSON object that represents a user. It has four properties: name, email, age, and isMember.

Basic Rules for Writing JSON

JSON syntax is derived from JavaScript object notation syntax, but the JSON format is text only. Code for reading and generating JSON data can be written in any programming language.

Here are the basic rules for writing JSON:

  1. Data is in name/value pairs: JSON data is written as name/value pairs, just like JavaScript object properties. A name/value pair consists of a field name (in double quotes), followed by a colon, followed by a value, like so: "name":"John".
  2. Data is separated by commas: Just like in JavaScript, we can write multiple name/value pairs in JSON, and they must be separated by commas. For example: "name":"John", "age":30, "city":"New York".
  3. Curly braces hold objects: In JSON, curly braces {} hold objects, and each name is followed by a colon :. The name/value pairs are separated by a comma ,. For example: {"name":"John", "age":30, "city":"New York"}.
  4. Square brackets hold arrays: In JSON, square brackets [] hold arrays. For example: "employees":["John", "Anna", "Peter"].

Data Types in JSON

JSON supports various data types including:

  1. Numbers: No difference between integer and float. Also, no restrictions on number size. For example: "age":30 or "average":20.15.
  2. Strings: A collection of characters enclosed in double quotes. For example: "name":"John".
  3. Boolean: True or false. For example: "sale":true.
  4. Array: An ordered list of 0 or more values. For example: "employees":["John", "Anna", "Peter"].
  5. Object: An unordered collection of key/value pairs (i.e., a string/value pair). For example: "employee":{"name":"John", "age":30, "city":"New York"}.
  6. null: An empty value. For example: "middlename":null.

Here's an example of a JSON object that includes all these data types:

JSON Schema is a powerful tool for validating the structure of JSON data. It describes your existing data format in a clear, human, and machine-readable way. With JSON Schema, you can ensure the data you're receiving, or sending, follows a specific structure with defined data types, value formats, and even complex constraints.

What is a JSON Schema?

A JSON Schema is a JSON object that defines various attributes of the data including properties, required properties, default values, and data types. It provides a contract for the JSON data required by a given application, and how that data can be modified.

For example, let's say we have a JSON object for a person:

{
  "name": "John",
  "age": 30,
  "city": "New York"
}

A simple JSON Schema for this object could look like this:

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "age": {
      "type": "number"
    },
    "city": {
      "type": "string"
    }
  },
  "required": ["name", "age"]
}

In this schema, we define that our data is an object ("type": "object") with properties name, age, and city. The name and city are of type string, and age is of type number. We also specify that name and age are required properties.

Why is JSON Schema Useful?

JSON Schema is particularly useful in the following scenarios:

  1. Validation: You can validate that the JSON sent to your application by a client meets the expectations and won't break your code.
  2. Automated Testing: You can generate mock data for your tests based on your schema.
  3. Documentation: Your schema serves as a form of documentation for your API. It's a single source of truth that describes the shape of your data.
  4. IDE Support: Some IDEs can validate JSON data on the fly using JSON Schema, which can be a big help during development.

Validating JSON Data Against a Schema

There are many libraries available that can validate JSON data against a JSON Schema. One popular option for JavaScript is ajv.

Here's an example of how you might use ajv to validate data against a schema:

const Ajv = require('ajv');
const ajv = new Ajv();

const schema = {
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "age": {
      "type": "number"
    },
    "city": {
      "type": "string"
    }
  },
  "required": ["name", "age"]
};

const validate = ajv.compile(schema);

const data = {
  "name": "John",
  "age": 30
};

const valid = validate(data);

if (valid) {
  console.log('Data is valid!');
} else {
  console.log('Data is invalid:', validate.errors);
}

In this example, we first compile our schema into a validation function using ajv.compile(). We then validate our data using this function. If the data is valid, we print a success message. If it's not, we print the validation errors.

Common Security Concerns

Cross-Site Scripting (XSS)

Cross-Site Scripting (XSS) is a type of security vulnerability typically found in web applications. XSS attacks enable attackers to inject client-side scripts into web pages viewed by other users. If an attacker can inject malicious scripts into a JSON response that is then executed in the browser, they can potentially steal sensitive data, perform actions on behalf of the user, or carry out other harmful actions.

Insecure Deserialization

Insecure deserialization is another common security concern when working with JSON. Deserialization is the process of converting a serialized format (like a JSON string) back into a JavaScript object. If an attacker can manipulate the serialized data and the application doesn't properly validate or sanitize the deserialized data, it can lead to various types of attacks, including code injection, privilege escalation, or Denial of Service (DoS).

Best Practices to Mitigate JSON Security Risks

Validate and Sanitize Input

Always validate and sanitize input data, whether it's coming from a user form or a JSON payload. This can help prevent XSS attacks and other types of input-based attacks. There are many libraries available that can help with this, such as validator.js for Node.js.

Use HTTPOnly Cookies

To help prevent XSS attacks, consider storing sensitive data in HTTPOnly cookies. These cookies cannot be accessed by JavaScript, which means they can't be stolen by an XSS attack.

Secure Your Deserialization Process

To mitigate the risks associated with insecure deserialization, be sure to validate and sanitize your serialized data before deserializing it. Also, consider using safe serialization and deserialization libraries that have built-in protections against these types of attacks.

Use Content Security Policy (CSP)

Content Security Policy (CSP) is a security layer that helps detect and mitigate certain types of attacks, including XSS and data injection attacks. By defining the sources from which the browser is allowed to load resources, CSP can significantly reduce the risk and impact of XSS attacks.

Section 3: Deep Look into API

What are APIs?

APIs, or Application Programming Interfaces, are sets of rules that allow different software applications to communicate with each other. They define the methods and data formats that a program can use to communicate with other programs.

In the context of web development, APIs often refer to web services that return data. This data can be used to update a web page with new information, without needing to refresh the page.

Here's an example of how you might use an API:

fetch('https://api.example.com/users')
  .then(response => response.json())
  .then(data => console.log(data));

In this example, we're sending a request to 'https://api.example.com/users', which is an API that returns a list of users. We then log the data to the console.

HTTP Verbs

As you can see in the above we did a lot of requests using this protocol called HTTP. Let's now dig deep into that and what other types of requests(verbs or methods) include with that. HTTP verbs, also known as methods, are the actions that we can perform on resources. They form the backbone of any HTTP request, and understanding them is crucial to working with APIs. Let's dive into the most common ones: GET, POST, PUT, DELETE, and PATCH.

GET

The GET method is used to retrieve data from a server. It's like saying, "Hey server, can you give me the information located at this specific URL?"

Here's an example of a GET request using the Fetch API:

fetch('https://api.example.com/users')
  .then(response => response.json())
  .then(data => console.log(data));

In this example, we're asking the server to give us the list of users. The server then responds with the data, which we log to the console.

POST

The POST method is used to send data to the server. This could be anything from submitting a form, to adding a new item in a database.

Here's an example of a POST request:

fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'John Doe',
    email: 'john@example.com'
  }),
})
.then(response => response.json())
.then(data => console.log(data));

In this example, we're sending a new user to the server to be added to the database. The server then responds with the data of the newly created user.

PUT

The PUT method is used to update a resource on the server. It's like saying, "Hey server, can you update the information at this specific URL with this new data?"

Here's an example of a PUT request:

fetch('https://api.example.com/users/1', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'John Doe',
    email: 'john@example.com'
  }),
})
.then(response => response.json())
.then(data => console.log(data));

In this example, we're updating the user with the ID of 1. The server then responds with the data of the updated user.

DELETE

The DELETE method is used to remove a resource from the server. It's like saying, "Hey server, can you delete the information at this specific URL?"

Here's an example of a DELETE request:

fetch('https://api.example.com/users/1', {
  method: 'DELETE',
})
.then(response => response.json())
.then(data => console.log(data));

In this example, we're deleting the user with the ID of 1. The server then responds with a confirmation of the deletion.

PATCH

The PATCH method is used to partially update a resource on the server. Unlike PUT, which updates the entire resource, PATCH only updates the fields that were included in the request.

Here's an example of a PATCH request:

fetch('https://api.example.com/users/1', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    email: 'john@example.com'
  }),
})
.then(response => response.json())
.then(data => console.log(data));

In this example, we're only updating the email of the user with the ID of 1. The server then responds with the data of the updated user.

These are the most common HTTP verbs you'll encounter when working with APIs. As you continue your journey into web development, you'll find these methods to be your trusty tools, helping you interact with the vast world of data on the web. Happy journey!

HTTP Status Codes

HTTP status codes are like the server's way of communicating with us. They're three-digit numbers that tell us whether our HTTP request was successful, and if not, what went wrong. Understanding these status codes is crucial for debugging and handling errors in our applications. Let's dive into the four main categories of HTTP status codes: 2xx, 3xx, 4xx, and 5xx.

2xx Success

2xx status codes mean that our request was successful. The most common 2xx status code you'll encounter is 200, which means "OK". This status code is returned when our GET or POST request was successfully received, understood, and accepted.

Here's an example of how you might handle a successful response:

fetch('https://api.example.com/users')
  .then(response => {
    if (response.status === 200) {
      return response.json();
    } else {
      throw new Error('Something went wrong on api server!');
    }
  })
  .then(data => console.log(data))
  .catch(error => console.error(error));

In this example, we're checking if the status code is 200. If it is, we proceed with our code. If it's not, we throw an error.

3xx Redirection

3xx status codes mean that the client must take additional action to complete the request. This is often used for URL redirection. For example, a 301 status code means "Moved Permanently", indicating that the resource has been permanently moved to a new URL, and the client should proceed to that URL.

4xx Client errors

4xx status codes mean that there was a problem with the request. This is often due to something the client did, like requesting a resource that doesn't exist or not providing a valid authentication token. The most common 4xx status code is 404, which means "Not Found". This status code is returned when the server can't find the requested resource.

5xx Server errors

5xx status codes mean that the server failed to fulfill a valid request. The most common 5xx status code is 500, which means "Internal Server Error". This status code is returned when the server encountered an unexpected condition that prevented it from fulfilling the request.

Understanding HTTP status codes is crucial for handling responses and errors in our applications. By checking the status code of a response, we can determine whether our request was successful, and if not, what went wrong. This allows us to handle errors gracefully and provide a better user experience. So next time you see a status code, don't be scared - it's just the server's way of talking to you!

Query Strings

Query strings are like the secret messages of the web. They're part of a URL that contains data to be passed to web applications. They're often used to send data from a client to a server, and they can be incredibly useful for things like tracking user activity, storing user preferences, and more.

A query string starts with a question mark (?) and is followed by a series of parameters. Each parameter is a key-value pair, and multiple parameters are separated by an ampersand (&). Here's what a query string might look like:

https://example.com/page?param1=value1&param2=value2

In this example, the query string is ?param1=value1&param2=value2. It contains two parameters: param1 with a value of value1, and param2 with a value of value2.

Query strings are often used in GET requests to send data to the server. For example, if you're building a search feature for your website, you might use a query string to send the user's search term to the server. Here's what that might look like:

let searchTerm = 'javascript';
fetch(`https://api.example.com/search?term=${searchTerm}`)
  .then(response => response.json())
  .then(data => console.log(data));

In this example, we're sending a GET request to https://api.example.com/search?term=javascript. The server would then return the search results for 'javascript'.

To sum it up, query strings are a powerful tool in web development. They allow us to send data from the client to the server in a simple and efficient way. So next time you see a question mark in a URL, remember: it's not just a punctuation mark, it's a query string!

HTTP Headers

HTTP headers are like the secret whispers of an HTTP request or response. They allow the client and the server to pass additional information along with the request or response. They're not typically visible to the user, but they play a crucial role in the HTTP communication process.

HTTP headers are defined by their name and value, and they're structured like this: Header-Name: Header-Value.

There are many different types of HTTP headers, but here are a few of the most common ones you'll encounter:

  • Content-Type: This header tells the server what type of data is being sent. For example, Content-Type: application/json indicates that the data is in JSON format.
  • Authorization: This header is used to authenticate a user. For example, Authorization: Bearer your-token would include a bearer token for authentication. Look for further details on OAuth.
  • User-Agent: This header provides information about the client (like the browser and operating system).
  • Accept: This header tells the server what media types the client will accept.

Here's an example of how you might set headers in a fetch request:

fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your-token'
  },
  body: JSON.stringify({
    name: 'John Doe',
    email: 'john@example.com'
  }),
})
.then(response => response.json())
.then(data => console.log(data));

In this example, we're sending a POST request to 'https://api.example.com/data'. We're including two headers: 'Content-Type' and 'Authorization'. The 'Content-Type' header tells the server that we're sending JSON data, and the 'Authorization' header includes our bearer token for authentication.

HTTP headers are a powerful tool in web development. They allow us to send additional information with our HTTP requests and responses, enabling us to do things like authenticate users, specify the type of data we're sending, and much more. So next time you're sending an HTTP request, don't forget about headers - they might just be the secret ingredient you need!

Security Considerations

In the realm of AJAX, JSON, and APIs, security is like the castle walls that protect your kingdom. It's crucial to understand and implement security measures to protect your data and your users. Two important security considerations when working with APIs are Cross-Origin Resource Sharing (CORS) and Cross-Site Request Forgery (CSRF).

CORS

Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. By default, web browsers prohibit AJAX requests to different domains for security reasons. However, APIs can use CORS to allow other domains to make AJAX requests to them.

Here's an example of how you might set the CORS headers in an Express.js server:

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', 'https://your-allowed-origin.com');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  next();
});

In this example, we're using Express.js middleware to set the CORS headers for every response. We're allowing access from https://your-allowed-origin.com and allowing the Origin, X-Requested-With, Content-Type, and Accept headers in requests.

Remember to replace 'https://your-allowed-origin.com' with the actual origin you want to allow, or a variable that contains the origin. If you need to allow multiple specific origins, you'll need to check the Origin header of each request and set the Access-Control-Allow-Origin header accordingly.

CSRF

Cross-Site Request Forgery (CSRF) is an attack that tricks the victim into submitting a malicious request. It uses the identity and privileges of the victim to perform an undesired function on their behalf.

To protect against CSRF attacks, you can use a CSRF token. A CSRF token is a unique, random value associated with a user's session. This token is included as a parameter in unsafe methods (such as POST and DELETE), and the server checks this token before processing the request. If the token is missing or incorrect, the server rejects the request.

Here's an example of how you might include a CSRF token in an AJAX request:

axios({
  method: 'post',
  url: 'https://api.example.com/data',
  data: {
    name: 'John Doe',
    email: 'john@example.com'
  },
  headers: {
    'X-CSRF-Token': 'your-csrf-token'
  }
})
.then(response => console.log(response.data))
.catch(error => console.error('Error:', error));

In this example, we're including the CSRF token in the 'X-CSRF-Token' header.

Conclusion

We've come a long way in this guide, diving deep into the world of AJAX, JSON, and APIs. We've explored the fundamental concepts, compared different methods for making HTTP requests, and even built a simple web application using these technologies.

We started by understanding AJAX, JSON, and APIs, and how they work together to create dynamic and interactive web applications. We then dived into the details of HTTP verbs, status codes, headers, and query strings. We learned how to make XMLHttpRequests (XHR), and how to use the Fetch API and Axios for making HTTP requests. We also discussed setting headers with Axios, and the importance of error handling and security considerations when working with APIs.

Remember, the key to mastering these concepts is practice. Don't be afraid to experiment with different APIs, try out different HTTP methods, and build your own projects. The more you practice, the more comfortable you'll become with these technologies.

Additional Resources

For further reading and learning, here are some recommended online resources:

  1. MDN Web Docs: A comprehensive resource for developers, with detailed documentation on JavaScript, AJAX, JSON, APIs, and much more.
  2. JSONPlaceholder: A free online REST API that you can use for testing and prototyping.
  3. HTTP Status Codes: A handy reference for HTTP status codes.
  4. Axios GitHub Repository: The official GitHub repository for Axios, with detailed documentation and usage examples.
  5. Fetch API Introduction on JavaScript.info: A detailed guide on the Fetch API.

Remember, the journey of learning never ends. Keep exploring, keep building, and most importantly, have fun along the way! Happy coding!

Top comments (0)