connect to an API
REST countries
[ xmlHttpRequest | open | onload | status | responseText | onerror | send ]

Connect to API

Create an app that connects to the REST countries API and extracts data for a specified country.


APIApplication Programming Interface

An API (Application Programming Interface), is a set of rules and protocols that allows different software applications to communicate with each other. It defines the methods and data formats that applications can use to request and exchange information.

APIs structure their interactions through endpoints, which are designated URLs corresponding to accessible services or data.

When a client requires something, it submits a request to one of these endpoints.


URLUniform Resource Locator

A URL is a reference or address used to access resources on the internet. It specifies the location of a resource and the protocol used to retrieve it.

https://example.com/products/item1 URL

https protocol

example.com domain

/products/item1 path to the specific resource


Example ...

Find the capital of Spain.

Enter a country name ...

Spain country name

From the select input choose an option ...

Get information about country

capital of country selected option

The url containing the country name endpoint is sent to the server and the capital is extracted from the returned data.

["Madrid"] capital of country

Arrays are used to store multiple values in a single variable.

Each value is called an element, and each element has a numeric position in the array, known as its index.

Arrays are zero-indexed, meaning the first element is at index 0, the second at index 1, and so on.

Arrays can contain any data type, including numbers, strings, and objects.

const arr1 = [2, 4, 6]; array

arr1[0]; element at index 0 → 2

arr1[1]; element at index 1 → 4

arr1[2]; element at index 2 → 6

arr1[3]; element at index 3 → undefined index not found


Objects are a data structure used to store related data collections.

It stores data as key/value pairs, where each key is a unique identifier for the associated value.

Each key must be a string and must be unique, each value can be any data type.

If you define an object with duplicate keys, the last one will overwrite any preceding ones.

Find the value for any given key in the object.

const obj1 = {"A": 4, "B": 5, "C": 6 }; object

obj1["A"]; key "A" 4

obj1["B"]; key "B" 5

obj1["C"]; key "C" 6

obj1["D"]; key "D" undefined key not found

Find the value for any given key in the object.

const obj2 = {"A": 4, "B": 5, "C": 6 }; object

const str = "ABC"; string

obj2[str[0]]; 4

obj2[str[1]]; 5

obj2[str[2]]; 6

obj2[str[3]]; undefined key not found


Object.keys() static method returns an array with the keys of an object.

const obj3 = { "A": 4, "B": 5, "C": 6 }; object

const obj3Key = Object.keys(obj3);

console.log(obj3Key); returns ↴

["A", "B", "C"] array

obj3Key[0] "A"

obj3Key[1] "B"

obj3Key[2] "C"


Object.values() returns an array with the proprty values of an object.

const obj4 = { "A": 4, "B": 5, "C": 6 }; object

const obj4Val = Object.values(obj4);

console.log(obj4Val); returns ↴

[4, 5, 6] array

obj4Val[0] 4

obj4Val[1] 5

obj4Val[2] 6


Object.entries() static method returns an array of the key/value pairs of an object.

const obj5 = { "A": 4, "B": 5, "C": 6 }; object

const obj5Ent = Object.entries(obj5);

console.log(obj5Ent); returns ↴

[ ["A", 4], ["B", 5], ["C", 6] ] → array of arrays

obj5Ent[0] ["A", 4] array

obj5Ent[1] ["B", 5] array

obj5Ent[2] ["C", 6] array

obj5Ent = [["A", 4], ["B", 5], ["C", 6]] → array of arrays

obj5Ent[0][0] "A" access the first element of the first array

obj5Ent[0][1] 4 access the second element of the first array

obj5Ent[1][0] "B" access the first element of the second array

obj5Ent[1][1] 5 access the second element of the second array

obj5Ent[2][0] "C" access the first element of the third array

obj5Ent[2][1] 6 access the second element of the third array


Connect to an API using ↴

XMLHttpRequest object → used to request data from a web server.

JSON → lightweight, human-readable text format for data storage and transmission.

RESTful API → API based on REST design principles that follow a set of rules and conventions for building and interacting with web services.

