Using an External API
Learning objectives
- You know how to use third party APIs.
Let's take a peek at accessing third party APIs. Here, we use APIs found from the https://github.com/public-apis/public-apis repository, which is a list of free APIs that can be used for software development. For convenience, we pick APIs that do not require authentication (i.e. there's no need to create an account): Dog API and NameDay API.
Using an API programmatically
When working with APIs, we rely on the Fetch API, which provides an interface for fetching resources (e.g. data) across the network.
GET Request
With the Fetch API, creating a GET request that asks for JSON data from a given address is written as follows. The fetch method is used to create the request, which receives a Response. The json method of the response is used to parse the received JSON document into a JavaScript object.
The following application uses the Fetch API to ask for a random dog resource from https://dog.ceo/api/breeds/image/random
, then printing the JavaScript object to the console.
const response = await fetch("https://dog.ceo/api/breeds/image/random");
const jsonData = await response.json();
console.log(jsonData);
When we run the above application from the command line, one possible response is as follows. The response contains a JavaScript object with two attributes: message
and status
. The attribute message
contains the address of an image, and the attribute status
contains the status of the request.
deno run --allow-net app.js
{
message: "https://images.dog.ceo/breeds/pekinese/n02086079_10721.jpg",
status: "success"
}
As the jsonData
is a JavaScript object, we can also log one of the properties of the object. In the following, we do a similar query as above, but instead of the JavaScript object, we log the message from the object.
const response = await fetch("https://dog.ceo/api/breeds/image/random");
const jsonData = await response.json();
console.log(jsonData.message);
When we run the program, we see the address of a random dog image being logged.
deno run --allow-net app.js
https://images.dog.ceo/breeds/hound-basset/n02088238_5239.jpg
POST Request
To post data to an API, we again use the Fetch API. The following example outlines how we can post data to the NameDay API that provides information on namedays. When asking for namedays, we POST data to the server that outlines information of the namedays that we wish for. See the API documentation for additional details.
The following application makes a request to the NameDay API, asking for the namedays for the first of April in Finland.
const data = {
"day": 1,
"month": 4,
"country": "fi",
};
const response = await fetch("https://nameday.abalin.net/api/V1/getdate", {
headers: {
"Content-Type": "application/json",
},
method: "POST",
body: JSON.stringify(data),
});
const jsonData = await response.json();
console.log(jsonData);
Running the above example provides the following output.
deno run --allow-net app.js
{ day: 1, month: 4, nameday: { fi: "Pulmu, Raita" }, country: "fi" }
Similarly to before, we can access the nameday information directly from the object. The above object has a property nameday
, which has the property fi
. To output just the names, we can do the following.
const data = {
"day": 1,
"month": 4,
"country": "fi",
};
const response = await fetch("https://nameday.abalin.net/api/V1/getdate", {
headers: {
"Content-Type": "application/json",
},
method: "POST",
body: JSON.stringify(data),
});
const jsonData = await response.json();
console.log(jsonData.nameday.fi);
Now, when we run the program, we see the names being logged.
deno run --allow-net app.js
Pulmu, Raita
Question not found or loading of the question is still in progress.
Using an API in a web application
Adding this information into a web application would be straightforward. The following example outlines a web application that makes a request to the NameDay API and then uses the response as a part of the response sent to the user.
import { Hono } from "https://deno.land/x/hono@v3.12.11/mod.ts";
const app = new Hono();
const fetchNamedays = async (day, month) => {
const data = {
"day": day,
"month": month,
"country": "fi",
};
const response = await fetch("https://nameday.abalin.net/api/V1/getdate", {
headers: {
"Content-Type": "application/json",
},
method: "POST",
body: JSON.stringify(data),
});
const jsonData = await response.json();
return jsonData.nameday.fi;
};
app.get("/", async (c) => {
const namedays = await fetchNamedays(1, 4);
return c.json({ namedays });
});
Deno.serve(app.fetch);
When we start the above application and make a query to it, we see a response that shows the namedays for the 1st of April in Finland.
curl localhost:8000
{"namedays":"Pulmu, Raita"}
A note on depending on third party APIs
APIs do change and evolve over time -- as an example, the NameDay API that we used here has changed a couple of times over the last years.
Whenever your application depends on a third party API, you will have to keep track of any changes to the third party API. If there are changes to the third party API, you need to adjust your application to match those changes.