News Ticker

Richardson Maturity Model and Pizzas

The model, developed by Leonard Richardson, attempts to classify an API according to its adherence to the constraints imposed by REST. The more compliant your implementation, the better it fares. There are four levels. The bottom is level 0, which designates the less compliant implementation, and the top is level 3, which is the most compliant and therefore the most RESTful.

Level 0: The Swamp of POX (Plain Old XML)

One line description: Uses HTTP protocol as transport but not to indicate application state akin to classic RPC: SOAP and XML-RPC,

What it’s like: Like going to the only takeaway restaurant in town and ordering a pizza, fried rice, and a curry

Natural Language:
Customer: What type of food do you serve?
Restaurant: We serve Italian food such as pizzas and calzones, Chinese food like fried rice and prawn crackers and Indian food including curry and poppadoms.
Customer: Great. I want a pizza, some fried rice, and a curry
Restaurant: Here’s your pizza, fried rice, and curry

In Code:

GET/FoodService HTTP 1.1

{
"action" : "GetFoodServed"
}
HTTP 1.1 200 OK

{
  "Italian": [ "pizza", "calzone" ],
  "Chinese": [ "fried rice", "prawn crackers" ],
  "Indian": [ "curry", "poppadoms" ]
}
GET/FoodService HTTP 1.1

{
  "action": "MakeFoodOrder",
  "order": [ "pizza", "fried rice", "curry" ]
}
HTTP 1.1 200 OK

{
  "order": [ "pizza", "fried rice", "curry" ]
}

 Note: I have used JSON rather than XML to maintain consistency between examples.

Level 1: Resources

One line description: Distinguishes between different resources but uses one HTTP method.

What it’s like: Like going to different takeaway restaurants and ordering pizza at the Italian restaurant, fried rice at the Chinese restaurant and a curry at the Indian restaurant.

Natural Language:
Customer: (goes to Pizza restaurant) I want a pizza with pepperoni and extra cheese toppings.
Restaurant: OK. Here’s your pizza. That will be £15.00.
Customer: (goes to Chinese restaurant) I want fried rice
Restaurant: OK. Here’s your rice. That will be £2.50.
Customer: (goes to the Indian restaurant) I want a curry
Restaurant: OK. Here’s your curry. That will be £5.60.

In Code:

POST/restaurants/italian/orders HTTP 1.1

{
  "order": [{
    "item": "pizza",
    "quantity": 1
  }]
}
HTTP 1.1 200 OK

{
  "order": [{
    "orderNo": "123456",
    "item": "pizza",
    "toppings": [ "pepperoni", "extra cheese" ],
    "quantity": 1
  }],
  "total": "£15.00"
}
POST/restaurants/chinese/orders HTTP 1.1

{
  "order": [{
    "item": "fried rice",
    "quantity": 1
  }]
}
HTTP 1.1 200 OK

{
  "order": [{
    "orderNo": "AW76W09",
    "item": "fried rice",
    "quantity": 1
  }],
  "total": "£2.50"
}
POST/restaurants/indian/orders HTTP 1.1

{
  "order": [{
    "item": "curry",
    "quantity": 1
  }]
}
HTTP 1.1 200 OK

{
  "order": [{
    "orderNo": "89GY7QW8",
    "item": "fried rice",
    "quantity": 1
  }],
  "total": "£5.60"
}

Level 2: HTTP Verbs

One line description: Full use of all HTTP verbs combined with resource nouns.

What it’s like: Like going to the Italian restaurant and specifying the pizza topping, then going to the Chinese restaurant to cancel the fried rice and then going to the Indian to change the number of poppadoms.

Natural Language:
Customer: (goes to Pizza restaurant) I want a pizza.
Restaurant: OK. Here’s your pizza. That will be £15.00.
Customer: (goes to Chinese restaurant) I want fried rice
Restaurant: OK. Here’s your rice. That will be £2.50.
Customer: (returns to the pizza restaurant) I want to change my order and add extra toppings. I want to olives and anchovies. Oh and make that two pizzas.
Restaurant: OK we can do that Sir. Gives us your pizza and we will add those toppings.
Customer: (goes to an Indian restaurant) I want curry and two poppadoms.
Restaurant: OK here’s your order. That will be £8.20.
Customer: I have changed my mind. I only want to cancel my order.
Restaurant: OK. your new has been canceled.

In Code:

PUT/restaurants/italian/orders/123456 HTTP 1.1

{
  "order": [{
    "items": [{
      "item": "pizza",
      "toppings": [ "pepperoni", "extra cheese",
                    "olives", "anchovies" ],
      "quantity": 2
    }]
  }]
}
HTTP 1.1 200 OK

{
  "order": [{
    "items": [{
      "item": "pizza",
      "toppings": [ "pepperoni", "extra cheese",
                    "olives", "anchovies" ],
       "quantity": 2
    }]
  }],
  "orderNo": "123456",
  "total": "£34.00"
}
POST/restaurants/indian/orders HTTP 1.1

{
  "order": [{
    "items": [{
      "item": "curry",
      "quantity": 1
    },{
    "item": "poppadoms",
    "quantity": 2
    }]
  }]
}

HTTP 1.1 200 OK

{
  "order": [{
    "items": [{
      "item": "curry",
      "quantity": 1
    },{
    "item": "poppadoms",
    "quantity": 2
    }]
  }],
  "orderNo": "89GY7QW8",
  "total": "£5.60"
}

DELETE /restaurants/indian/orders/89GY7QW8 HTTP 1.1

HTTP 1.1 200 OK

{
  "order": [{
    "items": [{
      "item": "curry",
      "quantity": 1
    },{
    "item": "poppadoms",
    "quantity": 2
    }]
  }],
  "orderNo": "89GY7QW8",
  "total": "£5.60"
}

Level 3: Hypermedia Controls

One line description: Uses HATEOAS (Hypermedia As The Engine Of Application State) to direct the application state.

What it like: Like going to the pizza restaurant to order a pizza, then the waiter brings you your pizza and then tells you what you just ordered, what other pizzas are available and how to get more info about each one.

Natural Language:
Customer: (goes to pizza restaurant) I want a pizza.
Restaurant: Here’s your pizza. You ordered a pepperoni pizza. Would you like to know what extra toppings we have? We have other pizzas: Margherita, four seasons and four cheeses. Would you like more info about each one?

In code:

POST/restaurants/italian/orders HTTP 1.1

{
  "order": [{
    "items": [{
      "item": "pizza",
      "toppings": [ "pepperoni", "extra cheese" ],
      "quantity": 1
    }]
  }]
}
HTTP 1.1 200 OK

{
  "response": [{
    "order": [{
      "items": [{
        "item": "pizza",
        "toppings": [ "pepperoni",
                      "extra cheese" ],
        "quantity": 1
      }]
    }],
    "orderNo": "123456",
    "total": "£17.00"
  }],
  "links": [{
    "rel": "self",
    "href": "/restaurants/italian/orders/89GY7QW8",
    "method": "GET"
  },{
  "rel": "toppings",
  "href": "/restaurants/italian/toppings",
  "method": "GET"
  },{
  "rel": "delete_order",
  "href": "/restaurants/italian/orders/89GY7QW8",
  "method": "DELETE"
  }]
}

Where to get more information?

There are many articles published on the internet about the Richardson Maturity Model and RESTful API and how you can implement but for a detailed introduction on how to develop a RESTful API using HATEOAS you I recommend that you read chapter 13 of our latest book Professional Java EE Design Patterns.

References:

Martin Fowler provides a good overview on his website: http://martinfowler.com/articles/richardsonMaturityModel.html.

Leave a Reply

%d bloggers like this: