Third-Party Web APIs

  1. Overview
    1. A Web Application Programming Interface or Web API is a service that a client program can interface with using HTTP
    2. A third-party web API is a service provided by a third party, which is often free but requires registering for a key to access it
    3. Many third-party web APIs provides access to a large data set
    4. Some popular web APIs:
      1. Flickr API (photos)
      2. Bing Search API (web search)
      3. Facebook Graph API (Facebook social graph)
      4. Yahoo Fantasy Sports API
    5. Some fake web APIs for testing
      1. {JSON} Placeholder
      2. Dummy API
      3. Fake JSON API
    6. Most third-party web APIs are RESTful, meaning they use a query string or path or access the API and return the results in XML or JSON
    7. Some web APIs are SOAP-based, which is more complicated and heavily dependent on transfering XML between the client and server
  2. General architecture
    1. Client-side usage (with CORS, JSONP, or proxy server)
                 API Req
      1) Browser ---------> Service Provider 
      
                 XML/JSON
      2) Browser <--------- Service Provider           
      
    2. Server-side usage
                 Request
      1) Browser ---------> Web Server 
      
                                       API Req
      2) Browser            Web Server ---------> Service Provider 
      
                                       XML/JSON
      3) Browser            Web Server <--------- Service Provider 
      
                 Response
      4) Browser <--------- Web Server            Service Provider 
      
  3. OMDb API
    1. OMDb API is a free web API to obtain movie information
    2. The movie data is obtained from IMDb
    3. You must obtain a free API key to use the service
    4. Example queries
      1. Example 1 - Search for all movies with the word "star" in the title

        http://www.omdbapi.com/?s=star&type=movie&apikey=APIKEY

        {
          "Search": [
            {
              "Title": "Star Wars: Episode IV - A New Hope",
              "Year": "1977",
              "imdbID": "tt0076759",
              "Type": "movie"
            },
            {
              "Title": "Star Wars: Episode V - The Empire Strikes Back",
              "Year": "1980",
              "imdbID": "tt0080684",
              "Type": "movie"
            },
            etc...
            {
              "Title": "Star Trek II: The Wrath of Khan",
              "Year": "1982",
              "imdbID": "tt0084726",
              "Type": "movie"
            }
          ]
        }
        
      2. Example 2 - Get info for movie with IMDB ID tt0076759 (returns JSON)

        http://www.omdbapi.com/?i=tt0076759&apikey=APIKEY

        {  
           "Title":"Star Wars: Episode IV - A New Hope",
           "Year":"1977",
           "Rated":"PG",
           "Released":"25 May 1977",
           "Runtime":"121 min",
           "Genre":"Action, Adventure, Fantasy",
           "Director":"George Lucas",
           "Writer":"George Lucas",
           "Actors":"Mark Hamill, Harrison Ford, Carrie Fisher, Peter Cushing",
           "Plot":"Luke Skywalker joins forces with a Jedi Knight, a cocky pilot, a Wookiee, and two droids to save the galaxy from the Empire's world-destroying battle-station, while also attempting to rescue Princess Leia from the evil Darth Vader.",
           "Language":"English",
           "Country":"USA",
           "Awards":"Won 6 Oscars. Another 50 wins & 28 nominations.",
           "Poster":"https://images-na.ssl-images-amazon.com/images/M/MV5BZDk2NmNhZDgtZDgzZS00NTRkLWFiYjUtNGMzZTYwNTFhYjFmXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_SX300.jpg",
           "Ratings":[  
              {  
                 "Source":"Internet Movie Database",
                 "Value":"8.7/10"
              },
              {  
                 "Source":"Rotten Tomatoes",
                 "Value":"93%"
              },
              {  
                 "Source":"Metacritic",
                 "Value":"92/100"
              }
           ],
           "Metascore":"92",
           "imdbRating":"8.7",
           "imdbVotes":"1,009,663",
           "imdbID":"tt0076759",
           "Type":"movie",
           "DVD":"21 Sep 2004",
           "BoxOffice":"N/A",
           "Production":"20th Century Fox",
           "Website":"http://www.starwars.com/episode-iv/",
           "Response":"True"
        }
        
  4. Accessing the movie API in JavaScript
    1. Use XMLHttpRequest to make GET request
    2. Set responseType to "json" if results are JSON-encoded
    3. Use encodeURIComponent() to ensure string used in HTTP request is URL-encoded
    4. Example
      const search = "star wars";
      const xhr = new XMLHttpRequest();
      xhr.addEventListener("load", responseReceived);
      xhr.responseType = "json";
      xhr.open("GET", "https://www.omdbapi.com/?s=" + encodeURIComponent(search) + "&type=movie&apikey=APIKEY"); 
      xhr.send();
      
      function responseReceived() {
      	// Check for error
      	if (this.response.Error) {
      		console.log("Error: " + this.response.Error);
      	} 
      	else {
      		// Display all movie titles
      		for (let movie of this.response.Search) {
      			console.log(movie.Title);
      		}
      	}
      }
      
    5. Example encapsulating the code in an object
      const movieApi = {    
      	apiKey: "API KEY",
      	baseUrl: "https://www.omdbapi.com/",
         
      	getMovies: function(searchStr, callback) {
      		const xhr = new XMLHttpRequest();
      		xhr.addEventListener("load", function() {
      			if (this.response.Error) {
      				callback(this.response.Error);
      			}
      			else {
      				callback(null, this.response.Search);
      			}
      		});
      		
      		xhr.responseType = "json";
      		xhr.open("GET", `${this.baseUrl}?s=${encodeURIComponent(searchStr)}&type=movie&apikey=${this.apiKey}`); 
      		xhr.send();
      	} 
      };
      
      movieApi.getMovies("star wars", function(err, results) { 
      	if (err) {
      		console.log("Error: " + err);
      	}
      	else {
      		// Display all movie titles
      		for (let movie of results) {
      			console.log(movie.Title);
      		}
      	}
      });