#002554
#FED141
#007396
#007396
#382F2D
#3EB1C8
#F9423A
What is an API?
APIs in Everyday Life
Forms as Organizational APIs
Service Ontario
Emma's Restaurant
UofT
Ordinary Things: Hydro as API
abstraction
encapsulation
requirements
enabling innovation
The Web and Your Career
API examples
A few more details
REST or SOAP
URL parameters
Understanding API documentation
Asynchronous interaction
Example Zotero, Leaflet
Tutorial: The New York Times API
What is an API?
APIs in Everyday Life
Forms as Organizational APIs
Service Ontario
Emma's Restaurant
UofT
Ordinary Things: Hydro as API
abstraction
encapsulation
requirements
enabling innovation
The Web and Your Career
API examples
A few more details
REST or SOAP
URL parameters
Understanding API documentation
Asynchronous interaction
Example Zotero, Leaflet
Tutorial: The New York Times API
Application Program Interface
An interface for application programs...
...as opposed to an interface for (human) users
Devices can move from “plug to plug”
Anyone can build a device and “plug it in”
Supplier doesn’t care who plugs in
Other people are building boats that bring people to your casino
Interact with abstraction; ignore details
Why reinvent the wheel?
Anyone can build a device and “plug it in”
Ginormous fraction of all web apps are built on APIs
APIs are how open data/information gets done
The transactional web is built on APIs
Understanding APIs can release your inner-inventor
GET retrieve one or more records from database
POST put a new record into database
PUT overwrite existing data with new data
DELETE remove data from database
See also: "The REST API Tutorial", "CRUD vs. REST: What’s the Difference?"
Create
Delete
Update
Read
Create
Delete
Update
Read
insert
delete
update
select
https://innoeduvation.org/313/applets/zotero?tag=reqapi
https://innoeduvation.org/313/applets/zotero?tag=recapi
https://innoeduvation.org/313/applets/zotero?tag=reqapi
// hardcode the target URL
var url = "https://api.zotero.org/groups/2494325/items";
function getZoteroItems( tagparm, typeparm ) {
var users = getUrlParam("users","none")
var groups = getUrlParam("groups","2494325")
console.log('users=', users, 'groups=', groups)
if (users !== "none") {url = "https://api.zotero.org/users/" + users + "/items"}
else {url = "https://api.zotero.org/groups/" + groups + "/items"}
var recievedParameterString = getParameterString (tagparm, typeparm);
//replace commas with space pipe pipe space '%20||%20'
var usableParameterString = recievedParameterString.replace(/,/g, "%20||%20")
loadJSON(url + usableParameterString, gotData);
// callback from loadJSON processes retrieved data into HTML and writes it to webpage div
function gotData(data) {
var output = '<ol>'
var url = ''
var myclass = ' style="font-size:1.5em;">'
for (var i=0; i<data.length; i++) {
if (data[i].data.itemType == 'attachment') {continue;}
url = data[i].data.url
if (url) {
var date = (data[i].data.date == '' ? 'n.d.' : data[i].data.date)
output += '<li' + myclass + data[i].meta.creatorSummary + ' (' + date + '), ' + '<a href="' + data[i].data.url + '" target="_blank">' + data[i].data.title + '</a>' + ' <span style="font-size:0.75em;">(<a href="' + data[i].links.alternate.href + '" target="_blank">Zotero</a>)</span>' + '</li>'
}
else {
output += '<li' + myclass + data[i].meta.creatorSummary + ' (' + data[i].data.date + '), ' + data[i].data.title + ' <span style="font-size:0.75em;">(<a href="' + data[i].links.alternate.href + '" target="_blank">Zotero</a>)</span>' + '</li>'
}
//If URL contains abstract=yes we try to show the abstract
}
}
output += '</ol>'
document.getElementById("bibliography").innerHTML = output
}
API
server
A
P
I
application program
request
response
API
server
A
P
I
application program
request
response
API
server
A
P
I
application program
request
response
URL of the server where the API lives
directory path to the desired endpoint
parameters specifying what we want
https://api.nytimes.com
/svc/search/v2/articlesearch.json
?q=Canada&begin_date=19590707&
end_date=19590707&
api-key=f4SmA2yQ8JMFdxuckjzF0rD53QHrvLrk
server
path to API endpoint
query string or parameter string
URL?key=value&key=value
?first=this+is+a+field&second=was+it+clear+%28already%29%3F
%3f | ? |
%20 | space |
%26 | & |
%2b | + |
%2c | , |
%28 | ( |
%29 | ) |
See also W3Schools: "HTML URL Encoding Reference"
Need to encode "Illegal" characters that look to browser/server like URL punctuation
Read as "The NYT Books API has six endpoints four of which are lists
curly brackets represent parameters that can be passed as part of the path instead of as key value pairs
API
server
A
P
I
application program
request
response
response = {"status": number,
"data": array of objects}
API responses include a status code.
200 OK
429 Too Many Requests
404 Not Found
401 Unauthorized 403 Forbidden
400 Bad Request
500 Internal Server Error
Something happened on server that it was not programmed to handle.
Client has sent too many requests in a given amount of time ("rate limiting").
401, the client must authenticate itself to get the requested response. 403, we know who you are and you are not allowed to have this.
The server could not understand the request due to invalid syntax.
The server refuses the attempt to brew coffee with a teapot.
The server refuses the attempt to brew coffee with a teapot.
URL not recognized or endpoint valid but resource does not exist. Sometimes sent instead of 403 to hide existence of resource from unauthorized client.
Basic Structure of API Access Code
//Build URL based on user needs
//Issue request with three parameters:
// the url (including endpoints and query)
// name of function to call on success
// name of function to call on failure
function success (data){
//parse data and produce HTML for webpage
}
function failure (data) {
//prepare appropriate error message for user
}
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin="">
</script>
<style>
#map { height: 300px; width: 600px;}
</style>
</head>
<body>
<div id="map"></div>
<script>
var mymap = L.map('map').setView([43.664862, -79.399207], 13);
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: 'Map data © <a href="https://www.openstreetmap.org/copyright">
OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1,
accessToken: 'pk.eyJ1IjoiZGpqcmpyIiwiYSI6ImNrdm1pNnI2MmRvYnIycG1uZHM2MGI4ZXAifQ.qLKvSTy526H_YVqQqCD6tg'
}).addTo(mymap);
</script>
</body>
</html>
See also: HTTP status codes
400 (Bad Request)
401 (Unauthorized)
403 (Forbidden)
404 (Not Found)
https://developer.nytimes.com/
Request specified list of fields (lf)
function loadJSON | URL | function to run on success | function to run on failure |
function accessAPI_displayResults url = buildURL loadJSON (url, processData, processError)
function processData
//loop over data.response.docs[]
function processError //display error on webpage
function buildURL
return NYTURL?api_key=blahblahblah&key=value
Get results in code
function loadJSON | URL | function to run on success | function to run on failure |
function accessAPI_displayResults
url = buildURL
loadJSON (url, processData, processError)
function processData
//loop over data.response.docs[]
function processError
//display error on webpage
function buildURL
return NYTURL +
?api_key=blahblahblah
&key=value&key=value
Get results in code
function loadJSON(path, success, error) { //generic function to get JSON
//create new HTTP request object
var xhr = new XMLHttpRequest();
//define Event handler called when the readyState changes
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
if (success)
success(JSON.parse(xhr.responseText));
} else {
if (error)
error(xhr);
}
}
};
//Initialize a request.
xhr.open("GET", path, true);
//Send the request
xhr.send();
}
For more on XMLHttpRequest see MDN Web Docs
Get results in code
function accessAPI_displayResults() {
var url = constructURL();
loadJSON(url,
function(data) {processData(data);},
function(xhr) {processError(xhr);}
);
};
Get results in code
//processDATA runs when data comes back from API
function processData(data) {
//create variable to hold the HTML we build
var html ='';
//loop over data.response.docs[]
for (i=0; i < data.response.docs.length; i++) {-
//build up the html, item by item
html = html + '<br />' + '<h2>'
+ data.response.docs[i].web_url
+ data.response.docs[i].headline.main
+ '</h2>'
}
//send the html to the page element called "formattedAPIoutput"
document.getElementById("formattedAPIoutput").innerHTML = html
}
This is part we will change in tutorial
Get results in code
NYT API v0.0F21 Example
Get results in code
Get results in code
server IP address
path to API endpoint
query string or parameter string
Let's look at the ProblemSet
https://api.nytimes.com/svc/search/v2/articlesearch.json?q=rainbow&api-key=f4SmA2yQ8JMFdxuckjzF0rD53QHrvLrk
Build a flexible, database-driven tool for presenting review and exam problems.
These can be embedded (<iframe> in Quercus or slides.com
<iframe src="https://server.com/path/filename.html">
</iframe>
path/filename.html
Each problem is a separate html file (webpage).
https://teachingplatform.uk.r.appspot.com
//Endpoint to serve one problem by number
app.get('/problems/number/:id', (req, res) => {
var out = '';
for (var i = 0; i < d.data.length; i++) {
if (d.data[i].number == req.params.id)
{out += d.data[i].q + '<br />';}
};
res.status(200).send(out).end();
});
Each problem is a separate html file (webpage). These can be embedded (<iframe> in Quercus or slides.com
<iframe src="https://server.com/path/filename.html">
</iframe>
path/filename.html
Single html page with JavaScript and data in JSON.
d = {"data": [{"num": "01",
"q": "what is 2+2?",
"a": 4},
{"num": "02",
"q": "what is red+yellow?",
"a": "orange"}
]
};
//read num=xxxx from URL
p = getURLParameters();
//set default output
out = "not found";
//loop over data looking for match
for (var i=0; i<d.data.length; i++) {
if (d.data[i].num == p.num) {
out = d.data[i].q + d.data[i].a;
}
//write data onto the webpage
document.getElementById('output').innerHTML = out;
Web form submitting data to create or update a database