REST countries API → provides information about countries including their name, capital, population, currencies, flags, languages, timezones, and more.


REST APIRepresentational State Transfer

A REST API is any API that adheres to the principles of Representational State Transfer (REST). It is a set of guidelines for creating web services that allow for interaction with resources over HTTP.


RESTful API

A RESTful API is governed by several key constraints that ensure its effectiveness and scalability. These constraints include ...

Statelessness Each request from a client must contain all the information needed to process it. The server does not store any client context between requests, which simplifies server design and improves scalability.

Client-Server Architecture The separation of client and server allows for independent evolution of both. The client handles the user interface, while the server manages data storage and processing.

Cacheability Responses must define themselves as cacheable or non-cacheable, allowing clients to reuse responses for identical requests, thus improving performance.

Layered System A RESTful API can be composed of multiple layers, with each layer having its own responsibilities. This promotes scalability and security by allowing intermediaries like proxies and gateways.

Uniform Interface A consistent interface simplifies the architecture, allowing different clients to interact with the API in a standardized way. This includes using standard HTTP methods (GET, POST, PUT, DELETE) and resource representations (JSON, XML).

It allows different software applications to communicate over the internet using standard HTTP methods such as ...

GET request data from a server

POST send data to a server

PUT update existing data on a server

DELETE remove specified data from a server

While all RESTful APIs are REST APIs, not all REST APIs are necessarily RESTful. REST APIs have a higher level of adherence to REST principles.


XMLHttpRequest and RESTful APIs

XMLHttpRequest is a JavaScript object that allows web applications to send and receive data asynchronously from a server.

XMLHttpRequest can be used to interact with RESTful APIs, it is not limited to them and can work with any HTTP-based service.

When you use XMLHttpRequest to interact with a RESTful API, you are essentially sending requests to endpoints that conform to these principles.


XMLHttpRequestXHR

XMLHttpRequest objects are used to interact with servers. You can retrieve data from a URL without having to do a full page refresh. This enables a Web page to update just part of a page without disrupting what the user is doing.

The XMLHttpRequest() constructor creates a new XMLHttpRequest

The object must be prepared by at least calling open() to initialize it before calling send() to send the request to the server.

To send an HTTP request ...

1. Create an XMLHttpRequest object

2. Open a URL

3. Send the request

Syntax

open(method, url, async)

method The HTTP request method to use (GET, POST, PUT, DELETE) to perform operations on resources.

url Reference or address used to access resources on the internet.

It specifies the location of a resource and the protocol used to retrieve it.

async optional Booloean value to determine whether the request should be processed asynchronously or synchronously.

When set to true (the default), the request is asynchronous, meaning that the JavaScript code will continue executing while the request is being processed.

If async is set to false the request is synchronous, which means that the execution of the code will pause until the request completes. This can lead to a poor user experience, as the application may become unresponsive during the wait time.

Make an asynchronous GET request to a server.

const xhr = new XMLHttpRequest();

xhr.open("GET", url, true);


Examples of some properties of the XMLHttpRequest Object ...

XMLHttpRequest instance properties

XMLHttpRequest object provides several instance properties that are vital for managing HTTP requests and responses.

readyState

Property holds the current state of the XMLHttpRequest instance.

It can take one of the following integer values ...

0 UNSENT request has been created but not yet opened

1 OPENED request has been opened but not yet sent

2 HEADERS_RECEIVED request has been sent, and the headers have been received

3 LOADING response is being downloaded

4 DONE operation is complete.

You can use this property to determine the current state of the request and to execute code based on that state.

status

Property returns the numerical HTTP status code of the XMLHttpRequest's response.

Common status codes include ...

200 OK

404 Not Found

500 Internal Server Error

statusText

Property provides a textual description of the HTTP status code.

For example, if the status is 200 the statusText would typically be OK

This can be useful for logging or displaying user-friendly messages.

responseXML

Property returns the response data as an XML Document object.

It is useful for working with XML data directly.

withCredentials

