Anatomy of a Request

INFO 153B/INFO 253B: Backend Web Architecture

Kay Ashaolu

Request and Response

  • What is really sent from a client (request)?
  • What is really sent for a server (response)?
  • How do we send and retrieve data from requests and responses?

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

Let's Dive in with code

# explore_api.py

from flask import Flask, request, Response
import json
import logging

app = Flask(__name__)

@app.route('/post_json_endpoint', methods=["POST"])
def post_json_endpoint():
    if request.headers['Content-Type'] == 'application/json':
        arguments = request.get_json()
        param1 = arguments.get("param1")
        param2 = arguments.get("param2")

    data = { 
        "param1": param1, 
        "param2": param2, 
        "request-content-type": "application/json" 
    }
    resp = Response(json.dumps(data), mimetype='application/json')

    return resp

Let's Dive in with code

@app.route('/post_form_endpoint', methods=["POST"])
def post_form_endpoint():
    if request.headers['Content-Type'] == 'application/x-www-form-urlencoded':
        param1 = request.form.get("param1")
        param2 = request.form.get("param2")

    data = { "param1": param1, "param2": param2, "request-content-type": "application/x-www-form-urlencoded" }
    resp = Response(json.dumps(data), mimetype='application/json')

    return resp

@app.route('/get_endpoint', methods=["GET"])
def get_endpoint():
    # Note for GET Request, we get input parameters from URL, not
    # application/json nor applicaiton/x-www-form-urlencoded
    # request body
    param1 = request.args.get("param1")
    param2 = request.args.get("param2")

    data = { "param1": param1, "param2": param2 }
    resp = Response(json.dumps(data), mimetype='application/json')

    return resp
GET /get_endpoint?param1=param1&param2=param2 HTTP/1.1
Host: localhost:5050
Content-Type: application/json

Get Request

POST /post_json_endpoint? HTTP/1.1
Host: localhost:5050
Content-Type: application/json
{"param1": "param1-data", "param2": "param2-data"}

POST Request (JSON)

POST Request (Form)

POST /post_form_endpoint? HTTP/1.1
Host: localhost:5050
Content-Type: application/x-www-form-urlencoded
?param1=param1+data&param2=param+2+data

Request/Response Parts

  • Method, Path, Protocol: Specify the Method (GET), the Path (/get_endpoint), and the Protocol (HTTP version 1.1) that you want to send the requests
  • Headers: meta information about the request, like Content-Type
  • Body: The data that is being sent to the server

Content-Type Header

  • Describes what format the data is in
  • MIME: Multipurpose Internet Mail Extensions
  • Internet Media Type, Content-Type

Format

  • MIME format: [type] / [subtype] ; [parameters]
    • type: the general category of data
    • subtype: formats, encodings
    • parameters: extra information that applies to that subtype

Extensible

  • Common MIME types are registered
    • text/plain
    • image/png
    • audio/mpeg
  • Make up your own with vnd., prs.

Pranks

Query Arguments

  • Delimited by =, separated by &
  • What happens if you want to send a ?
  • What happens if you want to send a &?

Encoding

  • Map one representation of data to another
  • Map normal text to a format accepted by HTTP query params
  • Map special characters to the hexadecimal representation

Url Encoding

  • = - %3D
  • & - %26
  • space - %20

Questions?