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:
1 2 3 4 5 | GET/FoodService HTTP 1.1 { "action" : "GetFoodServed" } |
1 2 3 4 5 6 7 | HTTP 1.1 200 OK { "Italian" : [ "pizza" , "calzone" ], "Chinese" : [ "fried rice" , "prawn crackers" ], "Indian" : [ "curry" , "poppadoms" ] } |
1 2 3 4 5 6 | GET/FoodService HTTP 1.1 { "action" : "MakeFoodOrder" , "order" : [ "pizza" , "fried rice" , "curry" ] } |
1 2 3 4 5 | 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:
1 2 3 4 5 6 7 8 | POST/restaurants/italian/orders HTTP 1.1 { "order" : [{ "item" : "pizza" , "quantity" : 1 }] } |
01 02 03 04 05 06 07 08 09 10 11 | HTTP 1.1 200 OK { "order" : [{ "orderNo" : "123456" , "item" : "pizza" , "toppings" : [ "pepperoni" , "extra cheese" ], "quantity" : 1 }], "total" : "£15.00" } |
1 2 3 4 5 6 7 8 | POST/restaurants/chinese/orders HTTP 1.1 { "order" : [{ "item" : "fried rice" , "quantity" : 1 }] } |
01 02 03 04 05 06 07 08 09 10 | HTTP 1.1 200 OK { "order" : [{ "orderNo" : "AW76W09" , "item" : "fried rice" , "quantity" : 1 }], "total" : "£2.50" } |
1 2 3 4 5 6 7 8 | POST/restaurants/indian/orders HTTP 1.1 { "order" : [{ "item" : "curry" , "quantity" : 1 }] } |
01 02 03 04 05 06 07 08 09 10 | 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:
01 02 03 04 05 06 07 08 09 10 11 12 | PUT/restaurants/italian/orders/123456 HTTP 1.1 { "order" : [{ "items" : [{ "item" : "pizza" , "toppings" : [ "pepperoni" , "extra cheese" , "olives" , "anchovies" ], "quantity" : 2 }] }] } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 | HTTP 1.1 200 OK { "order" : [{ "items" : [{ "item" : "pizza" , "toppings" : [ "pepperoni" , "extra cheese" , "olives" , "anchovies" ], "quantity" : 2 }] }], "orderNo" : "123456" , "total" : "£34.00" } |
01 02 03 04 05 06 07 08 09 10 11 12 13 | POST/restaurants/indian/orders HTTP 1.1 { "order" : [{ "items" : [{ "item" : "curry" , "quantity" : 1 },{ "item" : "poppadoms" , "quantity" : 2 }] }] } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 | HTTP 1.1 200 OK { "order" : [{ "items" : [{ "item" : "curry" , "quantity" : 1 },{ "item" : "poppadoms" , "quantity" : 2 }] }], "orderNo" : "89GY7QW8" , "total" : "£5.60" } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | 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:
01 02 03 04 05 06 07 08 09 10 11 | POST/restaurants/italian/orders HTTP 1.1 { "order" : [{ "items" : [{ "item" : "pizza" , "toppings" : [ "pepperoni" , "extra cheese" ], "quantity" : 1 }] }] } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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" }] } |
Further reading
Four ways to define examples in a RAML specification
Defining an example body payload and response for a RESTful API endpoint is an essential aspect of designing a modern API. These examples ensure that it is clear what the API contract expects to receive from the client and to respond with to the client.
Five aspects of RESTful API design
There are five principal aspects to a RESTful API specification that must be considered prior to coding an API specification. In this post I will discuss those five features with examples using a product use case. Before I get started let’s ensure that we understand what is meant by API and REST.
Published on Java Code Geeks with permission by Alex Theedom, partner at our JCG program. See the original article here: Richardson Maturity Model and Pizzas Opinions expressed by Java Code Geeks contributors are their own. |