Property indicates whether or not cross-site Access-Control requests should be made using credentials such as cookies or authorization headers. Setting the boolean value to true allows credentials to be sent.

responseType

Property specifies the type of data that is expected in the response.

Possible values include "" (default), text, document, json, blob, arraybuffer.

Setting this property can help in automatically parsing the response data.

timeout

Property sets the time in milliseconds before the request times out. If the request takes longer than this time, it will be aborted.

You can use this property to prevent long waits for a response.

responseText

Property contains the response data as a string. This property is only available when the readyState is 4 (DONE).

It is useful for retrieving textual data from the server.

Event handlers ...

An event handler is a function that is executed in response to specific events that occur during the lifecycle of an XMLHttpRequest.

onload

Event handler is triggered when the request completes successfully. This means that the response has been received, and the status code indicates success, typically a status code of 200

It is often used when you want to execute code after the response is fully loaded.

onreadystatechange

Event handler is triggered whenever the readyState attribute of the XMLHttpRequest changes.

It is called multiple times during the lifecycle of the request. It is triggered every time the readyState property changes, which can be useful for tracking the progress of the request. The readyState can have values from 0 (UNSENT) to 4 (DONE).

onerror

Event handler is triggered when a network error occurs during the request. This could be due to various reasons such as a failed connection, a timeout, or an inability to reach the server.

send

Method is used to send the request to the server after the request has been configured using the open() method.

jsonplaceholder API

https://jsonplaceholder.typicode.com/

jsonplaceholder is a simple fake REST API for testing and prototyping.

It has different endpoints that give us fake users, posts, todos, comments etc.

Connect to API and get xhr object

let xhr = new XMLHttpRequest();

xhr.open("GET", "https://jsonplaceholder.typicode.com/users", true);

xhr.onload = function () {

if (xhr.readyState === 4 && xhr.status === 200) {

let response = xhr;

console.log(response);

}

};

xhr.send(); returns ↴

fetch response image

The request was successful.

readyState 4

status 200

Error handling

When making requests with xmlHttpRequest, errors can occur due to network issues or invalid responses.

HTTP response status codes indicate whether a specific HTTP request has been successfully completed.

Responses are grouped in five classes ...

100-199 informational response the request was received, continuing process

200-299 successful the request was successfully received, understood, and accepted

300-399 redirection further action needs to be taken in order to complete the request

400-499 client error the request cannot be fulfilled due to an issue that the client might be able to control

500-599 server error the server failed to fulfil an apparently valid request

Connect to API and return response data for users endpoint

let xhr = new XMLHttpRequest();

xhr.open("GET", "https://jsonplaceholder.typicode.com/users", true);

xhr.onload = function () {

if (xhr.readyState === 4 && xhr.status === 200) {

let response = JSON.parse(xhr.responseText);

console.log(response);

}

};

xhr.onerror = function () {

console.error("Request failed due to a network error.");

};

xhr.send(); returns ↴

fetch response image

new XMLHttpRequest() create a new XMLHttpRequest object

open initializes a newly-created request, or re-initializes an existing one

onload event handler triggered when the request completes successfully

readyState returns the state an XMLHttpRequest client is in

status returns the numerical HTTP status code of the XMLHttpRequest's response

JSON.parse converts JSON string to a javaScript object

responseText returns the text received from a server following a request being sent

onerror event triggered whenever an uncaught JavaScript error has been thrown

send sends the request to the server

Error Examples ...

Console.error message - (typo: comm should be com)

response error image

Console.error message - (typo: comm should be com)

response error image

Console.error message - resource not found (typo: user should be users)

response error image

JSONJavaScript Object Notation

JSON is a text-based data format following JavaScript object syntax. It represents structured data as a string, which is useful when you want to transmit data across a network.

Even though it closely resembles JavaScript object literal syntax, it can be used independently from JavaScript. Many programming environments feature the ability to read (parse) and generate JSON.

In JavaScript, the methods for parsing and generating JSON are provided by the JSON object.

JSON Parsing

The response from the server will be a JSON string, which we need to parse to convert it into a JavaScript object for further manipulation.

