Web APIs and External Libraries 
                CMU422: Fundamentals of Web Design - Session 9 
                Birmingham Newman University 
                Lecturer: James Williams 
                Working with third-party services and libraries
                3-hour session • 25 slides • 2 interactive tasks 
                
                    Session Timeline: 
                    
                        10 min: Registration & waiting 
                        20 min: Opening slides 
                        45 min: Task 1 
                        15 min: Break/Catch up 
                        20 min: Secondary slides 
                        45 min: Task 2 
                        Remaining: Self-study 
                     
                 
             
            
            
                Learning Objectives 
                
                    Understand Web APIs and their usage 
                    Work with external libraries and frameworks 
                    Integrate third-party services 
                    Handle API authentication and security 
                    Build applications with external dependencies 
                 
             
            
            
                What are Web APIs? 
                
                    Web APIs  are interfaces that allow applications to communicate
                    with external services
                
                
                    REST APIs for data exchange 
                    Browser APIs for device features 
                    Third-party service APIs 
                    Social media and payment APIs 
                 
                
                    // Example: Fetching data from a REST API 
                    fetch('https://api.example.com/data') 
                      .then(response => response.json()) 
                      .then(data => console.log(data)) 
                      .catch(error => console.error(error));
                
             
            
            
                REST API Basics 
                
                    // HTTP Methods 
                    GET /api/users // Retrieve data 
                    POST /api/users // Create new data 
                    PUT /api/users/123 // Update data 
                    DELETE /api/users/123 // Delete data 
                    // Status Codes 
                    200 - OK 
                    201 - Created 
                    400 - Bad Request 
                    401 - Unauthorized 
                    404 - Not Found 
                    500 - Internal Server Error
                
                
                    Standard HTTP methods for CRUD operations 
                    Status codes indicate request results 
                    JSON is common data format 
                    Stateless communication 
                 
             
            
            
                Fetch API 
                
                    // Basic GET request 
                    fetch('https://api.example.com/users') 
                      .then(response => { 
                        if (!response.ok) { 
                          throw new Error('Network response was not
                    ok'); 
                        } 
                        return response.json(); 
                      }) 
                      .then(data => console.log(data)) 
                      .catch(error => console.error(error)); 
                    // POST request with data 
                    fetch('https://api.example.com/users', { 
                      method: 'POST', 
                      headers: { 
                        'Content-Type': 'application/json', 
                      }, 
                      body: JSON.stringify({ 
                        name: 'John Doe', 
                        email: 'john@example.com' 
                      }) 
                    });
                
                
                    Modern way to make HTTP requests 
                    Promise-based API 
                    Supports all HTTP methods 
                    Built into modern browsers 
                 
             
            
            
                API Authentication 
                
                    // API Key authentication 
                    fetch('https://api.example.com/data', { 
                      headers: { 
                        'Authorization': 'Bearer YOUR_API_KEY', 
                        'X-API-Key': 'your-api-key' 
                      } 
                    }); 
                    // OAuth 2.0 flow 
                    const clientId = 'your-client-id'; 
                    const redirectUri = 'https://yourapp.com/callback'; 
                    const authUrl =
                    `https://api.example.com/oauth/authorize?client_id=${clientId}&redirect_uri=${redirectUri}&response_type=code`;
                
                
                    API keys for simple authentication 
                    OAuth 2.0 for secure authorization 
                    JWT tokens for stateless authentication 
                    Always secure API keys 
                 
             
            
            
                Browser APIs 
                
                    // Geolocation API 
                    navigator.geolocation.getCurrentPosition( 
                      position => { 
                        console.log('Latitude:', position.coords.latitude); 
                        console.log('Longitude:',
                    position.coords.longitude); 
                      }, 
                      error => console.error('Error:', error) 
                    ); 
                    // Local Storage API 
                    localStorage.setItem('user', JSON.stringify(userData)); 
                    const user = JSON.parse(localStorage.getItem('user')); 
                    // Web Audio API 
                    const audioContext = new AudioContext(); 
                    const oscillator = audioContext.createOscillator();
                
                
                    Geolocation for location services 
                    Local Storage for client-side data 
                    Web Audio for sound processing 
                    Canvas for graphics and animations 
                 
             
            
            
                External Libraries 
                
                    Libraries  provide pre-built functionality to speed up
                    development
                
                
                    jQuery for DOM manipulation 
                    Lodash for utility functions 
                    Axios for HTTP requests 
                    Chart.js for data visualization 
                    Moment.js for date handling 
                 
                
                    // Including libraries 
                    <script
                    src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script> 
                    <script
                    src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script> 
                    // Using jQuery 
                    $('#element').hide().fadeIn(1000); 
                    // Using Lodash 
                    const uniqueItems = _.uniq(array);
                
             
            
            
                jQuery Library 
                
                    // DOM manipulation 
                    $('#myElement').addClass('highlight'); 
                    $('.items').each(function(index, element) { 
                      $(element).text('Item ' + (index + 1)); 
                    }); 
                    // Event handling 
                    $('#button').on('click', function() { 
                      console.log('Button clicked!'); 
                    }); 
                    // AJAX requests 
                    $.ajax({ 
                      url: 'https://api.example.com/data', 
                      method: 'GET', 
                      success: function(data) { 
                        console.log(data); 
                      }, 
                      error: function(xhr, status, error) { 
                        console.error(error); 
                      } 
                    });
                
                
                    Simplified DOM manipulation 
                    Cross-browser compatibility 
                    Rich plugin ecosystem 
                    Easy AJAX requests 
                 
             
            
            
                Axios HTTP Client 
                
                    // Basic GET request 
                    axios.get('https://api.example.com/users') 
                      .then(response => { 
                        console.log(response.data); 
                      }) 
                      .catch(error => { 
                        console.error(error); 
                      }); 
                    // POST request 
                    axios.post('https://api.example.com/users', { 
                      name: 'John Doe', 
                      email: 'john@example.com' 
                    }) 
                      .then(response => console.log(response.data)); 
                    // Request configuration 
                    axios.defaults.baseURL = 'https://api.example.com'; 
                    axios.defaults.headers.common['Authorization'] = 'Bearer token';
                
                
                    Promise-based HTTP client 
                    Automatic JSON transformation 
                    Request/response interceptors 
                    Better error handling 
                 
             
            
            
                Chart.js for Data Visualization 
                
                    // HTML 
                    <canvas id="myChart"></canvas> 
                    // JavaScript 
                    const ctx = document.getElementById('myChart').getContext('2d'); 
                    const myChart = new Chart(ctx, { 
                      type: 'bar', 
                      data: { 
                        labels: ['Red', 'Blue', 'Yellow', 'Green'], 
                        datasets: [{ 
                          label: 'Dataset 1', 
                          data: [12, 19, 3, 5], 
                          backgroundColor: [ 
                            'rgba(255, 99, 132, 0.2)', 
                            'rgba(54, 162, 235, 0.2)' 
                          ] 
                        }] 
                      }, 
                      options: { 
                        responsive: true, 
                        scales: { 
                          y: { 
                            beginAtZero: true 
                          } 
                        } 
                      } 
                    });
                
                
                    Multiple chart types (bar, line, pie, etc.) 
                    Responsive and interactive 
                    Customizable styling 
                    Animation support 
                 
                
                
                    Try It: Interactive Charts 
                    
                        
                            
                                Bar
                                    Chart 
                                Line
                                    Chart 
                                Pie
                                    Chart 
                                Doughnut Chart 
                            
                            
                                 
                            
                            
                                Chart.js Features: 
                                Interactive:  Hover over data points for details
                                
                                Responsive:  Charts automatically resize
                                Animated:  Smooth transitions and animations
                                Customizable:  Colors, fonts, and styling options
                                
                             
                         
                     
                    
                        Click the buttons to see different chart types powered by Chart.js!
                    
                 
             
            
            
                Interactive Map with Leaflet 
                
                    Leaflet  is a lightweight, open-source JavaScript library for
                    interactive maps
                
                
                
                    Try It: Interactive Map Playground 
                    
                        
                            
                                Add Marker 
                                Add Circle 
                                Add
                                    Polygon 
                                Clear Map 
                            
                            
                            
                                Leaflet Map Features: 
                                Interactive:  Zoom, pan, and click on the map
                                Markers:  Click "Add Marker" to place markers
                                Shapes:  Add circles and polygons to the map
                                Responsive:  Works on desktop and mobile devices
                                
                             
                         
                     
                    
                        This map is powered by Leaflet.js - a popular open-source mapping library!
                    
                 
             
            
            
                Weather API Integration 
                
                    // OpenWeatherMap API 
                    const apiKey = 'your-api-key'; 
                    const city = 'London'; 
                    fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`) 
                      .then(response => response.json()) 
                      .then(data => { 
                        const temperature = data.main.temp; 
                        const description = data.weather[0].description; 
                        const humidity = data.main.humidity; 
                        document.getElementById('weather').innerHTML = ` 
                          Temperature: ${temperature}°C 
                          Description: ${description} 
                          Humidity: ${humidity}% 
                        `; 
                      }) 
                      .catch(error => console.error('Error:', error));
                
                
                    Real-world API integration 
                    Data parsing and display 
                    Error handling 
                    User interface updates 
                 
             
            
            
                Social Media APIs 
                
                    // Twitter API (example) 
                    const twitterApi = { 
                      consumerKey: 'your-consumer-key', 
                      consumerSecret: 'your-consumer-secret', 
                      accessToken: 'your-access-token', 
                      accessTokenSecret: 'your-access-token-secret' 
                    }; 
                    // Facebook Graph API 
                    fetch('https://graph.facebook.com/me?access_token=your-token') 
                      .then(response => response.json()) 
                      .then(data => console.log(data)); 
                    // Instagram Basic Display API 
                    const instagramUrl =
                    'https://graph.instagram.com/me/media?fields=id,caption,media_type,media_url&access_token=your-token';
                
                
                    OAuth 2.0 authentication 
                    Rate limiting considerations 
                    Data privacy compliance 
                    API versioning 
                 
             
            
            
                Payment APIs 
                
                    // Stripe payment integration 
                    const stripe = Stripe('your-publishable-key'); 
                    const elements = stripe.elements(); 
                    // Create card element 
                    const card = elements.create('card'); 
                    card.mount('#card-element'); 
                    // Handle payment 
                    const form = document.getElementById('payment-form'); 
                    form.addEventListener('submit', async (event) => { 
                      event.preventDefault(); 
                      const {error, paymentMethod} = await
                    stripe.createPaymentMethod({ 
                        type: 'card', 
                        card: card, 
                      }); 
                      if (error) { 
                        console.error(error); 
                      } else { 
                        console.log('Payment method:', paymentMethod); 
                      } 
                    });
                
                
                    Secure payment processing 
                    PCI compliance requirements 
                    Multiple payment methods 
                    Webhook handling 
                 
             
            
            
                API Error Handling 
                
                    // Comprehensive error handling 
                    async function fetchData(url) { 
                      try { 
                        const response = await fetch(url); 
                        if (!response.ok) { 
                          throw new Error(`HTTP error! status:
                    ${response.status}`); 
                        } 
                        const data = await response.json(); 
                        return data; 
                      } catch (error) { 
                        if (error.name === 'TypeError') { 
                          console.error('Network error:',
                    error.message); 
                        } else { 
                          console.error('API error:',
                    error.message); 
                        } 
                        // Show user-friendly error message 
                        showErrorMessage('Failed to load data. Please try
                    again.'); 
                        throw error; 
                      } 
                    }
                
                
                    Network error handling 
                    HTTP status code checking 
                    User-friendly error messages 
                    Retry mechanisms 
                 
             
            
            
                API Security Best Practices 
                
                    Never expose API keys in client-side code 
                    Use HTTPS for all API requests 
                    Implement rate limiting 
                    Validate and sanitize input data 
                    Use CORS properly 
                    Implement proper authentication 
                 
                
                    // Secure API key handling 
                    // ❌ Bad: Exposing API key in frontend 
                    const apiKey = 'sk-1234567890abcdef'; 
                    // ✅ Good: Use environment variables 
                    const apiKey = process.env.API_KEY; 
                    // ✅ Good: Use backend proxy 
                    fetch('/api/weather?city=London') // Backend handles API key 
                    // Input validation 
                    function validateInput(input) { 
                      if (typeof input !== 'string' || input.length > 100) { 
                        throw new Error('Invalid input'); 
                      } 
                      return input.trim(); 
                    }
                
             
            
            
                API Performance Optimization 
                
                    Implement caching strategies 
                    Use request batching 
                    Implement pagination 
                    Optimize payload size 
                    Use CDNs for libraries 
                 
                
                    // Caching with localStorage 
                    function getCachedData(key, ttl = 300000) { // 5 minutes 
                      const cached = localStorage.getItem(key); 
                      if (cached) { 
                        const { data, timestamp } = JSON.parse(cached); 
                        if (Date.now() - timestamp < ttl) { 
                              return data; 
                            } 
                          } 
                          return null; 
                        } 
                        // Request batching 
                        const batchRequests = (requests) => { 
                          return Promise.all(requests.map(req => fetch(req))); 
                        };
                
             
            
            
                Task 1: Weather Dashboard 
                
                    Instructions: 
                    
                        Create a new HTML file called weather-dashboard.html 
                        Build a weather dashboard using OpenWeatherMap API: 
                        
                            Search for cities and display current weather 
                            Show temperature, humidity, wind speed, and weather description 
                            Display weather icons and background images 
                            Add a 5-day forecast section 
                         
                        Integrate external libraries: 
                        
                            Use Chart.js to display temperature trends 
                            Use Axios for API requests 
                            Use Moment.js for date formatting 
                         
                        Implement features: 
                        
                            Geolocation to get user's current location 
                            Local storage to save favorite cities 
                            Responsive design for mobile devices 
                            Error handling for API failures 
                         
                        Add loading states and user feedback 
                     
                    Time:  45 minutes
                    This task will help you understand API integration and external library
                            usage 
                 
             
            
            
                Break Time 
                
                    15 Minutes 
                    Take a break, ask questions, or catch up on the previous task.
                    Next: Secondary slides and Task 2 
                 
             
            
            
                Advanced API Patterns 
                
                    API versioning strategies 
                    Request/response interceptors 
                    Retry mechanisms 
                    Circuit breaker pattern 
                    API mocking for development 
                 
                
                    // Retry mechanism 
                    async function fetchWithRetry(url, maxRetries = 3) { 
                      for (let i = 0; i < maxRetries; i++) { 
                            try { 
                              const response = await fetch(url); 
                              if (response.ok) return
                        response.json(); 
                            } catch (error) { 
                              if (i === maxRetries - 1) throw
                        error; 
                              await new Promise(resolve =>
                        setTimeout(resolve, 1000 * (i + 1))); 
                            } 
                          } 
                        } 
                        // API mocking 
                        const mockApi = { 
                          get: (url) => Promise.resolve({ data: mockData[url] }), 
                          post: (url, data) => Promise.resolve({ data: { id: Date.now(),
                        ...data } }) 
                        };
                
             
            
            
                WebSocket APIs 
                
                    // WebSocket connection 
                    const socket = new WebSocket('wss://echo.websocket.org'); 
                    socket.onopen = function(event) { 
                      console.log('Connection established'); 
                      socket.send('Hello Server!'); 
                    }; 
                    socket.onmessage = function(event) { 
                      console.log('Message from server:', event.data); 
                    }; 
                    socket.onclose = function(event) { 
                      console.log('Connection closed:', event.code, event.reason); 
                    }; 
                    socket.onerror = function(error) { 
                      console.error('WebSocket error:', error); 
                    };
                
                
                    Real-time bidirectional communication 
                    Chat applications and live updates 
                    Gaming and collaborative tools 
                    Financial data streaming 
                 
             
            
            
                GraphQL APIs 
                
                    // GraphQL query 
                    const query = ` 
                      query GetUser($id: ID!) { 
                        user(id: $id) { 
                          id 
                          name 
                          email 
                          posts { 
                            title 
                            content 
                          } 
                        } 
                      } 
                    `; 
                    // Fetch GraphQL data 
                    fetch('/graphql', { 
                      method: 'POST', 
                      headers: { 'Content-Type': 'application/json' }, 
                      body: JSON.stringify({ 
                        query: query, 
                        variables: { id: '123' } 
                      }) 
                    });
                
                
                    Single endpoint for all data 
                    Client specifies required fields 
                    Strong typing system 
                    Real-time subscriptions 
                 
             
            
            
                API Testing 
                
                    Unit testing API calls 
                    Integration testing 
                    Mock API responses 
                    Error scenario testing 
                    Performance testing 
                 
                
                    // Jest test example 
                    describe('Weather API', () => { 
                      test('fetches weather data successfully', async () => { 
                        const mockResponse = { 
                          main: { temp: 20, humidity: 65 }, 
                          weather: [{ description: 'sunny' }] 
                        }; 
                        global.fetch = jest.fn(() => 
                          Promise.resolve({ 
                            json: () =>
                    Promise.resolve(mockResponse) 
                          }) 
                        ); 
                        const weather = await fetchWeather('London'); 
                        expect(weather.temperature).toBe(20); 
                      }); 
                    });
                
             
            
            
                Task 2: Social Media Integration App 
                
                    Instructions: 
                    
                        Create a new HTML file called social-media-app.html 
                        Build a social media integration app with: 
                        
                            Multiple API Integration:  Twitter, Instagram, and
                                YouTube APIs 
                            Content Aggregation:  Display posts from different
                                platforms 
                            Search Functionality:  Search across platforms by
                                hashtag or keyword 
                            Analytics Dashboard:  Show engagement metrics using
                                Chart.js 
                         
                        Implement advanced features: 
                        
                            OAuth 2.0 authentication flow 
                            Real-time updates using WebSockets 
                            Content filtering and moderation 
                            Scheduled posting functionality 
                            Export data to CSV/JSON 
                         
                        Use external libraries: 
                        
                            Axios for API requests 
                            Chart.js for analytics 
                            Moment.js for date handling 
                            Bootstrap or Material-UI for styling 
                         
                        Add comprehensive error handling and rate limiting 
                        Implement responsive design and accessibility features 
                     
                    Time:  45 minutes
                    This task will help you understand complex API integrations and
                            multi-platform development 
                 
             
            
            
                Session Summary 
                
                    Web APIs enable powerful integrations 
                    External libraries accelerate development 
                    Security and error handling are crucial 
                    Performance optimization improves user experience 
                    Testing ensures reliable API interactions 
                    Real-time features enhance user engagement 
                 
                
                    Next Session: 
                    Project Planning and Development - Building complete web applications