5-1 Web API, concepts

In a modern web app, the application server implements a Web API that provides service to the front-end JavaScript code.

A Web API is a defined set of HTTP request messages along with a definition of the structure of response messages, usually expressed in JSON format (from Wikipedia).

A Web API provides service to clients through several endpoints. Each endpoint is named with an URL, e.g. http://example.com/products. A client uses an appropriate HTTP verb to invoke the endpoint. There are a few common paradigms to design Web APIs and structure the endpoints. We’ll discuss two, namely REST and RPC, in the next two sections. We’ll use REST style in the examples here. However, the focus on this section is the payload in requests and responses.

The two most popular payload formats in Web APIs are URL-encoded and JSON. URL encoded payloads are key-value pairs, and are only suitable for simple values. JSON is more flexible in representing data structure.

URL-encoded JSON
Structure key value pairs similar to JavaScript objects
Content type application/x-www-form-urlencoded application/json
In GET requests as query of the URL no
In other requests (POST, PUT, etc) in body in body
In responses in body in body

URL-encoded payload

‘URL-encoded’ was one of the original encoding in the Web to encode form data that a <form> submits to a server. (We’ve discussed this in Chapter 1.) You can use URL-encoded in all kinds of requests and responses.

For example, below is a simple (RPC style) request to get information about product with id=5.

GET /products.info?id=5 HTTP/1.1
Host: example.com

Notice that GET requests cannot have message body. Therefore, the URL-encoded payload must be packed in the URL.

The response for the above request could be the following.

HTTP/1.1 200 Ok
Content-type: application/x-www-form-urlencoded
Content-length: 79

id=5&productName=Coke+candy&category=Confections&unitPrice=10.5&unitsInStock=20

URL-encoded payload are also common as body of other kinds of requests (e.g. POST, PUT). Below is a sample (RPC style) request to create a new product.

POST /products.create HTTP/1.1
Host: example.com
Content-type: application/x-www-form-urlencoded
Content-length: 53

productName=Great+new+chocolate&category=Confections&unitPrice=20&unitsInStock=100

JSON, JavaScript Object Notation

The JSON data format is a textual language-agnostic data exchange format. JSON is supported by many popular languages, including Java, Python, and, of course, JavaScript.

Below is a sample response message that returns information about the product with id=5.

HTTP/1.1 200 Ok
Content-type: application/json
Content-length: 116

{
  "id": 5,
  "productName": "Coke candy",
  "category": "Confections",
  "unitPrice": 10.5,
  "unitsInStock": 20
}

The syntax of JSON is similar to JavaScript object, array, numbers, string and boolean. But there are several differences.

  • string values must use double quotation marks, e.g. "correct", not 'incorrect'.
  • keys of objects must be quoted strings, e.g. {"name": "peter", "age": 20}, not {name: "peter", 'age': 20}
  • there is only one root value. To represent a list of value, you can use array, e.g. [1,2,3].
  • Simple values (namely numbers, strings, true, false, null) are supported, but JSON data cannot include functions.
  • Comments /* like this */ are not allowed in JSON.

Object-enclosed JSON

Although simple values like 123, "json sample", true are valid JSON data, in many Web APIs, the returned values in responses are object-enclosed. In other words, the root value in the JSON data is an object. Below are two possible designs for returning data about two products in JSON, e.g. in response to a search request. (We omit some fields about products for brevity.) The first design returns the items directly in an array.

HTTP/1.1 200 Ok
Content-type: application/json
Content-length: 131

[
  { "id": 5, "productName": "Coke candy", "unitPrice": 10.5 },
  { "id": 6, "productName": "Chocolate bar", "unitPrice": 25.0 }
]

The second design encloses the data in an object. Usually, the items are described under a property of the object, and there is another property to provide the number of items (e.g. count).

HTTP/1.1 200 Ok
Content-type: application/json
Content-length: 166

{
  "count": 2,
  "items": [
    { "id": 5, "productName": "Coke candy", "unitPrice": 10.5 },
    { "id": 6, "productName": "Chocolate bar", "unitPrice": 25.0 }
  ]
}

JSON payload in requests

GET requests cannot take message body. Because JSON payload is usually large and may exceed the maximum allowable length of URL, we do not use JSON payload in GET requests.

On the other hand, JSON payload can appear in the message body of non-GET requests (e.g. POST, PUT, DELETE) For example, to create a product, the client may send the following (RPC style) request.

POST /products.create HTTP/1.1
Host: example.com
Content-type: application/json
Content-length: 104

{
  "productName": "New candy",
  "category": "Confections",
  "unitPrice": 8.6,
  "unitsInStock": 500
}

JavaScript support for JSON

Two built-in functions in JavaScript support conversion between JavaScript values and JSON data.

JSON.stringify() (online ref) converts a JavaScript value into a JSON string.

let product5 = {
  productName: 'New candy',
  category: "Confections",
  unitPrice: 8.6,
  unitsInStock: 500
};
console.log(product5);
let jsonString = JSON.stringify(product5);
console.log(jsonString);

JSON.parse() (online ref) converts a JSON string back into a JavaScript value.

// a JSON string obtained from a Web API
const jsonString = '{"id":10248,"customerId":85,"orderDate":"2012-07-04","freight":32.38,"shipCity":"Reims","lines":[{"productId":11,"unitPrice":14,"quantity":12},{"productId":42,"unitPrice":9.8,"quantity":10},{"productId":72,"unitPrice":34.8,"quantity":5}]}';

let data = JSON.parse(jsonString);
console.log(data);