CS377: Database Design - RESTful Web Services to Map to CRUD Functionality

Activity Goals

The goals of this activity are:
  1. To integrate a Flask web service with a NoSQL database

Supplemental Reading

Feel free to visit these resources for supplemental background reading material.

The Activity

Directions

Consider the activity models and answer the questions provided. First reflect on these questions on your own briefly, before discussing and comparing your thoughts with your group. Appoint one member of your group to discuss your findings with the class, and the rest of the group should help that member prepare their response. Answer each question individually from the activity, and compare with your group to prepare for our whole-class discussion. After class, think about the questions in the reflective prompt and respond to those individually in your notebook. Report out on areas of disagreement or items for which you and your group identified alternative approaches. Write down and report out questions you encountered along the way for group discussion.

Model 1: Creating a RESTful Web Service in Python with Flask

SQLyHTTP

Questions

  1. The URL bindings to each function look similar from function to function; what differentiates them and what actions each function takes?
  2. What HTTP methods (or verbs) do you see in this program? To what part of the CRUD model does each correspond?
  3. What happens if you request a person ID that doesn't exist?
  4. Investigate what it means to be a RESTful web service?
  5. Investigate how to use curl to invoke these web services.
  6. How would you modify this example to incorporate a NoSQL database backend? How about a relational database backend?

Embedded Code Environment

You can try out some code examples in this embedded development environment! To share this with someone else, first have one member of your group make a small change to the file, then click "Open in Repl.it". Log into your Repl.it account (or create one if needed), and click the "Share" button at the top right. Note that some embedded Repl.it projects have multiple source files; you can see those by clicking the file icon on the left navigation bar of the embedded code frame. Share the link that opens up with your group members. Remember only to do this for partner/group activities!

Model 2: Making a Web Service Client Request

Questions

  1. How might you make an HTTP get request to retrieve the set of people from your example web service?
  2. Investigate how to add authentication to an HTTP request.
  3. How would you make these requests using curl?

RESTful Web Services

Representational State Transfer (REST)ful Web Services are a popular architecture for building scalable and interoperable distributed systems. They provide an efficient way to expose data and functionality through HTTP endpoints.

Flask RESTful Web Services

Flask RESTful Web Services is a blog post by Miguel Grinberg that provides an in-depth tutorial on designing RESTful APIs with Python and Flask. The tutorial covers various aspects of building web services, including resource modeling, routing, request handling, and response formatting. The post emphasizes the use of Flask-RESTful, an extension that simplifies the development of RESTful APIs with Flask.

According to Grinberg, Flask-RESTful offers powerful abstractions to define resources as classes and map them to URLs using routing decorators. It also provides request parsing, input validation, and output serialization capabilities out of the box. Grinberg gives detailed examples and code snippets to showcase these features. The tutorial also highlights the importance of using HTTP status codes appropriately to communicate the outcome of requests.

How to use curl

curl is a popular command-line tool for making HTTP requests. Flavio Copes’s blog post provides a comprehensive guide on how to use curl effectively.

The guide starts with the basics of making GET and POST requests using curl and covers various features and options available. It describes how to pass headers, cookies, HTTP authentication, and handle redirects. Additionally, it demonstrates how to make requests with a specific HTTP method, set request body data, and handle response headers and status codes.

An example of making a GET request using curl:

curl -X GET https://api.example.com/users

Python Requests Library

The Python Requests Library is a comprehensive guide by Real Python on using the requests library to interact with RESTful APIs. The requests library is an elegant and simple HTTP library for Python, widely used for making HTTP requests.

The guide demonstrates the various HTTP methods supported by requests, including GET, POST, PUT, and DELETE. It also covers authentication, headers, query parameters, and handling responses in both JSON and XML formats. Real Python emphasizes best practices, such as using session objects for handling persistent connections and working with asynchronous requests using requests-futures.

An example of performing a GET request using the requests library:

import requests

response = requests.get('https://api.example.com/users')
if response.status_code == 200:
    users = response.json()
    print(users)

Example

Here’s an example of a POST request:

import requests
import json

url = 'https://jsonplaceholder.typicode.com/posts'
data = {'title': 'foo', 'body': 'bar', 'userId': 1}

response = requests.post(url, data=json.dumps(data))

print(response.status_code)
print(response.json())

And here’s an example of a PUT request:

import requests
import json

url = 'https://jsonplaceholder.typicode.com/posts/1'
data = {'id': 1, 'title': 'foo', 'body': 'bar', 'userId': 1}

response = requests.put(url, data=json.dumps(data))

print(response.status_code)
print(response.json())

In these examples, we’re using the JSONPlaceholder API, which is a simple fake REST API for testing and prototyping.

The equivalent CURL commands would be:

POST:

curl -X POST -H "Content-Type: application/json" -d '{"title":"foo", "body":"bar", "userId":1}' https://jsonplaceholder.typicode.com/posts

PUT:

curl -X PUT -H "Content-Type: application/json" -d '{"id":1, "title":"foo", "body":"bar", "userId":1}' https://jsonplaceholder.typicode.com/posts/1
  • POST is used to submit data to be processed to a specified resource. It’s often used when you want to upload a file or submit a completed web form.
  • PUT is used to update a current resource with new data. It’s often used when you’re updating existing records.

Authentication

There are several RESTful authentication methods, including Basic Auth, OAuth, JWT (JSON Web Tokens), and API Keys.

For Basic Auth, here’s an example in Python:

import requests
from requests.auth import HTTPBasicAuth

response = requests.get('https://api.github.com/user', auth=HTTPBasicAuth('user', 'pass'))

print(response.status_code)

And the equivalent CURL command:

curl -u user:pass https://api.github.com/user

In this example, we’re accessing the GitHub API, which supports Basic Auth for some operations. You would replace ‘user’ and ‘pass’ with your actual GitHub username and password (which should be stored outside of your code, perhaps in an encrypted file that only your user has read access to).

Accessing RESTful Data through a Web Page

<!DOCTYPE html>
<html>
<head>
    <title>Weather App</title>
    <style>
        #weather {
            font-size: 2em;
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <h1>Current Weather</h1>
    <div id="weather">Loading...</div>

    <script>
        // Initial API endpoint
        const initialApiUrl = 'https://api.weather.gov/points/40.194,-75.4563';

        // Fetch initial data from API
        fetch(initialApiUrl)
            .then(response => response.json())
            .then(data => {
                // Get forecast URL from initial data
                const forecastApiUrl = data.properties.forecast;

                // Fetch forecast data from API
                return fetch(forecastApiUrl);
            })
            .then(response => response.json())
            .then(data => {
                // Update div with forecast data
                const weatherDiv = document.getElementById('weather');
                const forecast = data.properties.periods[0];
                weatherDiv.innerHTML = `
                    <h2>${forecast.name}</h2>
                    <p>${forecast.detailedForecast}</p>
                `;
            })
            .catch(error => {
                console.error('Error:', error);
            });
    </script>
</body>
</html>

Submission

I encourage you to submit your answers to the questions (and ask your own questions!) using the Class Activity Questions discussion board. You may also respond to questions or comments made by others, or ask follow-up questions there. Answer any reflective prompt questions in the Reflective Journal section of your OneNote Classroom personal section. You can find the link to the class notebook on the syllabus.