INteracting
With APIs
Gavin King
College of Computer and Information Science
Mobile Engineer @ Vimeo
ghking13@gmail.com
http://ghking.co
OVerview
- Architecture
- APIs
- Examples
- Exercise
- The API
- Our Server
- Our Client
Client/Server Architecture
CLIENT
- Web browser (in this case)
- Requests data from the server
- Initiates communication and waits for a response
SERVER
- Sends data to the client
- Receives requests from the client and responds with the appropriate data
- Also manages persistent data (like a database) and heavy lifting
Our Server
Web Browser
What We're Building
For this experiment, our goal is to build a web app that predicts how much it's going to snow in a given area.
REQUIREMENTS
- Web page that determines the user's current location
- Server to request snowfall data from for a given location
- Communication between browser and server
But how can we predict the weather?
Solution: Third-Party API
- Application Program Interface
- Interface between apps and external services
- Exposes a service's internal functions or data for outside use
- Documented set of available requests and responses
- Usually JSON or XML format
EXAMPLE: TWITTER
- Tweeting
- View lists of favorites, friends, and messages
- Search tweets by user, location and hashtags
- Authentication
EXAMPLE: FOURSQUARE
- Search venues by location or other attributes
- View tips and preferences of users
- Check-in to a place
EXAMPLE: VIMEO
- Search for videos and users
- Create and view comments and likes
- Upload videos
- View groups and channels
Why provide an api?
- Creates dependencies from other apps
- Some APIs cost money
- Brand exposure
Forecast.io
- Hyper-local weather prediction service
- Powers the Dark Sky app for iOS
- Provides a forecast API for a given latitude and longitude
- JSON format
- Requires an API Key
https://api.forecast.io/forecast/APIKEY/LATITUDE,LONGITUDE
{
latitude: 42.3601,
longitude: -71.0589,
timezone: "America/New_York",
offset: -5,
currently: {...},
minutely: {...},
hourly: {...},
daily: {
summary: "Mixed precipitation tomorrow through Wednesday, with temperatures rising to 40°F on Sunday.",
icon: "snow",
data: [
{
time: 1424754000,
summary: "Light snow starting in the evening.",
sunriseTime: 1424777367,
sunsetTime: 1424816908,
moonPhase: 0.21,
precipIntensity: 0.0005,
precipIntensityMaxTime: 1424836800,
precipProbability: 0.03,
precipType: "snow",
precipAccumulation: 3.159,
temperatureMin: 1.02,
temperatureMinTime: 1424768400,
temperatureMax: 23.86,
temperatureMaxTime: 1424836800,
apparentTemperatureMin: -11.35,
apparentTemperatureMinTime: 1424761200,
apparentTemperatureMax: 15.46,
apparentTemperatureMaxTime: 1424836800,
dewPoint: 9.82,
humidity: 0.87,
windSpeed: 6.69,
windBearing: 233,
cloudCover: 0.5,
pressure: 1020.52,
ozone: 400.82
},
{...},
{...},
{...},
{...},
{...},
{...},
{...}
]
},
alerts: [...],
flags: {...}
}
response.daily.data.precipAccumulation
Forecast.io
Web Browser
?
Don't do this.
Why do we need our own server?
- Javascript code is downloaded to browsers in plain text
- Users can read the code and see variables
- Our private API Key would be exposed in the code if we make a request directly from the Javascript to the API
- This key can be used maliciously by others pretending to be us
- Could cost a lot of money
SOLUTION: Obfuscation
- Our API Key is hidden on the server away from plain view
- Our data source is abstracted from the user
- Requests can be cached saving money and bandwidth
- Our service can now be more easily extended with new features like history, favorites, etc.
Forecast.io
Web Browser
Our Server
The Server
Node.js
- Server-side runtime environment
- Written in Javascript
- Uses the Google V8 Javascript engine to execute code
- Allows applications to act as web servers without software such as Apache
Express
- Web framework for building applications with Node.js
- Used for maintaining an MVC architecture
- Kind of like the Rails for Ruby or the Django for Python
Installation
Node.js
- http://nodejs.org/download
- Download and install the package
Express
- NPM - Node Package Manager
-
$ npm install -g express
$ express howmuchsnow
var constants = require('./constants.js');
var express = require('express');
var app = express();
// Set a port for our application
app.set('port', (process.env.PORT || 5000))
// Listen on that port
app.listen(app.get('port'), function()
{
console.log("Node app is running on port " + app.get('port'))
})
// Create our API route
app.get('/forecast', forecast);
module.exports = {
FORECAST_API_KEY: "474jsj87474hfn8347fh8748hw8f7ef289",
ERROR_RESPONSE: {status: "error"}
}
constants.js
index.js
function forecast(req, res, next)
{
// Extract the parameters
latitude = req.query.latitude;
longitude = req.query.longitude;
// Send a request to the Forecast.io API
client = json.newClient("https://api.forecast.io/")
url = 'forecast/' + constants.FORECAST_API_KEY + "/" + latitude + "," + longitude
client.get(url, function(error, response, body)
{
if (response.statusCode == 200)
{
days = body.daily.data;
preicpAmount = 0
// Get the accumulation for the next 3 days including today
for (i = 0; i < 3; i++)
{
day = days[i]
if (day.precipType == "snow")
{
preicpAmount += day.precipAccumulation;
}
}
return res.json({status: "ok", amount: preicpAmount});
}
else
{
console.log(error);
return res.json(constants.ERROR_RESPONSE);
}
});
}
The Browser
HTML, CSS, jQuery
getLocationAndShowSnowfall();
function getLocationAndShowSnowfall()
{
if (navigator.geolocation)
{
// Get the user's location
navigator.geolocation.getCurrentPosition(getSnowfall);
}
else
{
showError();
}
}
function getSnowfall(position)
{
lat = position.coords.latitude;
lon = position.coords.longitude;
// Make the request to our server
$.getJSON("forecast/", {latitude: lat, longitude: lon}, showSnowfall);
}
function showSnowfall(response)
{
if (response.status == "ok")
{
populateUserInterface(response.amount);
}
else
{
showError();
}
}
Interacting with APIs
By ghking
Interacting with APIs
- 485