This can be accomplished using the JSON.parse() method.

const jsonStr = '{"name": "Spain", "capital": "Madrid"}'; → JSON string

console.log(jsonStr); returns ↴

{"name": "Spain", "capital": "Madrid"} → string

const obj6 = JSON.parse(jsonStr);

console.log(obj6); returns ↴

{name: "Spain", capital: "Madrid"} → JavaScript object


API key

An API key is a unique code that identifies calls made to an API. It is used to authenticate and/or authorize API users and to track their usage.

const API_KEY = "your-api-key-here";

const url = `https://api.example.com/data?key=${API_KEY}`;


REST countries API

The REST Countries API provides detailed information about countries around the world in a simple RESTful interface. Users can retrieve data such as country names, capital, population, languages, currencies, flags, and more.

Search by full name

The REST Countries API offers an endpoint specifically to search for countries by their full name. This endpoint is more precise than the Name endpoint, which returns all countries whose names partially match the query.

To use the Full Name endpoint, we need to specify the name of the country we want to look up in the API request URL and set the fullText query parameter to true.

The URL for this endpoint is ...

https://restcountries.com/v3.1/name/{name}?fullText=true

A URL is a reference or address used to access resources on the internet.

It specifies the location of a resource and the protocol used to retrieve it.

To search by country name - Spain

https://restcountries.com/v3.1/name/spain?fullText=true URL

https protocol

restcountries.com domain

/v3.1/name/spain?fullText=true path to the specific resource

The REST countries API is open source and free to use and does not require an API key.


Initialize a variable to hold the countryName.

const countryName = "Spain"; → user input

Select an option | Find capital

capital of country → user input


Define the country name for which we want to fetch data.

const countryName = "Spain"; → user input

Select the data we want to retreive.

capital of the country → user input

capital will be the endpoint

capital endpoint image

Define a function getData to fetch data from an API.

function getData(countryName) {}

The function takes a string as input countryName and requests data from the REST countries API with that country name.

From the response, user selected data is retrieved.

If the requested endpoint is stored within an object, the specific data can to be accessed using ...

Object.values to return an array of the property values of the object.

Object.keys to return an array with the keys of the object.

Template literals denote strings using backticks ``

This lets you embed variables and expressions within your strings.

Construct the URL for the REST Countries API using template literals.

const url = `https://restcountries.com/v3.1/name/${countryName}?fullText=true` url

Create a new XMLHttpRequest object.

const xhr = new XMLHttpRequest() xhr

Initialize a GET request to the API endpoint with the country name.

xhr.open("GET", url, true)

Define what happens when the request is successfully completed.

xhr.onload = function () {

Check if the response status is OK (200)

if (xhr.status === 200) {

If true, parse the JSON response.

const data = JSON.parse(xhr.responseText) data

Check if we received any data.

if (data.length > 0) {

Extract the data from the response

const res = data[0].capital res

Log results to the console

console.log(res)

else if no data was found

console.error("No data found for the specified country.")

If response status is not 200, log an error message.

console.error(`Error: ${xhr.status} - ${xhr.statusText}`)

Define what happens in case of a request error.

xhr.onerror = function () {

Log an error message for failed network requests.

console.error("Request failed due to a network error.")

Send the request to the server.

xhr.send()


Call the function with ↴

getData (countryName);


Connect to REST countries API and return the capital of Spain.

const countryName = "spain";

const getData = (country) => {

const url = `https://restcountries.com/v3.1/name/${country}?fullText=true`;

const xhr = new XMLHttpRequest();

xhr.open("GET", url, true);

xhr.onload = function () {

if (xhr.status === 200) {

const data = JSON.parse(xhr.responseText);

if (data.length > 0) {

const res = data[0].capital;

console.log(res);

} else {

console.error("No data found for the specified country.");

}

} else {

console.error(`Error: ${xhr.status} - ${xhr.statusText}`);

}

};

xhr.onerror = function () {

console.error("Request failed due to a network error.");

};

xhr.send();

}

call function

getData(countryName); returns ↴

["Madrid"]

Connect to REST countries API