Nuts and Bolts: HTTP

INFO 153B/253B: Backend Web Architecture

Kay Ashaolu

What is a resource?

  • Anything a server send back as a response
  • Various formats:
    • HTML
    • JSON
    • Audio Formats
    • Video Formats
    • Plain Text

What resource to return?

  • How are resources specified?
  • How does servers know what data to send?

Hostname/Path -> Resource

  • http://localhost:5000/static/
  • How to specify hostname in HTTP?
  • How to specify path?
  • What method to use?
  • What do you return?

Let's look at a static webserver

from flask import Flask
import json

app = Flask(__name__,static_url_path="/static")

Let's look at a static webserver

  • Associate "/static/style.js" with
    • /Users/kay/Desktop/demo/static/style.js
  • Associate "/static/style.css" with
    • /Users/kay/Desktop/demo/static/style.css
  • Associate "/static/cool_img_1.png with
    • /Users/kay/Desktop/demo/static/cool_img_1.png
  • ​Associate "/static/cool_img_2.png with
    • /Users/kay/Desktop/demo/static/cool_img_2.png

Note: Most requests to static servers are GET requests

HTTP Methods

  • POST (i.e. C in CRUD - Create data)
    • Submits data to be processed to a specified resource
  • GET (i.e. R in CRUD - Retrieve data)
    • Requests data from a specified resource.
    • NOTE: ONLY method where input is expected in the URL
  • PUT (i.e. U in CRUD - Update Data
    • Update specified resource
  • DELETE (i.e. D in CRUD - Delete Data)
    • Deletes specified resource

What if something goes wrong or unexpected?

  • You didn't define a route in flask and someone tries to go to that path
  • Your python code throws an exception
  • You redirect someone to another page 

Example: Missing File

  • What should we do if we request a file that is not there?
  • Return "Oops!"
  • Return nothing?
  • Return standard HTML?

HTTP Response Codes

  • Numbers are unambiguous, can be read by machines
  • Always return a response code
  • Return text as well for human readability

HTTP Response Codes

  • 200's: OK
  • 300's: Redirect
  • 400's: Client Errors
  • 500's: Server Errors

200's: OK

  • 200: OK
  • 201: OK - Entity Created
  • 204: OK - No Content in body

300's: Redirect

  • 301: Permanent Redirect
  • 302: Temporary Redirect
  • Location: Header with URI of target

400's: Client Errors

  • 400: Bad Reqeust
  • 401: Unauthorized
  • 404: Resource Not Found

500's: Server Errors

  • 500: Internal Server Error (Hard drive on fire)

Example

from flask import Flask, request
import json

app = Flask(__name__)

quote_db = {
  'sunday': "Life is about making an impact, not making an income. \
  –Kevin Kruse",
  'monday': "Whatever the mind of man can conceive and believe, it can achieve. \
  –Napoleon Hill",
  'tuesday': "Strive not to be a success, but rather to be of value. \
  –Albert Einstein",
  'wednesday': "You miss 100% of the shots you don’t take. \
  –Wayne Gretzky",
  'thursday': "Every strike brings me closer to the next home run. \
  –Babe Ruth",
  'friday': "We become what we think about. \
  –Earl Nightingale",
  'saturday': "Life is what happens to you while you’re busy making other plans. \
  –John Lennon",
}

Example

def gen_response(day_of_week):
    if not day_of_week:
        response = {"message": "We need the day_of_week in order to send a quote"}
        response_code = 400
    elif day_of_week.lower() not in quote_db:
        response = {"message": "Sorry we don't know that day of the week" }
        response_code = 404
    else:
        response = {"day": day_of_week, "quote": quote_db[day_of_week.lower()]}
        response_code = 200

    return json.dumps(response), response_code

@app.route('/quote/<day_of_week>')
def quote_of_the_day(day_of_week):
    return gen_response(day_of_week)

@app.route('/quote', methods = ['GET'])
@app.route('/quote/', methods = ['GET'])
def quote_of_the_day_get():
    day_of_week = request.args.get("day_of_week")
    return gen_response(day_of_week)

@app.route('/quote', methods = ['POST'])
def quote_of_the_day_post():
    data = request.get_json()
    day_of_week = data.get("day_of_week")
    return gen_response(day_of_week)

Example

@app.errorhandler(400)
def page_not_found(e):
    response = {"message": "We could not understand your request. \
        Please fix and try again"}
    return json.dumps(response), 404

@app.errorhandler(404)
def page_not_found(e):
    response = {"message": "This endpoint is not supported"}
    return json.dumps(response), 404

Questions?

Nuts and Bolts: HTTP - Backend Webarch

By kayashaolu

Nuts and Bolts: HTTP - Backend Webarch

Course Website: https://www.ischool.berkeley.edu/courses/info/253b

  • 829